RE: [PATCH] xfrm_policy delete security check misplaced
> > > > > > Signed-off-by: Eric Paris <[EMAIL PROTECTED]> > > Acked-by: Venkat Yekkirala <[EMAIL PROTECTED]> > > What about your previous comment: > > "I guess you meant to do this here? > else if (err) > return err; " I saw that this was taken care of in patch-2 for the delete case, but while err isn't currently applicable to the non-delete case, it would be proper/complete for err to still be handled for the non-delete case. Thanks for asking. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] xfrm audit hook misplaced in pfkey_delete and xfrm_del_sa
> Inside pfkey_delete and xfrm_del_sa the audit hooks were not called if > there was any permission/security failures in attempting to do the del > operation (such as permission denied from security_xfrm_state_delete). > This patch moves the audit hook to the exit path such that > all failures > (and successes) will actually get audited. Not sure ALL failures are being audited this way elsewhere, but I guess they would catchup in course of time. > > Signed-off-by: Eric Paris <[EMAIL PROTECTED]> Acked-by: Venkat Yekkirala <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] Add xfrm policy change auditing to pfkey_spdget
> pfkey_spdget neither had an LSM security hook nor auditing for the > removal of xfrm_policy structs. The security hook was added > when it was > moved into xfrm_policy_byid instead of the callers to that function by > my earlier patch and this patch adds the auditing hooks as well. > > Signed-off-by: Eric Paris <[EMAIL PROTECTED]> Acked-by: Venkat Yekkirala <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] xfrm_policy delete security check misplaced
> > Signed-off-by: Eric Paris <[EMAIL PROTECTED]> Acked-by: Venkat Yekkirala <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] xfrm_policy delete security check misplaced
> Also, [Joy cc'd] deletions here needn't be audited? OK, I see the next patch addressed this :) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] xfrm_policy delete security check misplaced
> @@ -2552,7 +2550,7 @@ static int pfkey_spdget(struct sock > *sk, struct sk_buff *skb, struct sadb_msg *h > return -EINVAL; > > xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, > pol->sadb_x_policy_id, > - hdr->sadb_msg_type == SADB_X_SPDDELETE2); > + hdr->sadb_msg_type == > SADB_X_SPDDELETE2, &err); > if (xp == NULL) > return -ENOENT; I guess you meant to do this here? else if (err) return err; Also, [Joy cc'd] deletions here needn't be audited? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: when having to acquire an SA, ipsec drops the packet
> Something like this (untested) on the ipv4 side, for example: > > diff --git a/include/net/route.h b/include/net/route.h > index 486e37a..a8af632 100644 > --- a/include/net/route.h > +++ b/include/net/route.h > @@ -146,7 +146,8 @@ static inline char rt_tos2priority(u8 tos) > > static inline int ip_route_connect(struct rtable **rp, __be32 dst, > __be32 src, u32 tos, int > oif, u8 protocol, > -__be16 sport, __be16 dport, > struct sock *sk) > +__be16 sport, __be16 dport, > struct sock *sk, > +int flags) > { > struct flowi fl = { .oif = oif, > .nl_u = { .ip4_u = { .daddr = dst, > @@ -168,7 +169,7 @@ static inline int ip_route_connect(struct > rtable **rp, __be32 dst, > *rp = NULL; > } > security_sk_classify_flow(sk, &fl); > - return ip_route_output_flow(rp, &fl, sk, 0); > + return ip_route_output_flow(rp, &fl, sk, 1); I guess you meant to pass the new flags param to ip_route_output_flow here? > } > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: 2.6.20-rc6: known unfixed regressions (part 2)
FYI- The patch can be viewed here: http://marc.theaimsgroup.com/?l=linux-netdev&m=116983297300536&w=2 > -Original Message- > From: Michal Piotrowski [mailto:[EMAIL PROTECTED] > Sent: Friday, January 26, 2007 1:04 PM > To: Adrian Bunk > Cc: Linus Torvalds; Andrew Morton; Linux Kernel Mailing List; > Uwe Bugla; > [EMAIL PROTECTED]; linux-ide@vger.kernel.org; > [EMAIL PROTECTED]; Gerhard Dirschl; Christoph Hellwig; > [EMAIL PROTECTED]; Michal Piotrowski; Venkat Yekkirala; David Miller; > [EMAIL PROTECTED]; [EMAIL PROTECTED]; netdev@vger.kernel.org; Livio > Soares; Paul Mackerras; [EMAIL PROTECTED]; Cijoml Cijomlovic > Cijomlov; Nick Piggin; [EMAIL PROTECTED]; [EMAIL PROTECTED]; Malte > Schröder; Vladimir V. Saveliev; [EMAIL PROTECTED]; Sami Farin; > David Chinner; [EMAIL PROTECTED] > Subject: Re: 2.6.20-rc6: known unfixed regressions (part 2) > > > Hi, > > Adrian Bunk napisał(a): > > This email lists some known regressions in 2.6.20-rc6 > compared to 2.6.19 > > that are not yet fixed in Linus' tree. > > > > If you find your name in the Cc header, you are either > submitter of one > > of the bugs, maintainer of an affectected subsystem or > driver, a patch > > of you caused a breakage or I'm considering you in any > other way possibly > > involved with one or more of these issues. > > > > Due to the huge amount of recipients, please trim the Cc > when answering. > > > > > > Subject: SELinux compile error with CONFIG_XFRM=n > > References : http://lkml.org/lkml/2007/1/25/233 > > Submitter : Michal Piotrowski <[EMAIL PROTECTED]> > > Caused-By : Venkat Yekkirala <[EMAIL PROTECTED]> > > commit 334c85569b8adeaa820c0f2fab3c8f0a9dc8b92e > > Handled-By : Venkat Yekkirala <[EMAIL PROTECTED]> > > David Miller <[EMAIL PROTECTED]> > > Status : problem is being discussed > > > > Venkat Yekkirala has sent me a patch that fixed this build problem. > > Thanks! > > Regards, > Michal > > -- > Michal K. K. Piotrowski > LTG - Linux Testers Group > (http://www.stardust.webpages.pl/ltg/) > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1] selinux: fix 2.6.20-rc6 build when no xfrm
This patch is an incremental fix to the flow_cache_genid patch for selinux that breaks the build of 2.6.20-rc6 when xfrm is not configured. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/include/xfrm.h |9 + security/selinux/ss/services.c |6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 161eb57..31929e3 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -37,6 +37,11 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, struct avc_audit_data *ad, u8 proto); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); + +static inline void selinux_xfrm_notify_policyload(void) +{ + atomic_inc(&flow_cache_genid); +} #else static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, struct avc_audit_data *ad) @@ -55,6 +60,10 @@ static inline int selinux_xfrm_decode_se *sid = SECSID_NULL; return 0; } + +static inline void selinux_xfrm_notify_policyload(void) +{ +} #endif static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ff03933..ca9154d 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1299,7 +1299,7 @@ int security_load_policy(void *data, siz avc_ss_reset(seqno); selnl_notify_policyload(seqno); selinux_netlbl_cache_invalidate(); - atomic_inc(&flow_cache_genid); + selinux_xfrm_notify_policyload(); return 0; } @@ -1355,7 +1355,7 @@ #endif avc_ss_reset(seqno); selnl_notify_policyload(seqno); selinux_netlbl_cache_invalidate(); - atomic_inc(&flow_cache_genid); + selinux_xfrm_notify_policyload(); return 0; @@ -1855,7 +1855,7 @@ out: if (!rc) { avc_ss_reset(seqno); selnl_notify_policyload(seqno); - atomic_inc(&flow_cache_genid); + selinux_xfrm_notify_policyload(); } return rc; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [IPSEC] flow: Cache negative results
> > Only, on a security policy denial (-ESRCH from the LSM hook), a 0 > > is returned by the resolver to signify no applicable policy since > > a negative result is akin to no policy. And I see the "no policy" > > case is already cached. > > I'm not talking about an xfrm policy lookup failure, that exists > with or without SELinux. I'm talking about an error returned from > security_xfrm_policy_lookup(), i.e., whether a policy can be used > or not. I was talking about this (the latter) as well. Currently, on a proper "negative", -ESRCH is returned by security_xfrm_policy_lookup(), and this comes back up as a 0 from resolver(), correctly indicating NO applicable xfrm policy (after taking security into account). But if security_xfrm_policy_lookup() were to return anything other than a zero or -ESRCH, such as -ENOMEM, you will see it come back up as such (as -ENOMEM) from resolver(), and in this case, it's neither a positive nor a negative, just an error. Hence a full lookup would be in order, the next time round. > For that case, we only cache positive results currently. Negatives are currently properly cached as NULL. Any errors returned from resolver() are true errors, not negatives. Hence, they needn't be cached. Also, I would fix the other bug you had noted, by something like: @@ -232,11 +232,7 @@ nocache: err = resolver(key, family, dir, &obj, &obj_ref); if (fle) { - if (err) { - /* Force security policy check on next lookup */ - *head = fle->next; - flow_entry_kill(cpu, fle); - } else { + if (!err) { fle->genid = atomic_read(&flow_cache_genid); if (fle->object) I am planning to test and submit a patch to SELinux to invoke flow_cache_flush() on policy reloads tomorrow. I believe changes to labels on SPD rules are already taken care of by checks involving flow_cache_genid. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [IPSEC] flow: Cache negative results
> > This patch causes security policy denials to be cached instead of > > causing a relookup every time. Only, on a security policy denial (-ESRCH from the LSM hook), a 0 is returned by the resolver to signify no applicable policy since a negative result is akin to no policy. And I see the "no policy" case is already cached. I think what may have gotten us here is the comment: if (err) { /* Force security policy check on next lookup */ *head = fle->next; flow_entry_kill(cpu, fle); } else { But the error we would be looking at here would be a non-denial related error (neither positive nor negative) that the security server may have run into, in which case we would in fact want to attempt a full-lookup again the next time. > > So if the security folks actually care about this, they'd need to > > flush the flow cache whenever a relevant change is made to the > > security database. Sure. Will look into this. > > > > This patch also happens to fix a nasty bug where if an expiring > > flow entry that's not at the head happens to trigger a security > > denial, all entries before it are removed from the cache and > > leaked. I think just leaving the flow_entry as it is will take care of it. IOW, no entry_killing nor messing with it's object/reference. This should naturally cause us to invoke the resolver again the next time. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [IPSEC] flow: Cache negative results
> > So if the security folks actually care about this, they'd need to > > flush the flow cache whenever a relevant change is made to the > > security database. I do not believe we are doing this. I will look into this ASAP. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Multiple end-points behind same NAT
Hi, I am wondering if 26sec supports NAT-Traversal for multiple endpoints behind the same NAT. In looking at xfrm_tmpl it's not obvious to me that it's supported, at least going by the following from the setkey man page: When NAT-T is enabled in the kernel, policy matching for ESP over UDP packets may be done on endpoint addresses and port (this depends on the system. System that do not perform the port check cannot support multiple endpoints behind the same NAT). When using ESP over UDP, you can specify port numbers in the endpoint addresses to get the correct matching. Here is an example: spdadd 10.0.11.0/24[any] 10.0.11.33/32[any] any -P out ipsec esp/tunnel/192.168.0.1[4500]-192.168.1.2[3]/require ; Or is this to be accomplished in a different way? Thanks, venkat - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] labeled-ipsec: Repost patchset with updates [Originally: mlsxfrm: Various Fixes]
> I pulled in the lspp respin kernels and am checking the labeling > behavior now so I should have a full response later, however > I ran into > one unexpected thing immediately on bootup with the new kernel: Just FYI- The labeled-ipsec patch doesn't affect or influence the packet class handling in any manner. > > audit(1163061323.188:197): avc: denied { send } for pid=1676 > comm="modprobe" daddr=ff02:::::::0016 > netif=eth0 > scontext=system_u:system_r:kernel_t:s0 > tcontext=system_u:object_r:unlabeled_t:s0 tclass=packet > audit(1163061343.335:204): avc: denied { send } for pid=1804 > comm="avahi-daemon" saddr=fe80::::020c:29ff:fe72:2dd1 > src=5353 daddr=ff02:::::::00fb dest=5353 > netif=eth0 scontext=system_u:system_r:avahi_t:s0 > tcontext=system_u:object_r:unlabeled_t:s0 tclass=packet > audit(1163061343.338:205): avc: denied { recv } for pid=1804 > comm="avahi-daemon" saddr=fe80::::020c:29ff:fe72:2dd1 > src=5353 daddr=ff02:::::::00fb dest=5353 > netif=eth0 scontext=system_u:system_r:avahi_t:s0 > tcontext=system_u:object_r:unlabeled_t:s0 tclass=packet > audit(1163061346.139:210): avc: denied { send } for pid=1856 > comm="smartd-conf.py" saddr=fe80::::020c:29ff:fe72:2dd1 > daddr=ff02:::::::0016 netif=eth0 > scontext=system_u:system_r:kernel_t:s0 > tcontext=system_u:object_r:unlabeled_t:s0 tclass=packet > > These denials come after iptables-restore sets up labeling in > the mangle > table so I'm not sure why they are unlabeled.. Could you list the mangle table rules and see that the above IPv6 addresses are covered (i.e. labeled appropriately) or otherwise that your policy allows kernel_t to receive all packets (may or may not be desired/good, just thinking out loud). > They also > don't say which > port they were using, The port info is currently available only for tcp/udp packets. > perhaps is it a different protocol that > our packet > labeling isn't covering yet? James can perhaps comment on this better, but it *should* be covered to the extent that you are able to define mangle table/secmark rules for them. > Is there any way we could get protocol > information in the denial? This is possible with kernel changes, specifically by adding protocol to avc_audit_data. If Stephen agrees I can look into doing it. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] labeled-ipsec: Repost patchset with updates [Originally: mlsxfrm: Various Fixes]
> I think this should be aimed at 2.6.20, because we are at the last or > second-last -rc currently, and I don't think these fixes are > urgent enough > to justify the risk at this stage. That makes sense. Thanks. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] labeled-ipsec: Various fixes
Since the upstreaming of the mlsxfrm modification a few months back, testing has resulted in the identification of the following issues/bugs that are resolved in this patch set. 1. Fix the security context used in the IKE negotiation to be the context of the socket as opposed to the context of the SPD rule. 2. Fix SO_PEERSEC for tcp sockets to return the security context of the peer as opposed to the source. 3. Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. The following would be the result of applying this patchset: - SO_PEERSEC will now correctly return the peer's context. - IKE deamons will receive the context of the source socket/flow as opposed to the SPD rule's context so that the negotiated SA will be at the same context as the source socket/flow. - The SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs: 1. To enable a socket to communicate without using labeled-IPSec SAs: allow socket_t unlabeled_t:association { sendto recvfrom } 2. To enable a socket to communicate with labeled-IPSec SAs: allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom }; This Patch: Pass correct security context to IKE for use in negotiation Fix the security context passed to IKE for use in negotiation to be the context of the socket as opposed to the context of the SPD rule so that the SA carries the label of the originating socket/flow. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 21 -- security/dummy.c|4 +-- security/selinux/include/xfrm.h |4 +-- security/selinux/xfrm.c | 35 +++--- 4 files changed, 23 insertions(+), 41 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index b200b98..a509329 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -836,10 +836,8 @@ #ifdef CONFIG_SECURITY * used by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level policy update program (e.g., setkey). - * @sk refers to the sock from which to derive the security context. * Allocate a security structure to the xp->security field; the security - * field is initialized to NULL when the xfrm_policy is allocated. Only - * one of sec_ctx or sock can be specified. + * field is initialized to NULL when the xfrm_policy is allocated. * Return 0 if operation was successful (memory to allocate, legal context) * @xfrm_policy_clone_security: * @old contains an existing xfrm_policy in the SPD. @@ -858,9 +856,6 @@ #ifdef CONFIG_SECURITY * Database by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level SA generation program (e.g., setkey or racoon). - * @polsec contains the security context information associated with a xfrm - * policy rule from which to take the base context. polsec must be NULL - * when sec_ctx is specified. * @secid contains the secid from which to take the mls portion of the context. * Allocate a security structure to the x->security field; the security * field is initialized to NULL when the xfrm_state is allocated. Set the @@ -1378,12 +1373,12 @@ #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, - struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk); + struct xfrm_user_sec_ctx *sec_ctx); int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); void (*xfrm_policy_free_security) (struct xfrm_policy *xp); int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); int (*xfrm_state_alloc_security) (struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *polsec, + struct xfrm_user_sec_ctx *sec_ctx, u32 secid); void (*xfrm_state_free_security) (struct xfrm_state *x); int (*xfrm_state_delete_security) (struct xfrm_state *x); @@ -3120,7 +3115,7 @@ #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) { - return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); + return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); } static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) @@ -3141,7 +3136,7 @@ static inline int security_xfrm_policy_d static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx
[PATCH 2/3] labeled-ipsec: Return correct context for SO_PEERSEC
Fix SO_PEERSEC for tcp sockets to return the security context of the peer (as represented by the SA from the peer) as opposed to the SA used by the local/source socket. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 14 ++ include/net/request_sock.h |1 net/ipv4/tcp_input.c|2 + security/dummy.c|6 security/selinux/hooks.c| 21 --- security/selinux/include/xfrm.h | 12 - security/selinux/xfrm.c | 40 ++ 7 files changed, 49 insertions(+), 47 deletions(-) --- net-2.6.lx1/include/linux/security.h2006-11-08 09:40:42.0 -0600 +++ net-2.6/include/linux/security.h2006-11-08 09:47:42.0 -0600 @@ -826,6 +826,8 @@ struct request_sock; * Sets the openreq's sid to socket's sid with MLS portion taken from peer sid. * @inet_csk_clone: * Sets the new child socket's sid to the openreq sid. + * @inet_conn_established: + * Sets the connection's peersid to the secmark on skb. * @req_classify_flow: * Sets the flow's sid to the openreq sid. * @@ -1368,6 +1370,7 @@ struct security_operations { int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb, struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); + void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); #endif /* CONFIG_SECURITY_NETWORK */ @@ -2961,6 +2964,12 @@ static inline void security_inet_csk_clo { security_ops->inet_csk_clone(newsk, req); } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ + security_ops->inet_conn_established(sk, skb); +} #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct socket * sock, struct socket * other, @@ -3110,6 +3119,11 @@ static inline void security_inet_csk_clo const struct request_sock *req) { } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM --- net-2.6.lx1/include/net/request_sock.h 2006-11-08 09:38:06.0 -0600 +++ net-2.6/include/net/request_sock.h 2006-11-08 09:47:42.0 -0600 @@ -54,6 +54,7 @@ struct request_sock { struct request_sock_ops *rsk_ops; struct sock *sk; u32 secid; + u32 peer_secid; }; static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) --- net-2.6.lx1/net/ipv4/tcp_input.c2006-11-08 09:38:06.0 -0600 +++ net-2.6/net/ipv4/tcp_input.c2006-11-08 09:47:42.0 -0600 @@ -4230,6 +4230,8 @@ static int tcp_rcv_synsent_state_process mb(); tcp_set_state(sk, TCP_ESTABLISHED); + security_inet_conn_established(sk, skb); + /* Make sure socket is routed, for correct metrics. */ icsk->icsk_af_ops->rebuild_header(sk); --- net-2.6.lx1/security/dummy.c2006-11-08 09:40:42.0 -0600 +++ net-2.6/security/dummy.c2006-11-08 09:47:42.0 -0600 @@ -828,6 +828,11 @@ static inline void dummy_inet_csk_clone( { } +static inline void dummy_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} + static inline void dummy_req_classify_flow(const struct request_sock *req, struct flowi *fl) { @@ -1108,6 +1113,7 @@ void security_fixup_ops (struct security set_to_dummy_if_null(ops, sock_graft); set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); + set_to_dummy_if_null(ops, inet_conn_established); set_to_dummy_if_null(ops, req_classify_flow); #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM --- net-2.6.lx1/security/selinux/include/xfrm.h 2006-11-08 09:40:42.0 -0600 +++ net-2.6/security/selinux/include/xfrm.h 2006-11-08 09:47:42.0 -0600 @@ -39,7 +39,6 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s struct avc_audit_data *ad); int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, struct avc_audit_data *ad); -u32 selinux_socket_getpeer_stream(struct sock *sk); u32 selinux_socket_getpeer_dgram(struct sk_buff *skb); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); #else @@ -55,11 +54,6 @@ static inline int selinux_xfrm_postroute return 0; } -static inli
[PATCH 3/3] labeled-ipsec: Fix SA selection semantics
Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. This eliminates the SELinux policy's ability to use/sendto SAs with contexts other than the socket's. With this patch applied, the SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs: 1. To enable a socket to communicate without using labeled-IPSec SAs: allow socket_t unlabeled_t:association { sendto recvfrom } 2. To enable a socket to communicate with labeled-IPSec SAs: allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom }; Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 19 - net/xfrm/xfrm_policy.c |3 security/dummy.c|7 -- security/selinux/hooks.c| 26 +-- security/selinux/include/xfrm.h |7 -- security/selinux/xfrm.c | 101 ++ 6 files changed, 70 insertions(+), 93 deletions(-) --- net-2.6.lx2/include/linux/security.h2006-11-08 09:47:42.0 -0600 +++ net-2.6/include/linux/security.h2006-11-08 16:36:32.0 -0600 @@ -886,11 +886,6 @@ struct request_sock; * @xp contains the policy to check for a match. * @fl contains the flow to check for a match. * Return 1 if there is a match. - * @xfrm_flow_state_match: - * @fl contains the flow key to match. - * @xfrm points to the xfrm_state to match. - * @xp points to the xfrm_policy to match. - * Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. * @secid points to the flow key secid to set. @@ -1388,8 +1383,6 @@ struct security_operations { int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); - int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp); int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ @@ -3186,12 +3179,6 @@ static inline int security_xfrm_state_po return security_ops->xfrm_state_pol_flow_match(x, xp, fl); } -static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) -{ - return security_ops->xfrm_flow_state_match(fl, xfrm, xp); -} - static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) { return security_ops->xfrm_decode_session(skb, secid, 1); @@ -3255,12 +3242,6 @@ static inline int security_xfrm_state_po return 1; } -static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) -{ - return 1; -} - static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) { return 0; --- net-2.6.lx2/net/xfrm/xfrm_policy.c 2006-11-08 09:38:02.0 -0600 +++ net-2.6/net/xfrm/xfrm_policy.c 2006-11-08 16:36:32.0 -0600 @@ -1894,7 +1894,8 @@ int xfrm_bundle_ok(struct xfrm_policy *p if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) return 0; - if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) + if (fl && pol && + !security_xfrm_state_pol_flow_match(dst->xfrm, pol, fl)) return 0; if (dst->xfrm->km.state != XFRM_STATE_VALID) return 0; --- net-2.6.lx2/security/dummy.c2006-11-08 09:47:42.0 -0600 +++ net-2.6/security/dummy.c2006-11-08 16:36:32.0 -0600 @@ -886,12 +886,6 @@ static int dummy_xfrm_state_pol_flow_mat return 1; } -static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp) -{ - return 1; -} - static int dummy_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) { return 0; @@ -1126,7 +1120,6 @@ void security_fixup_ops (struct security set_to_dummy_if_null(ops, xfrm_state_delete_security); set_to_dummy_if_null(ops, xfrm_policy_lookup); set_to_dummy_if_null(ops, xfrm_state_pol_flow_match); - set_to_dummy_if_null(ops, xfrm_flow_state_match); set_to_dummy_if_null(ops, xfrm_decode_session); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ #ifdef CONFIG_KEYS --- net-2.6.lx2/security/selinux/include/xfrm.h 2006-11-08 09:47:42.0 -0600 +++ net-2.6/security/selinux/include/xfrm.h 2006-11-08 16:36:32.0 -0600 @@ -19,9 +19,6 @@ int selinux_xfrm_state_delete(struct xfr int selinux_xfrm_policy_lookup(struct
[PATCH 0/3] labeled-ipsec: Repost patchset with updates [Originally: mlsxfrm: Various Fixes]
This patchset is against davem's net-2.6.git. Please apply to 2.6.19. The following are the changes since the previous post of this patchset: 1. Separate BUG_ON usage per Eric's suggestion. 2. Replace security_sid_compare with a simple sid compare check per a suggestion from Paul/Stephen. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/3] mlsxfrm: Various fixes
> > > Not sure > > > though when > > > that would apply here, > > > > It could apply to xfrms if they happen to be using the context > > represented by any of the initial SIDs. > > Which would happen when? If one were attempting to use a context pertaining to the unlabeled init sid in the SPD and/or the SAD. But would I be correct in assuming that the same sid (unlabeled init sid in all likelyhood) would end up being returned when the context is turned into a sid, resulting in the SPD and the SAD using the same init sid, thus making a full-context compare unnecessary? > > > > and it would only apply if both SIDs > > > were initial > > > SIDs. > > > > OK. Will narrow the full context comparison to just this case. > > What's the harm from just using the SID comparison and > allowing for the > possibility that there might be a few duplicates in rare > circumstances? > Does it break any assumptions in the rest of the logic? The best I can think of is if the SA's sid doesn't match the socket's SID, IKE would come into play, if it's configured. I also wanted to conversely ask what harm exists if we did a full-context compare in the event the sids didn't match? Are we just trying to generally avoid extra code? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 3/3] mlsxfrm: Various fixes
> Such duplication can occur among the initial SIDs. For some reason I thought that could happen between an initial SID and a non-initial SID. > Not sure > though when > that would apply here, It could apply to xfrms if they happen to be using the context represented by any of the initial SIDs. > and it would only apply if both SIDs > were initial > SIDs. OK. Will narrow the full context comparison to just this case. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/3] mlsxfrm: Various fixes
> > Fix SO_PEERSEC for tcp sockets to return the security context of > > the peer (as represented by the SA from the peer) as opposed to the > > SA used by the local/source socket. > > What about the case of a localhost TCP connection not using > xfrm labeling? > > Joe Nall raised this as an important requirement. Yes. We need to come up with some new ideas on this (the failed secid-recon patchset sought to do this using the secmark field on the skb). The scope of this patchset is to strictly fix things related to labeled-xfrm. > > > > (Also, 'mlsxfrm' is MLS-specific). Will switch to "labeled-ipsec". - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] mlsxfrm: Various fixes
Since the upstreaming of the mlsxfrm modification a few months back, testing has resulted in the identification of the following issues/bugs that are resolved in this patch set. 1. Fix the security context used in the IKE negotiation to be the context of the socket as opposed to the context of the SPD rule. 2. Fix SO_PEERSEC for tcp sockets to return the security context of the peer as opposed to the source. 3. Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. The following would be the result of applying this patchset: - SO_PEERSEC will now correctly return the peer's context. - IKE deamons will receive the context of the source socket/flow as opposed to the SPD rule's context so that the negotiated SA will be at the same context as the source socket/flow. - The SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs: 1. To enable a socket to communicate without using labeled-IPSec SAs: allow socket_t unlabeled_t:association { sendto recvfrom } 2. To enable a socket to communicate with labeled-IPSec SAs: allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom }; This Patch: Fix the security context used in the IKE negotiation to be the context of the socket as opposed to the context of the SPD rule so that the SA carries the label of the originating socket/flow. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- This patchset is against davem's net-2.6.git. Please apply to 2.6.19. include/linux/security.h| 21 - security/dummy.c|4 +-- security/selinux/include/xfrm.h |4 +-- security/selinux/xfrm.c | 36 +++--- 4 files changed, 23 insertions(+), 42 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index b200b98..a509329 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -836,10 +836,8 @@ #ifdef CONFIG_SECURITY * used by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level policy update program (e.g., setkey). - * @sk refers to the sock from which to derive the security context. * Allocate a security structure to the xp->security field; the security - * field is initialized to NULL when the xfrm_policy is allocated. Only - * one of sec_ctx or sock can be specified. + * field is initialized to NULL when the xfrm_policy is allocated. * Return 0 if operation was successful (memory to allocate, legal context) * @xfrm_policy_clone_security: * @old contains an existing xfrm_policy in the SPD. @@ -858,9 +856,6 @@ #ifdef CONFIG_SECURITY * Database by the XFRM system. * @sec_ctx contains the security context information being provided by * the user-level SA generation program (e.g., setkey or racoon). - * @polsec contains the security context information associated with a xfrm - * policy rule from which to take the base context. polsec must be NULL - * when sec_ctx is specified. * @secid contains the secid from which to take the mls portion of the context. * Allocate a security structure to the x->security field; the security * field is initialized to NULL when the xfrm_state is allocated. Set the @@ -1378,12 +1373,12 @@ #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, - struct xfrm_user_sec_ctx *sec_ctx, struct sock *sk); + struct xfrm_user_sec_ctx *sec_ctx); int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); void (*xfrm_policy_free_security) (struct xfrm_policy *xp); int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); int (*xfrm_state_alloc_security) (struct xfrm_state *x, - struct xfrm_user_sec_ctx *sec_ctx, struct xfrm_sec_ctx *polsec, + struct xfrm_user_sec_ctx *sec_ctx, u32 secid); void (*xfrm_state_free_security) (struct xfrm_state *x); int (*xfrm_state_delete_security) (struct xfrm_state *x); @@ -3120,7 +3115,7 @@ #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) { - return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); + return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); } static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) @@ -3141,7 +3136,7 @@ static inline int security_xfrm_policy_d static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_se
[PATCH 2/3] mlsxfrm: Various fixes
Fix SO_PEERSEC for tcp sockets to return the security context of the peer (as represented by the SA from the peer) as opposed to the SA used by the local/source socket. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 14 ++ include/net/request_sock.h |1 net/ipv4/tcp_input.c|2 + security/dummy.c|6 security/selinux/hooks.c| 21 --- security/selinux/include/xfrm.h | 12 - security/selinux/xfrm.c | 40 ++ 7 files changed, 49 insertions(+), 47 deletions(-) --- net-2.6.xfrm1/include/linux/security.h 2006-10-25 09:34:47.0 -0500 +++ net-2.6.xfrm2/include/linux/security.h 2006-10-25 12:26:20.0 -0500 @@ -826,6 +826,8 @@ struct request_sock; * Sets the openreq's sid to socket's sid with MLS portion taken from peer sid. * @inet_csk_clone: * Sets the new child socket's sid to the openreq sid. + * @inet_conn_established: + * Sets the connection's peersid to the secmark on skb. * @req_classify_flow: * Sets the flow's sid to the openreq sid. * @@ -1368,6 +1370,7 @@ struct security_operations { int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb, struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); + void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); #endif /* CONFIG_SECURITY_NETWORK */ @@ -2961,6 +2964,12 @@ static inline void security_inet_csk_clo { security_ops->inet_csk_clone(newsk, req); } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ + security_ops->inet_conn_established(sk, skb); +} #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct socket * sock, struct socket * other, @@ -3110,6 +3119,11 @@ static inline void security_inet_csk_clo const struct request_sock *req) { } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM --- net-2.6.xfrm1/include/net/request_sock.h2006-10-25 11:20:48.0 -0500 +++ net-2.6.xfrm2/include/net/request_sock.h2006-10-25 11:21:56.0 -0500 @@ -54,6 +54,7 @@ struct request_sock { struct request_sock_ops *rsk_ops; struct sock *sk; u32 secid; + u32 peer_secid; }; static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) --- net-2.6.xfrm1/net/ipv4/tcp_input.c 2006-10-25 12:29:06.0 -0500 +++ net-2.6.xfrm2/net/ipv4/tcp_input.c 2006-10-25 12:30:07.0 -0500 @@ -4230,6 +4230,8 @@ static int tcp_rcv_synsent_state_process mb(); tcp_set_state(sk, TCP_ESTABLISHED); + security_inet_conn_established(sk, skb); + /* Make sure socket is routed, for correct metrics. */ icsk->icsk_af_ops->rebuild_header(sk); --- net-2.6.xfrm1/security/dummy.c 2006-10-23 14:31:28.0 -0500 +++ net-2.6.xfrm2/security/dummy.c 2006-10-25 12:23:47.0 -0500 @@ -828,6 +828,11 @@ static inline void dummy_inet_csk_clone( { } +static inline void dummy_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} + static inline void dummy_req_classify_flow(const struct request_sock *req, struct flowi *fl) { @@ -1108,6 +1113,7 @@ void security_fixup_ops (struct security set_to_dummy_if_null(ops, sock_graft); set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); + set_to_dummy_if_null(ops, inet_conn_established); set_to_dummy_if_null(ops, req_classify_flow); #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM --- net-2.6.xfrm1/security/selinux/include/xfrm.h 2006-10-23 14:31:56.0 -0500 +++ net-2.6.xfrm2/security/selinux/include/xfrm.h 2006-11-07 09:49:24.0 -0600 @@ -39,7 +39,6 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s struct avc_audit_data *ad); int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, struct avc_audit_data *ad); -u32 selinux_socket_getpeer_stream(struct sock *sk); u32 selinux_socket_getpeer_dgram(struct sk_buff *skb); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); #else @@ -55,11 +54,6 @@ static inline int selinux_xfrm_post
[PATCH 3/3] mlsxfrm: Various fixes
Fix the selection of an SA for an outgoing packet to be at the same context as the originating socket/flow. This eliminates the SELinux policy's ability to use/sendto SAs with contexts other than the socket's. With this patch applied, the SELinux policy will require one or more of the following for a socket to be able to communicate with/without SAs: 1. To enable a socket to communicate without using labeled-IPSec SAs: allow socket_t unlabeled_t:association { sendto recvfrom } 2. To enable a socket to communicate with labeled-IPSec SAs: allow socket_t self:association { sendto }; allow socket_t peer_sa_t:association { recvfrom }; Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 19 - net/xfrm/xfrm_policy.c |3 security/dummy.c|7 - security/selinux/hooks.c| 26 -- security/selinux/include/security.h |2 security/selinux/include/xfrm.h |7 - security/selinux/ss/services.c | 44 +++ security/selinux/xfrm.c | 97 -- 8 files changed, 112 insertions(+), 93 deletions(-) --- net-2.6.xfrm2/include/linux/security.h 2006-10-25 12:26:20.0 -0500 +++ net-2.6/include/linux/security.h2006-11-01 11:22:17.0 -0600 @@ -886,11 +886,6 @@ struct request_sock; * @xp contains the policy to check for a match. * @fl contains the flow to check for a match. * Return 1 if there is a match. - * @xfrm_flow_state_match: - * @fl contains the flow key to match. - * @xfrm points to the xfrm_state to match. - * @xp points to the xfrm_policy to match. - * Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. * @secid points to the flow key secid to set. @@ -1388,8 +1383,6 @@ struct security_operations { int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); - int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp); int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ @@ -3186,12 +3179,6 @@ static inline int security_xfrm_state_po return security_ops->xfrm_state_pol_flow_match(x, xp, fl); } -static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) -{ - return security_ops->xfrm_flow_state_match(fl, xfrm, xp); -} - static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) { return security_ops->xfrm_decode_session(skb, secid, 1); @@ -3255,12 +3242,6 @@ static inline int security_xfrm_state_po return 1; } -static inline int security_xfrm_flow_state_match(struct flowi *fl, - struct xfrm_state *xfrm, struct xfrm_policy *xp) -{ - return 1; -} - static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) { return 0; --- net-2.6.xfrm2/net/xfrm/xfrm_policy.c2006-11-01 11:25:39.0 -0600 +++ net-2.6/net/xfrm/xfrm_policy.c 2006-11-01 12:10:23.0 -0600 @@ -1894,7 +1894,8 @@ int xfrm_bundle_ok(struct xfrm_policy *p if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) return 0; - if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) + if (fl && pol && + !security_xfrm_state_pol_flow_match(dst->xfrm, pol, fl)) return 0; if (dst->xfrm->km.state != XFRM_STATE_VALID) return 0; --- net-2.6.xfrm2/security/dummy.c 2006-10-25 12:23:47.0 -0500 +++ net-2.6/security/dummy.c2006-11-01 11:22:34.0 -0600 @@ -886,12 +886,6 @@ static int dummy_xfrm_state_pol_flow_mat return 1; } -static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, - struct xfrm_policy *xp) -{ - return 1; -} - static int dummy_xfrm_decode_session(struct sk_buff *skb, u32 *fl, int ckall) { return 0; @@ -1126,7 +1120,6 @@ void security_fixup_ops (struct security set_to_dummy_if_null(ops, xfrm_state_delete_security); set_to_dummy_if_null(ops, xfrm_policy_lookup); set_to_dummy_if_null(ops, xfrm_state_pol_flow_match); - set_to_dummy_if_null(ops, xfrm_flow_state_match); set_to_dummy_if_null(ops, xfrm_decode_session); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ #ifdef CONFIG_KEYS --- net-2.6.xfrm2/security/selinux/include/xfrm.h 2006-11-07 09:49:24.0 -0600 +++ net-2.6/security/selinu
RE: [PATCH 00/11] The _entire_ secid reconciliation patchset (tada!)
> From an initial review of this patchset, it doesn't look > quite ready to > queue for 2.6.20 (which I plan to to via git once it is). > > Outstanding items include resolving the igmp skb hook issue > generally, > testing to verify both the design and implementation, and > ensuring that > all the related policy changes are merged upstream first. > Regarding the igmp hook issue, we could do a generic hook like Paul suggested. Would that be more palatable you think? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.04: Fix selinux code
Currently when an IPSec policy rule doesn't specify a security context, it is assumed to be "unlabeled" by SELinux, and so the IPSec policy rule fails to match to a flow that it would otherwise match to, unless one has explicitly added an SELinux policy rule allowing the flow to "polmatch" to the "unlabeled" IPSec policy rules. In the absence of such an explicitly added SELinux policy rule, the IPSec policy rule fails to match and so the packet(s) flow in clear text without the otherwise applicable xfrm(s) applied. The above SELinux behavior violates the SELinux security notion of "deny by default" which should actually translate to "encrypt by default" in the above case. This was first reported by Evgeniy Polyakov and the way James Morris was seeing the problem was when connecting via IPsec to a confined service on an SELinux box (vsftpd), which did not have the appropriate SELinux policy permissions to send packets via IPsec. With this patch applied, SELinux "polmatching" of flows Vs. IPSec policy rules will only come into play when there's a explicit context specified for the IPSec policy rule (which also means there's corresponding SELinux policy allowing appropriate domains/flows to polmatch to this context). Secondly, when a security module is loaded (in this case, SELinux), the security_xfrm_policy_lookup() hook can return errors other than access denied, such as -EINVAL. We were not handling that correctly, and in fact inverting the return logic and propagating a false "ok" back up to xfrm_lookup(), which then allowed packets to pass as if they were not associated with an xfrm policy. The solution for this is to first ensure that errno values are correctly propagated all the way back up through the various call chains from security_xfrm_policy_lookup(), and handled correctly. Then, flow_cache_lookup() is modified, so that if the policy resolver fails (typically a permission denied via the security module), the flow cache entry is killed rather than having a null policy assigned (which indicates that the packet can pass freely). This also forces any future lookups for the same flow to consult the security module (e.g. SELinux) for current security policy (rather than, say, caching the error on the flow cache entry). This patch: Fix the selinux side of things. This makes sure SELinux polmatching of flow contexts to IPSec policy rules comes into play only when an explicit context is associated with the IPSec policy rule. Also, this no longer defaults the context of a socket policy to the context of the socket since the "no explicit context" case is now handled properly. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 24 + include/net/xfrm.h |3 + net/ipv4/xfrm4_policy.c |2 - net/ipv6/xfrm6_policy.c |2 - net/key/af_key.c|5 -- net/xfrm/xfrm_policy.c |7 ++- net/xfrm/xfrm_user.c|9 - security/dummy.c|3 + security/selinux/include/xfrm.h |3 + security/selinux/xfrm.c | 53 +++--- 10 files changed, 62 insertions(+), 49 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 9b5fea8..b200b98 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -882,7 +882,8 @@ #ifdef CONFIG_SECURITY * Check permission when a flow selects a xfrm_policy for processing * XFRMs on a packet. The hook is called when selecting either a * per-socket policy or a generic xfrm policy. - * Return 0 if permission is granted. + * Return 0 if permission is granted, -ESRCH otherwise, or -errno + * on other errors. * @xfrm_state_pol_flow_match: * @x contains the state to match. * @xp contains the policy to check for a match. @@ -891,6 +892,7 @@ #ifdef CONFIG_SECURITY * @xfrm_flow_state_match: * @fl contains the flow key to match. * @xfrm points to the xfrm_state to match. + * @xp points to the xfrm_policy to match. * Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. @@ -1388,7 +1390,8 @@ #ifdef CONFIG_SECURITY_NETWORK_XFRM int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); - int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); + int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm, + struct xfrm_policy *xp); int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ @@ -3120,11 +3123,6 @@ static inline int security_xfrm_policy_
[PATCH 2/3] Fix for IPsec leakage with SELinux enabled - V.04: Fix xfrm code
From: James Morris <[EMAIL PROTECTED]> When a security module is loaded (in this case, SELinux), the security_xfrm_policy_lookup() hook can return an access denied permission (or other error). We were not handling that correctly, and in fact inverting the return logic and propagating a false "ok" back up to xfrm_lookup(), which then allowed packets to pass as if they were not associated with an xfrm policy. The way I was seeing the problem was when connecting via IPsec to a confined service on an SELinux box (vsftpd), which did not have the appropriate SELinux policy permissions to send packets via IPsec. The first SYNACK would be blocked, because of an uncached lookup via flow_cache_lookup(), which would fail to resolve an xfrm policy because the SELinux policy is checked at that point via the resolver. However, retransmitted SYNACKs would then find a cached flow entry when calling into flow_cache_lookup() with a null xfrm policy, which is interpreted by xfrm_lookup() as the packet not having any associated policy and similarly to the first case, allowing it to pass without transformation. The solution presented here is to first ensure that errno values are correctly propagated all the way back up through the various call chains from security_xfrm_policy_lookup(), and handled correctly. Then, flow_cache_lookup() is modified, so that if the policy resolver fails (typically a permission denied via the security module), the flow cache entry is killed rather than having a null policy assigned (which indicates that the packet can pass freely). This also forces any future lookups for the same flow to consult the security module (e.g. SELinux) for current security policy (rather than, say, caching the error on the flow cache entry). Signed-off-by: James Morris <[EMAIL PROTECTED]> --- include/net/flow.h |2 - net/core/flow.c| 42 net/xfrm/xfrm_policy.c | 68 ++- 3 files changed, 82 insertions(+), 30 deletions(-) --- net-2.6.leak1/include/net/flow.h2006-10-09 08:54:39.0 -0500 +++ net-2.6.leak2/include/net/flow.h2006-10-09 10:50:32.0 -0500 @@ -97,7 +97,7 @@ struct flowi { #define FLOW_DIR_FWD 2 struct sock; -typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, +typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, void **objp, atomic_t **obj_refp); extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, --- net-2.6.leak1/net/core/flow.c 2006-10-09 08:54:40.0 -0500 +++ net-2.6.leak2/net/core/flow.c 2006-10-09 10:50:32.0 -0500 @@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsig add_timer(&flow_hash_rnd_timer); } +static void flow_entry_kill(int cpu, struct flow_cache_entry *fle) +{ + if (fle->object) + atomic_dec(fle->object_ref); + kmem_cache_free(flow_cachep, fle); + flow_count(cpu)--; +} + static void __flow_cache_shrink(int cpu, int shrink_to) { struct flow_cache_entry *fle, **flp; @@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, } while ((fle = *flp) != NULL) { *flp = fle->next; - if (fle->object) - atomic_dec(fle->object_ref); - kmem_cache_free(flow_cachep, fle); - flow_count(cpu)--; + flow_entry_kill(cpu, fle); } } } @@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *ke nocache: { + int err; void *obj; atomic_t *obj_ref; - resolver(key, family, dir, &obj, &obj_ref); + err = resolver(key, family, dir, &obj, &obj_ref); if (fle) { - fle->genid = atomic_read(&flow_cache_genid); - - if (fle->object) - atomic_dec(fle->object_ref); - - fle->object = obj; - fle->object_ref = obj_ref; - if (obj) - atomic_inc(fle->object_ref); + if (err) { + /* Force security policy check on next lookup */ + *head = fle->next; + flow_entry_kill(cpu, fle); + } else { + fle->genid = atomic_read(&flow_cache_genid); + + if (fle->object) + atomic_dec(fle->object_ref); + + fle->object = obj; + fle->object_ref = obj_ref; + if (obj) +
[PATCH 0/3] Fix for IPsec leakage with SELinux enabled - V.04
This is a bug fix for the MLSXFRM patchset already queued for 2.6.19. This version is just a repost of V.03 with the subject titles fixed up, and the patches ported to davem's net-2.6.git as of today. include/linux/security.h| 24 ++- include/net/flow.h |2 include/net/xfrm.h |3 net/core/flow.c | 42 net/ipv4/xfrm4_policy.c |2 net/ipv6/xfrm6_policy.c |2 net/key/af_key.c|5 - net/xfrm/xfrm_policy.c | 101 ++ net/xfrm/xfrm_user.c|9 -- security/dummy.c|3 security/selinux/include/xfrm.h |3 security/selinux/xfrm.c | 53 --- 12 files changed, 162 insertions(+), 87 deletions(-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] Fix for IPsec leakage with SELinux enabled - V.04: Process security errors for scket policies also
This treats the security errors encountered in the case of socket policy matching, the same as how these are treated in the case of main/sub policies, which is to return a full lookup failure. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- net/xfrm/xfrm_policy.c | 26 ++ 1 file changed, 18 insertions(+), 8 deletions(-) --- net-2.6.leak2/net/xfrm/xfrm_policy.c2006-10-09 10:50:32.0 -0500 +++ net-2.6.leak3/net/xfrm/xfrm_policy.c2006-10-09 10:51:01.0 -0500 @@ -1016,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_polic sk->sk_family); int err = 0; - if (match) - err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); - - if (match && !err) - xfrm_pol_hold(pol); - else + if (match) { + err = security_xfrm_policy_lookup(pol, fl->secid, + policy_to_flow_dir(dir)); + if (!err) + xfrm_pol_hold(pol); + else if (err == -ESRCH) + pol = NULL; + else + pol = ERR_PTR(err); + } else pol = NULL; } read_unlock_bh(&xfrm_policy_lock); @@ -1313,8 +1317,11 @@ restart: pol_dead = 0; xfrm_nr = 0; - if (sk && sk->sk_policy[1]) + if (sk && sk->sk_policy[1]) { policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); + if (IS_ERR(policy)) + return PTR_ERR(policy); + } if (!policy) { /* To accelerate a bit... */ @@ -1607,8 +1614,11 @@ int __xfrm_policy_check(struct sock *sk, } pol = NULL; - if (sk && sk->sk_policy[dir]) + if (sk && sk->sk_policy[dir]) { pol = xfrm_sk_policy_lookup(sk, dir, &fl); + if (IS_ERR(pol)) + return 0; + } if (!pol) pol = flow_cache_lookup(&fl, family, fl_dir, - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] Fix for IPsec leakage with SELinux enabled - V.03
> > My apologies. The second one is also numbered 1, but has the > > following distinct subject line: > > [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - > V.03: Fix xfrm code > > I definitely deleted one of them, since I usually get N copies > of very single patch posting and two of them looked identical:) I guess this is probably the reason why I don't see the fix in net-2.6.git yet :) I will resend the patchset with the subject titles fixed up since it needs to be in 2.6.19. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03
> From: James Morris <[EMAIL PROTECTED]> > Date: Thu, 5 Oct 2006 16:54:38 -0400 (EDT) > > > > #ifdef CONFIG_XFRM_SUB_POLICY > > > pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, > fl, family, dir); > > > - if (pol) > > > + if (IS_ERR(pol)) { > > > + err = PTR_ERR(pol); > > > + pol = NULL; > > > + } > > > + if (pol || err) > > > goto end; > > > > Similarly, if the sub-policy lookup returns -EACCESS, > should we then try a > > main policy lookup before failing? > > We're trying to fill the flow cache here. In the case where we'd > have a match in both the sub-policy and main table, I think the > sub-policy is supposed to take precedence, and if you fail to get > this sub-policy you should fail the entire lookup. Which is what's happening here correct? > > The way the sub-policied entries work is that you find the sub-policy > as the primary object in the flow cache, and once you notice you have > a sub-policy you do an explicit lookup in the main table to put the > whole thing together. May be James can help me understand this; when exactly would a sub-policy be "notice"d here? What does "put the whole thing together" mean? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] Fix for IPsec leakage with SELinux enabled - V.03
> > > This version takes into account David Miller's comments > > > regarding treatment of security layer errors in the case > > > of socket policies. Specifically, these errors will be > > > treated like how these kind of errors are treated for > > > the main/sub policies, which is to return a full lookup > > > failure. > > > > I only have patches "1" and "3" in my inbox, did you forget > > to send the second one out or are they simply misnumbered? > > > > My apologies. The second one is also numbered 1, but has the > following distinct subject line: > [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - > V.03: Fix xfrm code In actuality, patch 2 in the series has the following subject line: [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03
> > - if (xfrm_policy_match(pol, fl, type, family, dir)) { > > + err = xfrm_policy_match(pol, fl, type, family, dir); > > + if (err) { > > + if (err == -ESRCH) > > + continue; > > + else { > > + ret = ERR_PTR(err); > > + goto fail; > > + } > > + } else { > > Semantics issue: if the exact policy match fails with > -EACCESS, should we > then try an inexact match before failing? I wonder what you mean by an inexact match here. > > > #ifdef CONFIG_XFRM_SUB_POLICY > > pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, > fl, family, dir); > > - if (pol) > > + if (IS_ERR(pol)) { > > + err = PTR_ERR(pol); > > + pol = NULL; > > + } > > + if (pol || err) > > goto end; > > Similarly, if the sub-policy lookup returns -EACCESS, should > we then try a > main policy lookup before failing? I would think not since we are already handling the more usual "failure" of EACCES properly, and any other error would usually have to be a near-fatal error concerning the whole LSM policy or temporary memory pressure, for example. Usually the latter is auto handled when the callers reattempt the llokup. While it is theoretically possible that the LSM might generate an error for the sub but not for the main, we would have to first redefine the LSM hook to communicate this differentiation. And at least in the case of the current user of LSM (SELinux) I don't currently see the need for this differentiation. > > I would think yes to both. > > Opinions? > > > - James > -- > James Morris > <[EMAIL PROTECTED]> > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] Fix for IPsec leakage with SELinux enabled - V.03
> > This version takes into account David Miller's comments > > regarding treatment of security layer errors in the case > > of socket policies. Specifically, these errors will be > > treated like how these kind of errors are treated for > > the main/sub policies, which is to return a full lookup > > failure. > > I only have patches "1" and "3" in my inbox, did you forget > to send the second one out or are they simply misnumbered? > My apologies. The second one is also numbered 1, but has the following distinct subject line: [PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03: Fix xfrm code - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03
From: James Morris <[EMAIL PROTECTED]> When a security module is loaded (in this case, SELinux), the security_xfrm_policy_lookup() hook can return an access denied permission (or other error). We were not handling that correctly, and in fact inverting the return logic and propagating a false "ok" back up to xfrm_lookup(), which then allowed packets to pass as if they were not associated with an xfrm policy. The way I was seeing the problem was when connecting via IPsec to a confined service on an SELinux box (vsftpd), which did not have the appropriate SELinux policy permissions to send packets via IPsec. The first SYNACK would be blocked, because of an uncached lookup via flow_cache_lookup(), which would fail to resolve an xfrm policy because the SELinux policy is checked at that point via the resolver. However, retransmitted SYNACKs would then find a cached flow entry when calling into flow_cache_lookup() with a null xfrm policy, which is interpreted by xfrm_lookup() as the packet not having any associated policy and similarly to the first case, allowing it to pass without transformation. The solution presented here is to first ensure that errno values are correctly propagated all the way back up through the various call chains from security_xfrm_policy_lookup(), and handled correctly. Then, flow_cache_lookup() is modified, so that if the policy resolver fails (typically a permission denied via the security module), the flow cache entry is killed rather than having a null policy assigned (which indicates that the packet can pass freely). This also forces any future lookups for the same flow to consult the security module (e.g. SELinux) for current security policy (rather than, say, caching the error on the flow cache entry). Signed-off-by: James Morris <[EMAIL PROTECTED]> --- include/net/flow.h |2 - net/core/flow.c| 42 net/xfrm/xfrm_policy.c | 68 ++- 3 files changed, 82 insertions(+), 30 deletions(-) diff -purN -X dontdiff net-2.6.o/include/net/flow.h net-2.6.w/include/net/flow.h --- net-2.6.o/include/net/flow.h2006-09-29 11:33:58.0 -0400 +++ net-2.6.w/include/net/flow.h2006-09-30 23:50:32.0 -0400 @@ -97,7 +97,7 @@ struct flowi { #define FLOW_DIR_FWD 2 struct sock; -typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, +typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, void **objp, atomic_t **obj_refp); extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, diff -purN -X dontdiff net-2.6.o/net/core/flow.c net-2.6.w/net/core/flow.c --- net-2.6.o/net/core/flow.c 2006-09-29 11:33:59.0 -0400 +++ net-2.6.w/net/core/flow.c 2006-10-01 01:07:24.0 -0400 @@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsig add_timer(&flow_hash_rnd_timer); } +static void flow_entry_kill(int cpu, struct flow_cache_entry *fle) +{ + if (fle->object) + atomic_dec(fle->object_ref); + kmem_cache_free(flow_cachep, fle); + flow_count(cpu)--; +} + static void __flow_cache_shrink(int cpu, int shrink_to) { struct flow_cache_entry *fle, **flp; @@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, } while ((fle = *flp) != NULL) { *flp = fle->next; - if (fle->object) - atomic_dec(fle->object_ref); - kmem_cache_free(flow_cachep, fle); - flow_count(cpu)--; + flow_entry_kill(cpu, fle); } } } @@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *ke nocache: { + int err; void *obj; atomic_t *obj_ref; - resolver(key, family, dir, &obj, &obj_ref); + err = resolver(key, family, dir, &obj, &obj_ref); if (fle) { - fle->genid = atomic_read(&flow_cache_genid); - - if (fle->object) - atomic_dec(fle->object_ref); - - fle->object = obj; - fle->object_ref = obj_ref; - if (obj) - atomic_inc(fle->object_ref); + if (err) { + /* Force security policy check on next lookup */ + *head = fle->next; + flow_entry_kill(cpu, fle); + } else { + fle->genid = atomic_read(&flow_cache_genid); + + if (fle->object) + atomic_dec(fle->object_ref); + + fle->object =
[PATCH 1/3] Fix for IPsec leakage with SELinux enabled - V.03: Fix xfrm code
Currently when an IPSec policy rule doesn't specify a security context, it is assumed to be "unlabeled" by SELinux, and so the IPSec policy rule fails to match to a flow that it would otherwise match to, unless one has explicitly added an SELinux policy rule allowing the flow to "polmatch" to the "unlabeled" IPSec policy rules. In the absence of such an explicitly added SELinux policy rule, the IPSec policy rule fails to match and so the packet(s) flow in clear text without the otherwise applicable xfrm(s) applied. The above SELinux behavior violates the SELinux security notion of "deny by default" which should actually translate to "encrypt by default" in the above case. This was first reported by Evgeniy Polyakov and the way James Morris was seeing the problem was when connecting via IPsec to a confined service on an SELinux box (vsftpd), which did not have the appropriate SELinux policy permissions to send packets via IPsec. With this patch applied, SELinux "polmatching" of flows Vs. IPSec policy rules will only come into play when there's a explicit context specified for the IPSec policy rule (which also means there's corresponding SELinux policy allowing appropriate domains/flows to polmatch to this context). Secondly, when a security module is loaded (in this case, SELinux), the security_xfrm_policy_lookup() hook can return errors other than access denied, such as -EINVAL. We were not handling that correctly, and in fact inverting the return logic and propagating a false "ok" back up to xfrm_lookup(), which then allowed packets to pass as if they were not associated with an xfrm policy. The solution for this is to first ensure that errno values are correctly propagated all the way back up through the various call chains from security_xfrm_policy_lookup(), and handled correctly. Then, flow_cache_lookup() is modified, so that if the policy resolver fails (typically a permission denied via the security module), the flow cache entry is killed rather than having a null policy assigned (which indicates that the packet can pass freely). This also forces any future lookups for the same flow to consult the security module (e.g. SELinux) for current security policy (rather than, say, caching the error on the flow cache entry). This patch: Fix the selinux side of things. This makes sure SELinux polmatching of flow contexts to IPSec policy rules comes into play only when an explicit context is associated with the IPSec policy rule. Also, this no longer defaults the context of a socket policy to the context of the socket since the "no explicit context" case is now handled properly. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h| 24 + include/net/xfrm.h |3 + net/ipv4/xfrm4_policy.c |2 - net/ipv6/xfrm6_policy.c |2 - net/key/af_key.c|5 -- net/xfrm/xfrm_policy.c |7 ++- net/xfrm/xfrm_user.c|9 - security/dummy.c|3 + security/selinux/include/xfrm.h |3 + security/selinux/xfrm.c | 53 +++--- 10 files changed, 62 insertions(+), 49 deletions(-) --- net-2.6.sid3/include/linux/security.h 2006-10-01 15:18:23.0 -0500 +++ net-2.6.sid4/include/linux/security.h 2006-10-05 12:03:39.0 -0500 @@ -893,7 +893,8 @@ struct request_sock; * Check permission when a flow selects a xfrm_policy for processing * XFRMs on a packet. The hook is called when selecting either a * per-socket policy or a generic xfrm policy. - * Return 0 if permission is granted. + * Return 0 if permission is granted, -ESRCH otherwise, or -errno + * on other errors. * @xfrm_state_pol_flow_match: * @x contains the state to match. * @xp contains the policy to check for a match. @@ -902,6 +903,7 @@ struct request_sock; * @xfrm_flow_state_match: * @fl contains the flow key to match. * @xfrm points to the xfrm_state to match. + * @xp points to the xfrm_policy to match. * Return 1 if there is a match. * @xfrm_decode_session: * @skb points to skb to decode. @@ -1402,7 +1404,8 @@ struct security_operations { int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, struct flowi *fl); - int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); + int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm, + struct xfrm_policy *xp); int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); #endif /* CONFIG_SECURITY_NETWORK_XFRM */ @@ -3168,11 +3171,6 @@ static inline int security_xfrm_policy_
[PATCH 0/3] Fix for IPsec leakage with SELinux enabled - V.03
This version takes into account David Miller's comments regarding treatment of security layer errors in the case of socket policies. Specifically, these errors will be treated like how these kind of errors are treated for the main/sub policies, which is to return a full lookup failure. include/linux/security.h| 24 ++- include/net/flow.h |2 include/net/xfrm.h |3 net/core/flow.c | 42 net/ipv4/xfrm4_policy.c |2 net/ipv6/xfrm6_policy.c |2 net/key/af_key.c|5 - net/xfrm/xfrm_policy.c | 101 ++ net/xfrm/xfrm_user.c|9 -- security/dummy.c|3 security/selinux/include/xfrm.h |3 security/selinux/xfrm.c | 53 --- 12 files changed, 162 insertions(+), 87 deletions(-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] Fix for IPsec leakage with SELinux enabled - V.03: Process security errors for scket policies also
This treats the security errors encountered in the case of socket policy matching, the same as how these are treated in the case of main/sub policies, which is to return a full lookup failure. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- net/xfrm/xfrm_policy.c | 26 ++ 1 file changed, 18 insertions(+), 8 deletions(-) --- net-2.6.sid5/net/xfrm/xfrm_policy.c 2006-10-05 14:36:07.0 -0500 +++ net-2.6/net/xfrm/xfrm_policy.c 2006-10-05 14:38:32.0 -0500 @@ -1013,12 +1013,16 @@ static struct xfrm_policy *xfrm_sk_polic sk->sk_family); int err = 0; - if (match) - err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); - - if (match && !err) - xfrm_pol_hold(pol); - else + if (match) { + err = security_xfrm_policy_lookup(pol, fl->secid, + policy_to_flow_dir(dir)); + if (!err) + xfrm_pol_hold(pol); + else if (err == -ESRCH) + pol = NULL; + else + pol = ERR_PTR(err); + } else pol = NULL; } read_unlock_bh(&xfrm_policy_lock); @@ -1310,8 +1314,11 @@ restart: pol_dead = 0; xfrm_nr = 0; - if (sk && sk->sk_policy[1]) + if (sk && sk->sk_policy[1]) { policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); + if (IS_ERR(policy)) + return PTR_ERR(policy); + } if (!policy) { /* To accelerate a bit... */ @@ -1604,8 +1611,11 @@ int __xfrm_policy_check(struct sock *sk, } pol = NULL; - if (sk && sk->sk_policy[dir]) + if (sk && sk->sk_policy[dir]) { pol = xfrm_sk_policy_lookup(sk, dir, &fl); + if (IS_ERR(pol)) + return 0; + } if (!pol) pol = flow_cache_lookup(&fl, family, fl_dir, - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v4 1/2] NetLabel: secid reconciliation support
> On Wed, 2006-10-04 at 15:27 -0400, Paul Moore wrote: > > Venkat Yekkirala wrote: > > >> * XFRM present > > >> > > >> xfrm_sid = > > >> loc_sid = SECINITSID_NETMSG > > >> nlbl_sid = SECSID_NULL/0 > > >> ext_sid = xfrm_sid > > >> final skb->secmark = avc_ok : ext_sid ? unchanged As noted subsequently, I actually meant to refer to the below instead of the XFRM case above: * Nothing xfrm_sid = SECSID_NULL/0 loc_sid = SECSID_NULL/0 nlbl_sid = SECSID_NULL/0 ext_sid = xfrm_sid final skb->secmark = avc_ok : ext_sid ? unchanged > > >> > > >> * NetLabel present > > >> > > >> xfrm_sid = SECSID_NULL/0 > > >> loc_sid = SECSID_NULL/0 > > >> nlbl_sid = > > >> ext_sid = nlbl_sid > > >> final skb->secmark = avc_ok : ext_sid ? unchanged > > > > > > I was referring to the differences in what getpeercon would > > > return in the above 2 scenarios. > > > > > > In the xfrm case: final skb->secmark would be 0 > resulting in getpeercon > > > to return EPROTONOOPT > > > > In the "XFRM present" case above if the access is allowed (avc_ok is > > true) then the final skb->secmark value is going to be set > to the value > > of ext_sid which is the xfrm_sid. Any calls made to > getpeercon() would > > return success with the context matching xfrm_sid. > > > > I have a hunch we are still on different pages here ... > > > > > In the NetLabel case: final skb->secmark would be > network_t resulting in > > > getpeercon to return network_t > > > > Yep, and I understand you would like to see it as > unlabeled_t. I think > > we both have valid arguments for either case and we are > just waiting to > > hear from others. > > I don't understand the argument for network_t, and it seems to violate > our goals of 1) having consistent policy regardless of > network labeling > mechanism, and 2) having getpeercon() always return a subject > label that > can be used as a basis for avc_has_perm() and setexeccon() calls. But in the case where there's no domain info, but a cipso label, getpeercon will fail (EPROTONOOPT). Do I rememember that Paul was trying to use a special SID to use as a base sid in this case? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v4 1/2] NetLabel: secid reconciliation support
> >> * XFRM present > >> > >> xfrm_sid = > >> loc_sid = SECINITSID_NETMSG > >> nlbl_sid = SECSID_NULL/0 > >> ext_sid = xfrm_sid > >> final skb->secmark = avc_ok : ext_sid ? unchanged Actually, I meant to cite the following instead of the above: * Nothing xfrm_sid = SECSID_NULL/0 loc_sid = SECSID_NULL/0 nlbl_sid = SECSID_NULL/0 ext_sid = xfrm_sid final skb->secmark = avc_ok : ext_sid ? unchanged > >> > >> * NetLabel present > >> > >> xfrm_sid = SECSID_NULL/0 > >> loc_sid = SECSID_NULL/0 > >> nlbl_sid = > >> ext_sid = nlbl_sid > >> final skb->secmark = avc_ok : ext_sid ? unchanged > > > > I was referring to the differences in what getpeercon would > > return in the above 2 scenarios. > > > > In the xfrm case: final skb->secmark would be 0 > resulting in getpeercon > > to return EPROTONOOPT > > In the "XFRM present" case above if the access is allowed (avc_ok is > true) then the final skb->secmark value is going to be set to > the value > of ext_sid which is the xfrm_sid. Any calls made to > getpeercon() would > return success with the context matching xfrm_sid. You are right, but I was actually referring to the "Nothing" case above. > > I have a hunch we are still on different pages here ... > > > In the NetLabel case: final skb->secmark would be network_t > resulting in > > getpeercon to return network_t > > Yep, and I understand you would like to see it as > unlabeled_t. I think > we both have valid arguments for either case and we are just > waiting to > hear from others. > > -- > paul moore > linux security @ hp > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v4 1/2] NetLabel: secid reconciliation support
> * XFRM present > >xfrm_sid = >loc_sid = SECINITSID_NETMSG >nlbl_sid = SECSID_NULL/0 >ext_sid = xfrm_sid >final skb->secmark = avc_ok : ext_sid ? unchanged > > * NetLabel present > >xfrm_sid = SECSID_NULL/0 >loc_sid = SECSID_NULL/0 >nlbl_sid = >ext_sid = nlbl_sid >final skb->secmark = avc_ok : ext_sid ? unchanged I was referring to the differences in what getpeercon would return in the above 2 scenarios. In the xfrm case: final skb->secmark would be 0 resulting in getpeercon to return EPROTONOOPT In the NetLabel case: final skb->secmark would be network_t resulting in getpeercon to return network_t > > * Nothing > >xfrm_sid = SECSID_NULL/0 >loc_sid = SECSID_NULL/0 >nlbl_sid = SECSID_NULL/0 >ext_sid = xfrm_sid >final skb->secmark = avc_ok : ext_sid ? unchanged > > > This has implications for getpeercon() where it would > > > > - fail with ENOPROTOOPT (xfrm case) > > - returns network_t (netlabel) > > > > I would still argue that the nature of the domain being carried by > > the packet is still unlabeled_t as implied by the null > secmark. While > > I view secmark/point as specifying BOTH a flow control point and a > > default domain (incidentally using the same label more because of > > implementation constrainst), I view network_t as purely a > flow control > > point. > > > > But I also realize there can be equally forceful arguments > for what this > > patch does. > > I know the two of us have talked about this before on the mail lists, > but I don't believe anyone else has ever made a comment in > this regard. > I tend to feel rather strongly that when using just NetLabel on a > connection you shouldn't see an "unlabeled_t" type as I feel that the > connotation associated with this type is misleading, even > though from a > TE point of view there may be an argument made that it is appropriate. > > > What does the community think? We need to resolve it one way or the > > other unless the above differences in behavior are desired > or somehow > > accounted for in policy and apps. > > I agree - I'd like to hear what others (namely Stephen Smalley, James > Morris and all of the Tresys folks ) have to say on > this issue. > > -- > paul moore > linux security @ hp > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/2] [PATCH 0/2] Updated NetLabel/secid-reconciliation bits and a bugfix
> > As for the rest of the network labeling, please work > together with Venkat > > and the SELinux developers on a final patchset which meets > all of the > > design goals and has been tested, with policy which has been merged > > upstream and is available via Fedora devel. Please keep > the discussion > > going, but ensure that the final patchset for review and merge > > consideration is a complete set against the current git > kernel coming from > > one person. > > I'm trying :) When I posted the NetLabel secid support patch > last week > I asked Venkat if he could merge it with the main secid > patchset (due to > size and dependencies that seemed like the most reasonable course of > action). For reasons I'm not aware of he chose not to. FYI- I am no NetLabel expert, and the pathset I sent out that day included the peersid changes. And since you were going to have to post a patch for that again, I thought it best you ported and reposted the entire patch again. > As a result I > keep posting updated patches backed against Venkat's latest and > incorporating the latest feedback. And let's keep this going like this on the selinux list. When all the testing is done and selinux ok's the patchsets, I will combine them and send them onto netdev. How does that sound? > > Venkat, can you please merge the latest my latest NetLabel > secid support > patch in with your next release? I would, but it currently is premature. As James says, let's get policy done, the design proven, and tested and then we will go to netdev with one patchset. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v4 1/2] NetLabel: secid reconciliation support
> > @@ -3714,19 +3714,34 @@ static int selinux_skb_flow_in(struct sk > > if (skb->dev == &loopback_dev) > > return 1; > > > > + if (skb->secmark) > > + loc_sid = skb->secmark; > > + else > > + loc_sid = SECINITSID_NETMSG; > > + > > err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); > > BUG_ON(err); > > - > > - err = avc_has_perm(xfrm_sid, skb->secmark? : SECINITSID_NETMSG, > > - SECCLASS_PACKET, > > - PACKET__FLOW_IN, NULL); > > + err = selinux_netlbl_skb_sid(skb, > > +xfrm_sid ? xfrm_sid : loc_sid, > > +&nlbl_sid); > > if (err) > > goto out; > > > > - if (xfrm_sid) > > - skb->secmark = xfrm_sid; > > + if (nlbl_sid) > > + ext_sid = nlbl_sid; > > + else > > + ext_sid = xfrm_sid; > > There's a problem here in that it would require 2 different policies > depending on whether one is using netlabel or xfrm. Specifically, in > the absence of matching iptables contexts (secmark), as well as any external labeling via ipsec/NetLabel, > the skb here > will get: > > - 0 (xfrm case) > - network_t (netlabel) > > This has implications for getpeercon() where it would > > - fail with ENOPROTOOPT (xfrm case) > - returns network_t (netlabel) > > I would still argue that the nature of the domain being carried by > the packet is still unlabeled_t as implied by the null secmark. While > I view secmark/point as specifying BOTH a flow control point and a > default domain (incidentally using the same label more because of > implementation constrainst), I view network_t as purely a flow control > point. > > But I also realize there can be equally forceful arguments > for what this > patch does. > > What does the community think? We need to resolve it one way or the > other unless the above differences in behavior are desired or somehow > accounted for in policy and apps. > > > + > > + err = avc_has_perm(ext_sid, > > + loc_sid, > > + SECCLASS_PACKET, > > + PACKET__FLOW_IN, > > + NULL); > > + if (err) > > + goto out; > > > > - /* See if NetLabel can flow in thru the current secmark here */ > > + if (ext_sid) > > + skb->secmark = ext_sid; > > > > out: > > return err ? 0 : 1; > > > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v4 1/2] NetLabel: secid reconciliation support
> @@ -3714,19 +3714,34 @@ static int selinux_skb_flow_in(struct sk > if (skb->dev == &loopback_dev) > return 1; > > + if (skb->secmark) > + loc_sid = skb->secmark; > + else > + loc_sid = SECINITSID_NETMSG; > + > err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); > BUG_ON(err); > - > - err = avc_has_perm(xfrm_sid, skb->secmark? : SECINITSID_NETMSG, > - SECCLASS_PACKET, > - PACKET__FLOW_IN, NULL); > + err = selinux_netlbl_skb_sid(skb, > + xfrm_sid ? xfrm_sid : loc_sid, > + &nlbl_sid); > if (err) > goto out; > > - if (xfrm_sid) > - skb->secmark = xfrm_sid; > + if (nlbl_sid) > + ext_sid = nlbl_sid; > + else > + ext_sid = xfrm_sid; There's a problem here in that it would require 2 different policies depending on whether one is using netlabel or xfrm. Specifically, in the absence of matching iptables contexts (secmark), the skb here will get: - 0 (xfrm case) - network_t (netlabel) This has implications for getpeercon() where it would - fail with ENOPROTOOPT (xfrm case) - returns network_t (netlabel) I would still argue that the nature of the domain being carried by the packet is still unlabeled_t as implied by the null secmark. While I view secmark/point as specifying BOTH a flow control point and a default domain (incidentally using the same label more because of implementation constrainst), I view network_t as purely a flow control point. But I also realize there can be equally forceful arguments for what this patch does. What does the community think? We need to resolve it one way or the other unless the above differences in behavior are desired or somehow accounted for in policy and apps. > + > + err = avc_has_perm(ext_sid, > +loc_sid, > +SECCLASS_PACKET, > +PACKET__FLOW_IN, > +NULL); > + if (err) > + goto out; > > - /* See if NetLabel can flow in thru the current secmark here */ > + if (ext_sid) > + skb->secmark = ext_sid; > > out: > return err ? 0 : 1; > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/1] secid reconcialiation: Replace unlabeled_t with t he network_t
> > Considering the above change, I wonder if it would also > make sense to > > update the secmark to SECINITSID_UNLABELED in the abscence of any > > external labeling (labeled IPsec or NetLabel)? > > > > Ungh, my apologies ... I meant to say "SECINITSID_NETMSG" *not* > "SECINITSID_UNLABELED". In the xfrm/NetLabel/semark case, you have configured (domain) labels that are meant to be carried by the skb. Whereas that's not the case with network_t. So, just a flow_in check was in order here. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] Fix for IPsec leakage with SELinux enabled - V.02
Evegeniy, Please start with my patch which should actually address the issue you were originally running into. I doubt that you were running into the kind of errors that James' patch (which will need to be modified to not treat -EACCES as an error to be propagated up the chain) would handle. Thanks, venkat > -Original Message- > From: James Morris [mailto:[EMAIL PROTECTED] > Sent: Wednesday, October 04, 2006 8:00 AM > To: Evgeniy Polyakov > Cc: David S. Miller; Herbert Xu; netdev@vger.kernel.org; Stephen > Smalley; Venkat Yekkirala; Paul Moore; Daniel J Walsh > Subject: Re: [PATCH] Fix for IPsec leakage with SELinux enabled - V.02 > > > On Wed, 4 Oct 2006, Evgeniy Polyakov wrote: > > > Linux kano 2.6.18 #5 SMP Mon Oct 2 18:44:30 MSD 2006 i686 > i686 i386 GNU/Linux > > [EMAIL PROTECTED] ~]# rpm -q selinux-policy-targeted > > selinux-policy-targeted-2.3.17-2 > > > > I get only this messages in audit.log when remote racoon tries to > > connect to system with selinux enabled in enforcing mode: > > > > I think the policy has just not been written for racoon, and > it's being > denied by deault (cd'd Dan Walsh). > > > type=AVC msg=audit(1159938297.845:625): avc: denied { > polmatch } for > > scontext=system_u:object_r:unlabeled_t:s0 > > tcontext=root:system_r:unconfined_t:s0-s0:c0.c255 tclass=association > > type=AVC msg=audit(1159938297.845:626): avc: denied { > polmatch } for > > scontext=system_u:object_r:unlabeled_t:s0 > > tcontext=system_u:object_r:unlabeled_t:s0 tclass=association > > type=AVC msg=audit(1159938307.837:627): avc: denied { > polmatch } for > > scontext=system_u:object_r:unlabeled_t:s0 > > tcontext=system_u:object_r:unlabeled_t:s0 tclass=association > > type=AVC msg=audit(1159938317.838:628): avc: denied { > polmatch } for > > scontext=system_u:object_r:unlabeled_t:s0 > > tcontext=system_u:object_r:unlabeled_t:s0 tclass=association > > type=AVC msg=audit(1159938327.839:629): avc: denied { > polmatch } for > > scontext=system_u:object_r:unlabeled_t:s0 > > tcontext=system_u:object_r:unlabeled_t:s0 tclass=association > > > > It is with your patch applied. > > Should I try Venkat's or it is unrelated problem? > > > > > -- > > > James Morris > > > <[EMAIL PROTECTED]> > > > > > > -- > James Morris > <[EMAIL PROTECTED]> > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1] secid reconcialiation: Replace unlabeled_t with the network_t
The following replaces unlabeled_t with network_t for better characterization of the flow out/in checks in SELinux, as well as to allow for mls packets to flow out/in from the network since network_t would allow the full range of MLS labels, as opposed to the unlabeled init sid that only allows system-hi. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- This is an incremental patch the secid-reconcilation v4 patchset. --- net-2.6.sid3/security/selinux/hooks.c 2006-10-01 15:43:12.0 -0500 +++ net-2.6/security/selinux/hooks.c2006-10-03 16:43:21.0 -0500 @@ -3703,7 +3703,8 @@ static int selinux_skb_flow_in(struct sk err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); BUG_ON(err); - err = avc_has_perm(xfrm_sid, skb->secmark, SECCLASS_PACKET, + err = avc_has_perm(xfrm_sid, skb->secmark? : SECINITSID_NETMSG, + SECCLASS_PACKET, PACKET__FLOW_IN, NULL); if (err) goto out; @@ -3900,7 +3901,7 @@ static unsigned int selinux_ip_postroute skb->secmark = sksec->sid; } } - err = avc_has_perm(skb->secmark, SECINITSID_UNLABELED, + err = avc_has_perm(skb->secmark, SECINITSID_NETMSG, SECCLASS_PACKET, PACKET__FLOW_OUT, &ad); } out: - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH v2 1/1] NetLabel: secid reconciliation support
> > If this selinux_netlbl_skb_sid() call can fail for any > reason other than > > a kernel bug, then this needs to goto out instead of using > BUG_ON. For > > example, if the function can fail due to temporary memory pressure > > leading to a failed allocation, then you want to simply > drop the packet, > > not panic the kernel. > > That's fine - see the discussion Venkat and I had earlier. > I'll change > it to jump to "out". Just to clarify, my comments earlier about BUG_ON were in relation to selinux_xfrm_decode_session which can only fail as a result of a bug or kernel corruption. For "other" errors, a jump out indeed seems proper, like you are already planning to do. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] Fix for IPsec leakage with SELinux enabled
> > This is indeed the "designed" and expected (for me) behavior. > > This is a security hole. SELinux denies all access by > default, so the > default behavior of this code is to allow all traffic to bypass IPsec. > > You should not need to add a rule to 'allow' increased security. You are right. Currently working on a patch (should be out tonight/tomorrow). > This needs to be handled within SELinux as far as possible, > and errors > will generally need to be propagated back to the callers, as Agreed here as well. I have yet to review your patch in depth, but it definitely makes sense to do what you say here. Thanks. > we don't know > what other LSMs might do, and errors unrelated to access > control can be > returned. > > > - James > -- > James Morris > <[EMAIL PROTECTED]> > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/9] secid reconciliation-v04: Enforcement for SELinux
> My immediate concern is not really what selinux_xfrm_decode_session() > returns, but how to handle it, or rather errors in general, in > selinux_skb_flow_in(). I'm in the process of creating a patch to add > the missing NetLabel support to the secid patches and I am > wondering if > I should BUG_ON() for an error condition or simply jump to "out". > Jumping seems a bit cleaner to me, although perhaps harder to > debug, so > I was just wondering what the reasoning was behind the use of > BUG_ON(). It's more a "code integrity" check that I have sought to enforce via BUG_ON (meaning the function isn't expected to fail under any circumstances). Whether this is a severe enough error (possible as a result of a bug in decode_session or a corrupted kernel) that we should panic the system at that point is probably debatable. In particular I would be interested to know how similar situations are currently treated in the kernel. My recommendation would be to be consistent with the rest of the code and do a BUG_ON. As for other errors, you could jump out like the rest of the code already does (if that meets your needs that is). - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] Fix for IPsec leakage with SELinux enabled
> On Sun, 1 Oct 2006, Venkat Yekkirala wrote: > > > > The way I was seeing the problem was when connecting via > IPsec to a > > > confined service on an SELinux box (vsftpd), which did > not have the > > > appropriate SELinux policy permissions to send packets via IPsec. > > > > > > The first SYNACK would be blocked, > > > > Given that the resolver fails to find a policy here, I am trying to > > understand what exactly is blocking it (the first SYNACK) from > > proceeding without IPSec. > > You're right. My explanation there was for the case where > I'd modified > the code to propagate the SELinux denial back to > xfrm_lookup(), and not > for the original issue (sorry, it's been a long week). > > In the original case, all packets originating from a confined > domain will > bypass ipsec. During xfrm_lookup, flow_cache_lookup() returns NULL > policy: > > xfrm_lookup() > { > ... > > if (!policy) { > /* To accelerate a bit... */ > if ((dst_orig->flags & DST_NOXFRM) || > !xfrm_policy_count[XFRM_POLICY_OUT]) > return 0; > > policy = flow_cache_lookup(fl, dst_orig->ops->family, >dir, xfrm_policy_lookup); > } > > if (!policy) > return 0; <- bad > ... > } > > The call chain is: > > flow_cache_lookup() > xfrm_policy_lookup() >xfrm_policy_lookup_bytype() > xfrm_policy_match() { >xfrm_selector_match => returns true, then > security_xfrm_policy_lookup => returns -EACCESS > } > > then > > xfrm_policy_match() => returns 0 > xfrm_policy_lookup_bytype => returns 0 > xfrm_policy_lookup() => sets obj to NULL w/ void return > flow_cache_lookup() => returns NULL > xfrm_lookup => returns 0 > > and the packet proceeds without error and with no transform > applied (i.e. > leaked as cleartext). This is indeed the "designed" and expected (for me) behavior. But I am beginning to see where this is perhaps NOT in line with the user expectation when the users have an IPSec policy rule that does NOT use labels. IOW, if they have their policy like (NO LABELS): spdadd 192.168.4.79 192.168.4.78 any -P out ipsec esp/transport//require; spdadd 192.168.4.78 192.168.4.79 any -P in ipsec esp/transport//require; currently, EACH flow needing to use this rule MUST have SELinux policy "polmatch"ing the flow context (ftpd_t) to unlabeled_t (the implied in the absence of an explicit context on the IPSec policy rule) or the traffic would flow in clear text ("leaks" in user perception). What I propose we do is to do the polmatch check ONLY when there's an explicit label associated with the spd rule. Does this sound reasonable and correct in the larger SELinux context? In cases where there's an explicit label on an spd rule like: spdadd 192.168.4.79 192.168.4.78 any -ctx 1 1 "system_u:object_r:labeled_ipsec_t:s2-s4" -P out ipsec esp/transport//require; spdadd 192.168.4.78 192.168.4.79 any -ctx 1 1 "system_u:object_r:labeled_ipsec_t:s2-s4" -P in ipsec esp/transport//require; then the current behavior (prior to this proposed patch) would be the desired behavior, i.e., a polmatch denial in the SELinux module just means that the flow isn't expected to undergo IPSec xfrms. IOW, there's no need to propagate -EACCES all the way back up. We could still propagate errors other than -EACCES if we like. > > The first component of the fix is to propagate errors back up > to callers > via the flow cache resolver, and handle them correctly, as > this is where > we can experience security module denials. This will cause problems with the case where we may have multiple "labeled" spd rules, each of which should be attempted to be polmatched against before letting the flow out in clear text, as would be expected by the user as well. > > The second component is to then ensure that, on failure, -EACCES in this case is perceived as a failure since the designed behavior doesn't seem to be in line with the user expectation. Otherwise, with the above proposed change to the design, there won't be a polmatch check in this case and hence no failure. It's probably still a good idea to propagate non-EACCES failures back up the chain though. > we > kill the new > flow cache entry created during lookup, so that it is not > subsequently > looked up with a null policy (i.e. allowing future packets to > leak) and to > force the security hook to be called again in case the policy > has changed. > > Hope that clarifies. > > > - James > -- > James Morris > <[EMAIL PROTECTED]> > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> >>In the case above I am concerned about the situation where the > >>skb->secmark == 0 and there is a IPv4 option (i.e. it is NetLabel > >>labeled) on the packet. > > It's unfortunate that you cut out the code in your reply. It's even more unfortunate that you should say this. The proper thing to do is to simply repaste portions that you feel like you need to. Remember, we aren't opponents standing for election this season. :) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/9] secid reconciliation-v04: Invoke LSM hook for outbound traffic
Invoke the skb_flow_out LSM hook for outbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- net/netfilter/xt_CONNSECMARK.c | 72 --- net/netfilter/xt_SECMARK.c | 45 ++- 2 files changed, 100 insertions(+), 17 deletions(-) diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 4673862..cca4a0c 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -17,6 +17,8 @@ */ #include #include +#include +#include #include #include #include @@ -29,38 +31,78 @@ MODULE_DESCRIPTION("ip[6]tables CONNSECM MODULE_ALIAS("ipt_CONNSECMARK"); MODULE_ALIAS("ip6t_CONNSECMARK"); +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || +hooknum == NF_IP_LOCAL_OUT || +hooknum == NF_IP_FORWARD)) || + (family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || +hooknum == NF_IP6_LOCAL_OUT || +hooknum == NF_IP6_FORWARD))) + return 1; + else + return 0; +} + /* * If the packet has a security mark and the connection does not, copy * the security mark from the packet to the connection. */ -static void secmark_save(struct sk_buff *skb) +static void secmark_save(struct sk_buff *skb, unsigned int hooknum) { if (skb->secmark) { u32 *connsecmark; enum ip_conntrack_info ctinfo; connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && !*connsecmark) + if (connsecmark) if (*connsecmark != skb->secmark) *connsecmark = skb->secmark; } } /* - * If packet has no security mark, and the connection does, restore the - * security mark from the connection to the packet. + * On the inbound, restore the security mark from the connection to the packet. + * On the outbound, filter based on the current secmark. */ -static void secmark_restore(struct sk_buff *skb) +static unsigned int secmark_restore(struct sk_buff *skb, unsigned int hooknum, + const struct net_device *in, unsigned short family) { - if (!skb->secmark) { - u32 *connsecmark; - enum ip_conntrack_info ctinfo; - - connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && *connsecmark) - if (skb->secmark != *connsecmark) - skb->secmark = *connsecmark; + u32 *psecmark; + enum ip_conntrack_info ctinfo; + + psecmark = nf_ct_get_secmark(skb, &ctinfo); + + if (psecmark && *psecmark) { + + /* Set secmark on inbound and filter it on outbound */ + if (outbound(family, hooknum)) { + int err; + + err = security_skb_flow_out(skb, *psecmark); + if (!err) + return NF_DROP; + } else + /* +* inbound: +* loopback traffic should already be labeled +* and any filtering on outbound should suffice +*/ + if (in == &loopback_dev) + goto out; + + /* +* inbound or done with outbound check or no LSM hook +* for outbound +*/ + if (skb->secmark != *psecmark) + skb->secmark = *psecmark; } + +out: + return XT_CONTINUE; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -73,11 +115,11 @@ static unsigned int target(struct sk_buf switch (info->mode) { case CONNSECMARK_SAVE: - secmark_save(skb); + secmark_save(skb, hooknum); break; case CONNSECMARK_RESTORE: - secmark_restore(skb); + return secmark_restore(skb, hooknum, in, target->family); break; default: diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index add7521..9ecce66 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris <[EMAIL PROTECTED]>"); @@ -28,6 +30,21 @@ #define PFX "SECMARK: " static u8 mode; +static inline int outbound(unsigned short family, unsigned int hooknum) +{ + if ((family
[PATCH 8/9] secid reconciliation-v04: Use secmark when classifying flow using skb
This beings secmark into the picture when classifying flows using an skb. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h | 10 -- include/linux/skbuff.h | 20 2 files changed, 20 insertions(+), 10 deletions(-) --- net-2.6.sid/include/linux/security.h2006-09-30 16:02:59.0 -0500 +++ net-2.6/include/linux/security.h2006-10-01 13:07:43.0 -0500 @@ -3223,12 +3223,6 @@ static inline int security_xfrm_decode_s return security_ops->xfrm_decode_session(skb, secid, 1); } -static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) -{ - int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0); - - BUG_ON(rc); -} #else /* CONFIG_SECURITY_NETWORK_XFRM */ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) { @@ -3297,10 +3291,6 @@ static inline int security_xfrm_decode_s return 0; } -static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl) -{ -} - #endif /* CONFIG_SECURITY_NETWORK_XFRM */ #ifdef CONFIG_KEYS --- net-2.6.sid/include/linux/skbuff.h 2006-09-27 18:20:54.0 -0500 +++ net-2.6/include/linux/skbuff.h 2006-10-01 13:17:22.0 -0500 @@ -30,6 +30,7 @@ #include #include #include +#include #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8)*/ @@ -1514,6 +1515,20 @@ static inline void security_flow_classif skb->secmark = fl->secid; } +static inline void security_skb_classify_flow(struct sk_buff *skb, + struct flowi *fl) +{ + /* +* We need to check for xfrm label here since secid reconciliation +* may or may not have happened yet and we want the +* flow to use the best available label. +*/ + int rc = security_xfrm_decode_session(skb, &fl->secid); + + if (rc || !fl->secid) + fl->secid = skb->secmark; +} + #else static inline void security_skb_classify_skb(struct sk_buff *from, @@ -1526,6 +1541,11 @@ static inline void security_flow_classif { } +static inline void security_skb_classify_flow(struct sk_buff *skb, + struct flowi *fl) +{ +} + #endif /* CONFIG_SECURITY_NETWORK */ #endif /* __KERNEL__ */ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] secid reconciliation-v04: Label locally generated IPv6 traffic
This labels the skb(s) for locally generated IPv6 traffic. This will be used in pertinent flow control checks on the outbound later in the LSM hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/skbuff.h | 29 + net/ipv6/ip6_output.c|5 + net/ipv6/netfilter/ip6t_REJECT.c |2 ++ 3 files changed, 36 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 85577a4..18967f2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -29,6 +29,7 @@ #include #include #include #include +#include #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8)*/ @@ -1499,5 +1500,33 @@ static inline int skb_is_gso(const struc return skb_shinfo(skb)->gso_size; } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ + skb->secmark = from->secmark; +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ + skb->secmark = fl->secid; +} + +#else + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6671691..6648eb3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -170,6 +170,8 @@ int ip6_xmit(struct sock *sk, struct sk_ int hlimit, tclass; u32 mtu; + security_flow_classify_skb(fl, skb); + if (opt) { int head_room; @@ -1150,6 +1152,9 @@ alloc_new_skb: } if (skb == NULL) goto error; + + security_flow_classify_skb(fl, skb); + /* * Fill in the control structures */ diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 311eae8..0508c30 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -128,6 +128,8 @@ static void send_reset(struct sk_buff *o ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); + security_skb_classify_skb(oldskb, nskb); + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); /* Truncate to length (no data) */ tcph->doff = sizeof(struct tcphdr)/4; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 9/9] secid reconciliation-v04: Track peersecid at connection establishment
This tracks the peer's secid at connection establishment time for clients, for later retrieval using SO_PEERSEC. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h | 14 ++ net/ipv4/tcp_input.c |2 ++ security/dummy.c |6 ++ security/selinux/hooks.c |9 + 4 files changed, 31 insertions(+) --- net-2.6.sid2/include/linux/security.h 2006-10-01 13:07:43.0 -0500 +++ net-2.6/include/linux/security.h2006-10-01 15:18:23.0 -0500 @@ -826,6 +826,8 @@ struct request_sock; * Sets the openreq's sid to socket's sid with MLS portion taken from peer sid. * @inet_csk_clone: * Sets the new child socket's sid to the openreq sid. + * @inet_conn_established: + * Sets the connection's peersid to the secmark on skb. * @req_classify_flow: * Sets the flow's sid to the openreq sid. * @skb_flow_in: @@ -1380,6 +1382,7 @@ struct security_operations { int (*inet_conn_request)(struct sock *sk, struct sk_buff *skb, struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); + void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); int (*skb_flow_in)(struct sk_buff *skb, unsigned short family); int (*skb_flow_out)(struct sk_buff *skb, u32 nf_secid); @@ -2985,6 +2988,12 @@ static inline void security_inet_csk_clo { security_ops->inet_csk_clone(newsk, req); } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ + security_ops->inet_conn_established(sk, skb); +} #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct socket * sock, struct socket * other, @@ -3146,6 +3155,11 @@ static inline void security_inet_csk_clo const struct request_sock *req) { } + +static inline void security_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM --- net-2.6.sid2/net/ipv4/tcp_input.c 2006-10-01 15:09:12.0 -0500 +++ net-2.6/net/ipv4/tcp_input.c2006-10-01 15:17:39.0 -0500 @@ -4230,6 +4230,8 @@ static int tcp_rcv_synsent_state_process mb(); tcp_set_state(sk, TCP_ESTABLISHED); + security_inet_conn_established(sk, skb); + /* Make sure socket is routed, for correct metrics. */ icsk->icsk_af_ops->rebuild_header(sk); --- net-2.6.sid2/security/dummy.c 2006-09-27 13:02:12.0 -0500 +++ net-2.6/security/dummy.c2006-10-01 15:45:26.0 -0500 @@ -828,6 +828,11 @@ static inline void dummy_inet_csk_clone( { } +static inline void dummy_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ +} + static inline void dummy_req_classify_flow(const struct request_sock *req, struct flowi *fl) { @@ -1118,6 +1123,7 @@ void security_fixup_ops (struct security set_to_dummy_if_null(ops, sock_graft); set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); + set_to_dummy_if_null(ops, inet_conn_established); set_to_dummy_if_null(ops, req_classify_flow); set_to_dummy_if_null(ops, skb_flow_in); set_to_dummy_if_null(ops, skb_flow_out); --- net-2.6.sid2/security/selinux/hooks.c 2006-10-01 12:34:28.0 -0500 +++ net-2.6/security/selinux/hooks.c2006-10-01 15:43:12.0 -0500 @@ -3669,6 +3669,14 @@ static void selinux_inet_csk_clone(struc selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); } +static void selinux_inet_conn_established(struct sock *sk, + struct sk_buff *skb) +{ + struct sk_security_struct *sksec = sk->sk_security; + + sksec->peer_sid = skb->secmark; +} + static void selinux_req_classify_flow(const struct request_sock *req, struct flowi *fl) { @@ -4800,6 +4808,7 @@ static struct security_operations selinu .sock_graft = selinux_sock_graft, .inet_conn_request =selinux_inet_conn_request, .inet_csk_clone = selinux_inet_csk_clone, + .inet_conn_established =selinux_inet_conn_established, .req_classify_flow =selinux_req_classify_flow, .skb_flow_in = selinux_skb_flow_in, .skb_flow_out = selinux_skb_flow_out, - To unsubscribe from this list: send the line "unsubscribe netdev" i
[PATCH 7/9] secid reconciliation-v04: Enforcement for SELinux
This defines SELinux enforcement of the 2 new LSM hooks as well as related changes elsewhere in the SELinux code. This also now keeps track of the peersid thru the establishment of a connection on the server (tracking peersid on the client is covered later in this patch set). Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/hooks.c| 148 +++--- security/selinux/include/xfrm.h | 11 +- security/selinux/xfrm.c | 66 + 3 files changed, 150 insertions(+), 75 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5a66c4c..fc65cc7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3449,8 +3449,12 @@ static int selinux_sock_rcv_skb_compat(s err = avc_has_perm(sock_sid, port_sid, sock_class, recv_perm, ad); + if (err) + goto out; } + err = selinux_xfrm_sock_rcv_skb(sock_sid, skb, ad); + out: return err; } @@ -3489,10 +3493,6 @@ static int selinux_socket_sock_rcv_skb(s goto out; err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad); - if (err) - goto out; - - err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); out: return err; } @@ -3505,7 +3505,7 @@ static int selinux_socket_getpeersec_str u32 scontext_len; struct sk_security_struct *ssec; struct inode_security_struct *isec; - u32 peer_sid = 0; + u32 peer_sid; isec = SOCK_INODE(sock)->i_security; @@ -3516,8 +3516,10 @@ static int selinux_socket_getpeersec_str } else if (isec->sclass == SECCLASS_TCP_SOCKET) { peer_sid = selinux_netlbl_socket_getpeersec_stream(sock); - if (peer_sid == SECSID_NULL) - peer_sid = selinux_socket_getpeer_stream(sock->sk); + if (peer_sid == SECSID_NULL) { + ssec = sock->sk->sk_security; + peer_sid = ssec->peer_sid; + } if (peer_sid == SECSID_NULL) { err = -ENOPROTOOPT; goto out; @@ -3550,7 +3552,8 @@ out: return err; } -static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static int selinux_socket_getpeersec_dgram(struct socket *sock, + struct sk_buff *skb, u32 *secid) { u32 peer_secid = SECSID_NULL; int err = 0; @@ -3559,8 +3562,12 @@ static int selinux_socket_getpeersec_dgr selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); else if (skb) { peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb); - if (peer_secid == SECSID_NULL) - peer_secid = selinux_socket_getpeer_dgram(skb); + if (peer_secid == SECSID_NULL) { + if (selinux_compat_net) + peer_secid = selinux_socket_getpeer_dgram(skb); + else + peer_secid = skb->secmark; + } } if (peer_secid == SECSID_NULL) @@ -3626,19 +3633,24 @@ static int selinux_inet_conn_request(str return 0; } - err = selinux_xfrm_decode_session(skb, &peersid, 0); - BUG_ON(err); + if (selinux_compat_net) { + err = selinux_xfrm_decode_session(skb, &peersid, 0); + BUG_ON(err); - if (peersid == SECSID_NULL) { - req->secid = sksec->sid; - return 0; - } + if (peersid == SECSID_NULL) { + req->secid = sksec->sid; + req->peer_secid = 0; + return 0; + } + } else + peersid = skb->secmark; err = security_sid_mls_copy(sksec->sid, peersid, &newsid); if (err) return err; req->secid = newsid; + req->peer_secid = peersid; return 0; } @@ -3648,6 +3660,7 @@ static void selinux_inet_csk_clone(struc struct sk_security_struct *newsksec = newsk->sk_security; newsksec->sid = req->secid; + newsksec->peer_sid = req->peer_secid; /* NOTE: Ideally, we should also get the isec->sid for the new socket in sync, but we don't have the isec available yet. So we will wait until sock_graft to do it, by which @@ -3662,6 +3675,66 @@ static void selinux_req_classify_flow(co fl->secid = req->secid; } +static int selinux_skb_flow_in(struct sk_buff *skb, unsigned short family) +{ + u32 xfrm_sid; + int err; + + if (selinux_compat_net) + return 1; + + /* +* loopback
[PATCH 1/9] secid reconciliation-v04
This patchset helps with leveraging secmark in defining fine-grained security check points with support for a. a default place holder domain defined using secmark for each of the check points and b. flow control and reconciliation of domains entering/leaving the system. The reconciliation steps for SELinux are explained in the Labeled Networking document at: http://marc.theaimsgroup.com/?l=linux-netdev&m=115136637800361&w=2 Also please refer to the discussion at: http://marc.theaimsgroup.com/?l=selinux&m=115885031311565&w=2 The following are the identifiers handled here: 1. secmark on the skb 2. xfrm security identifier associated with the skb if it used any xfrms, a zero secid otherwise. The following features are included: - Retain secmark (from the originating socket/flow) on loopback traffic; this traffic is now flow controlled on the outbound only. - When multiple iptables labeling rules are present (e.g.: both on PREROUTING and INPUT) INBOUND: The label in the last rule will prevail. OUTBOUND: secmark (from the originating socket) is flow-controlled against the label on the first rule, and, if it passes, the label on the first rule overrides the secmark (from the originating socket). This secmark is flow controlled against labels on the subsequent rules, each time, overridden by those labels. - Forwarded packets: The FORWARD chain is treated as an outbound chain for flow control purposes. e.g: label with PREROUTING and flow-control with FORWARD or POSTROUTING. - SELinux postroute_last hook: unfortunately, the secmark Vs. UNLABELED SID check will be done for ALL traffic (couldn't figure out a way to except traffic already processed by (CONN)SECMARK outbound rules). This patch: Add new flask definitions to SELinux Adds a new avperm "flow_in" to arbitrate among the identifiers on the inbound (input/forward). Also adds a new avperm "flow_out" to enable flow control checks on the outbound (output/forward), addressed in this patch as well. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/include/av_perm_to_string.h |2 ++ security/selinux/include/av_permissions.h|2 ++ 2 files changed, 4 insertions(+) diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 09fc8a2..1e65d28 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h @@ -245,6 +245,8 @@ S_(SECCLASS_PACKET, PACKET__SEND, "send") S_(SECCLASS_PACKET, PACKET__RECV, "recv") S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") + S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in") + S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out") S_(SECCLASS_KEY, KEY__VIEW, "view") S_(SECCLASS_KEY, KEY__READ, "read") S_(SECCLASS_KEY, KEY__WRITE, "write") diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 81f4f52..2faf3d8 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -962,6 +962,8 @@ #define APPLETALK_SOCKET__NAME_BIND #define PACKET__SEND 0x0001UL #define PACKET__RECV 0x0002UL #define PACKET__RELABELTO 0x0004UL +#define PACKET__FLOW_IN 0x0008UL +#define PACKET__FLOW_OUT 0x0010UL #define KEY__VIEW 0x0001UL #define KEY__READ 0x0002UL - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] secid reconciliation-v04: Label locally generated IPv4 traffic
This labels the skb(s) for locally generated IPv4 traffic. This will be used in pertinent flow control checks on the outbound later in the LSM hook. This is not as pretty as it is for IPv6, but what to do? Note that skb(s) that derive the secmark from the originating socket do so in the outbound hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/ip.h | 31 +++ include/net/request_sock.h | 18 ++ net/dccp/ipv4.c|5 + net/ipv4/icmp.c|4 net/ipv4/ip_output.c |6 ++ net/ipv4/tcp_ipv4.c|1 + 6 files changed, 65 insertions(+) diff --git a/include/net/ip.h b/include/net/ip.h index 98f9084..40ac276 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -48,6 +48,9 @@ struct ipcm_cookie u32 addr; int oif; struct ip_options *opt; +#ifdef CONFIG_SECURITY_NETWORK + u32 secid; +#endif /* CONFIG_SECURITY_NETWORK */ }; #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) @@ -383,4 +386,32 @@ #endif extern struct ctl_table ipv4_table[]; +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ + ipc->secid = skb->secmark; +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ + skb->secmark = ipc->secid; +} + +#else + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _IP_H */ diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 8e165ca..6d6da9c 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -54,6 +54,7 @@ struct request_sock { struct request_sock_ops *rsk_ops; struct sock *sk; u32 secid; + u32 peer_secid; }; static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) @@ -259,4 +260,21 @@ static inline void reqsk_queue_hash_req( write_unlock(&queue->syn_wait_lock); } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ + skb->secmark = req->secid; +} + +#else + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _REQUEST_SOCK_H */ diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 66be29b..57ba542 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -230,6 +230,8 @@ static void dccp_v4_reqsk_send_ack(struc dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); + security_req_classify_skb(req, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, @@ -261,6 +263,7 @@ static int dccp_v4_send_response(struct dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr, ireq->rmt_addr); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + security_req_classify_skb(req, skb); err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt); @@ -743,6 +746,8 @@ static void dccp_v4_ctl_send_reset(struc dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, rxskb->nh.iph->daddr); + security_skb_classify_skb(rxskb, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c2ad07e..956791a 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -389,6 +389,8 @@ static void icmp_reply(struct icmp_bxm * if (icmp_xmit_lock()) return; + security_skb_classify_ipcm(skb, &ipc); + icmp_param->data.icmph.checksum = 0; icmp_out_count(icmp_param->data.icmph.type);
[PATCH 3/9] secid reconciliation-v04: Invoke LSM hook for inbound traffic
Invoke the skb_flow_in LSM hook for inbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/xfrm.h | 45 +-- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 11e0b1d..8f9c184 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -675,22 +675,18 @@ extern int __xfrm_policy_check(struct so static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { - if (sk && sk->sk_policy[XFRM_POLICY_IN]) - return __xfrm_policy_check(sk, dir, skb, family); - - return (!xfrm_policy_count[dir] && !skb->sp) || - (skb->dst->flags & DST_NOPOLICY) || - __xfrm_policy_check(sk, dir, skb, family); -} - -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET); -} + int ret; -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET6); + if (sk && sk->sk_policy[XFRM_POLICY_IN]) + ret = __xfrm_policy_check(sk, dir, skb, family); + else + ret = (!xfrm_policy_count[dir] && !skb->sp) || + (skb->dst->flags & DST_NOPOLICY) || + __xfrm_policy_check(sk, dir, skb, family); + + if (ret) + ret = security_skb_flow_in(skb, family); + return ret; } extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family); @@ -742,19 +738,22 @@ static inline void xfrm_sk_free_policy(s static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} +static inline int xfrm_policy_check(struct sock *sk, int dir, + struct sk_buff *skb, unsigned short family) +{ + return security_skb_flow_in(skb, family); +} +#endif + static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) { - return 1; + return xfrm_policy_check(sk, dir, skb, AF_INET); } -static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) + +static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) { - return 1; + return xfrm_policy_check(sk, dir, skb, AF_INET6); } -#endif static __inline__ xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] secid reconciliation-v04: Add LSM hooks
Add skb_policy_check and skb_netfilter_check hooks to LSM to enable reconciliation of the various security identifiers as well as enforce flow control on inbound (PREROUTING/INPUT) and outbound (OUTPUT/FORWARD/POSTROUTING) traffic. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h | 41 - security/dummy.c | 13 +++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/linux/security.h b/include/linux/security.h index 9f56fb8..84b826b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -828,6 +828,15 @@ #ifdef CONFIG_SECURITY * Sets the new child socket's sid to the openreq sid. * @req_classify_flow: * Sets the flow's sid to the openreq sid. + * @skb_flow_in: + * Checks to see if security policy would allow skb into the system + * while also reconciling the xfrm secid, cipso, etc, if any, and + * relabeling the skb with the reconciled secid. + * Returns 1 if skb allowed into system, 0 otherwise. + * @skb_flow_out: + * Checks to see if security policy would allow skb to go out of system. + * Returns 1 if skb allowed out of system, 0 if not, and -ENOENT if there's + * no hook defined. * * Security hooks for XFRM operations. * @@ -1372,6 +1381,8 @@ #ifdef CONFIG_SECURITY_NETWORK struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); + int (*skb_flow_in)(struct sk_buff *skb, unsigned short family); + int (*skb_flow_out)(struct sk_buff *skb, u32 nf_secid); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -2946,6 +2957,18 @@ static inline void security_req_classify security_ops->req_classify_flow(req, fl); } +static inline int security_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return security_ops->skb_flow_in(skb, family); +} + +static inline int security_skb_flow_out(struct sk_buff *skb, + u32 nf_secid) +{ + return security_ops->skb_flow_out(skb, nf_secid); +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { security_ops->sock_graft(sk, parent); @@ -3097,6 +3120,18 @@ static inline void security_req_classify { } +static inline int security_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return 1; +} + +static inline int security_skb_flow_out(struct sk_buff *skb, + u32 nf_secid) +{ + return -ENOENT; +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { } @@ -3150,7 +3185,11 @@ static inline int security_xfrm_state_al { if (!polsec) return 0; - return security_ops->xfrm_state_alloc_security(x, NULL, polsec, secid); + /* +* No need to pass polsec along since we want the context to be +* taken from secid which is usually from the sock. +*/ + return security_ops->xfrm_state_alloc_security(x, NULL, NULL, secid); } static inline int security_xfrm_state_delete(struct xfrm_state *x) diff --git a/security/dummy.c b/security/dummy.c index aeee705..921be56 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -832,6 +832,17 @@ static inline void dummy_req_classify_fl struct flowi *fl) { } + +static inline int dummy_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return -ENOENT; +} + +static inline int dummy_skb_flow_out(struct sk_buff *skb, u32 nf_secid) +{ + return -ENOENT; +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1108,6 +1119,8 @@ #ifdef CONFIG_SECURITY_NETWORK set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); set_to_dummy_if_null(ops, req_classify_flow); + set_to_dummy_if_null(ops, skb_flow_in); + set_to_dummy_if_null(ops, skb_flow_out); #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM set_to_dummy_if_null(ops, xfrm_policy_alloc_security); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/9] secid reconciliation-v04: Repost patchset with updates
This patchset is relative to davem's net-2.6.git The following are the changes included in this patchset since the previous post: - Create IPSec SAs to be acquired with the creating sock's context as opposed to that of the matching SPD rule, resulting in a simpler SPD as well as policy. - Set peer_sid on tcp sockets to the reconciled secmark so trusted applications can retrieve and service the data at the appropriate context. Also return secmark when security is queried for a UDP packet. - Fix minor things from James Morris' review. Paul, please spin a new patch to bring NetLabel into the reconciliation path as well as to address any NetLabel changes needed in regard to the above. Please consider for inclusion in 2.6.19. include/linux/security.h | 51 - include/linux/skbuff.h | 49 + include/net/ip.h | 31 +++ include/net/request_sock.h | 18 ++ include/net/xfrm.h | 45 ++--- net/dccp/ipv4.c |5 net/ipv4/icmp.c |4 net/ipv4/ip_output.c |6 net/ipv4/tcp_ipv4.c |1 net/ipv6/ip6_output.c|5 net/ipv6/netfilter/ip6t_REJECT.c |2 net/netfilter/xt_CONNSECMARK.c | 72 ++-- net/netfilter/xt_SECMARK.c | 45 - security/dummy.c | 13 + security/selinux/hooks.c | 148 + security/selinux/include/av_perm_to_string.h |2 security/selinux/include/av_permissions.h|2 security/selinux/include/xfrm.h | 11 - security/selinux/xfrm.c | 66 +++ 19 files changed, 450 insertions(+), 126 deletions(-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] Fix for IPsec leakage with SELinux enabled
> The way I was seeing the problem was when connecting via IPsec to a > confined service on an SELinux box (vsftpd), which did not have the > appropriate SELinux policy permissions to send packets via IPsec. > > The first SYNACK would be blocked, Given that the resolver fails to find a policy here, I am trying to understand what exactly is blocking it (the first SYNACK) from proceeding without IPSec. > because of an uncached lookup via > flow_cache_lookup(), which would fail to resolve an xfrm > policy because > the SELinux policy is checked at that point via the resolver. > > However, retransmitted SYNACKs would then find a cached flow > entry when > calling into flow_cache_lookup() with a null xfrm policy, which is > interpreted by xfrm_lookup() as the packet not having any associated > policy and similarly to the first case, allowing it to pass without > transformation. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> It seems more of a pain to actually > prevent their use at the same time and/or explain > strange/unnatural > behavior. > >>> > >>>Agreed, the solution that we agreed upon is much easier to > implement and > >>>explain than a lot of the alternatives. > >> > >>Ok, can you please explain it further? > >> > >>i.e. show me what the policy looks like, exactly what the > user is trying > >>to achieve, and explain what happens to each packet exactly > in terms of > >>labeling on the input and output paths. > > > > Also, why can't this be done just with xfrm labeling? > > I believe the issue Venkat and I were discussing was how to handle the > case of multiple external labeling protocols, i.e. what to do > if we get > a packet through labeled SA which has a CIPSO option. As I've said > before, I don't believe this is something we will see much in practice > but I think we need to decide what to do: handle it somehow > or just punt > on the problem and drop it. Several people with experience with > external labeling have commented on how supporting both external > labeling protocols would be a good idea so Venkat and I are trying to > come up with a solution that works. Here's the scoop on using xfrm and cipso at the same time: JUST REDUNDANT I was only paying attention to the inbound side when I was saying a ranged SA could be used in conjunction with fine-grained cipso labeling. In actuality, this isn't possible because of the change we are instituting for SA selection to be based on the context of the sock (specifically, the sock's MLS range must "equal" the range on the SA, and cipso at this point would be representing this same range). So, if someone were to configure CIPSO along with labeled ipsec, BOTH mechanisms will be used, with BOTH labels carrying the same MLS range, and with CIPSO always overriding the SA (after a flow_in check) on the inbound. Should just be additional overhead, that's all. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> Venkat, > > With xfrm labeling, the external packets are always going to > be protocol > ESP or AH, and we can't connection track the inner protocols. So, Are you sure? This doesn't compare to what my limited testing seems to have turned up (normal netfiltering of inner protos followed by xfrms, interspersed with their own netfiltering). > external labeling when using xfrm labeling seems somewhat > superfluous, > except for the case of setting a label based on the interface > the packets > arrived on. Correct? If so, all you can realistically do > with the flow > permissions is bind the ESP/AH packets to types of interfaces > (which does > seem useful for some folk). - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/1] NetLabel: secid reconciliation support
> @@ -3672,16 +3674,20 @@ static int selinux_skb_flow_in(struct sk > if (err) > goto out; > > - if (xfrm_sid) { > - err = security_transition_sid(xfrm_sid, skb->secmark, > - > SECCLASS_PACKET, &trans_sid); > - if (err) > - goto out; > + if (xfrm_sid) > + skb->secmark = xfrm_sid; > > - skb->secmark = trans_sid; > - } > + err = selinux_netlbl_skb_sid(skb, skb->secmark, &nlbl_sid); I take it nlbl_sid here will be 0 if netlabel is NOT configured for the traffic correct? > --- net-2.6.orig/security/selinux/ss/mls.c > +++ net-2.6/security/selinux/ss/mls.c > @@ -547,7 +547,7 @@ int mls_compute_sid(struct context *scon > &rtr->target_range); > } > } > - else if (tclass == SECCLASS_PACKET) > + if (tclass == SECCLASS_PACKET) What's the purpose of getting rid of "else" above? I haven't reviewed the netlbl native changes, but the hooks.c changes seem ok to me. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> >>While I don't see any explicit mention of it in the documentation or > >>your comments, I assume we would want a flow_out check for > >>NetLabel here > >>as well? > > > > I don't believe we do. By this time, the packet is or > should already be > > carrying the CIPSO/NetLabel option which should already be > the right one > > (derived from the socket or flow as appropriate), but you > would want to > > audit the code to make sure. IOW, the label option in the > IP header should > > already be reflecting the secmark on the skb. But again, > you may want to > > audit the code to make sure. > > In the case above I am concerned about the situation where the > skb->secmark == 0 and there is a IPv4 option (i.e. it is NetLabel > labeled) on the packet. Where we initialize the secmark should be immaterial from the NetLabel point of view. The kernel mechanisms should assure that the IP option reflects the MLS portion (or a label in the SA range) elsewhere. In any case, a flow_out check doesn't make sense since the IP option and the secmark are (should be) mirroring each other and there's in actuality no "flow out" happening; they are just 2 representation of the SAME label. Your suggestion as to adjusting the secmark per the IP option might be fraught with danger since, in certain cases, I believe, you just return the incoming options in the outgoing packet (timewait, openreq, etc.?), and there's no assurance that that's a valid enough option that you can retrieve a sid with it, correct? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> > +static int selinux_skb_flow_in(struct sk_buff *skb, > unsigned short family) > > +{ > > + u32 xfrm_sid, trans_sid; > > + int err; > > + > > + if (selinux_compat_net) > > + return 1; > > + > > + /* xfrm/cipso inapplicable for loopback traffic */ > > + if (skb->dev == &loopback_dev) > > + return 1; > > Just to clarify (I believe this is the case from your remarks > as well as > the code, but better safe than sorry) the secmark for loopback traffic > is set by the originating socket, yes? That's correct. > > Beware: a bit of a nit follows :) > > While I understand that NetLabel currently only supports > CIPSO, it is a > framework that can support multiple labeling procotols (i.e. RIPSO > support is planned). Please change the comment from cipso/CIPSO to > netlabel/NetLabel so it is consistent with the rest of the code which > makes use of NetLabel. Sure. > > > + err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); > > + BUG_ON(err); > > + > > + err = avc_has_perm(xfrm_sid, skb->secmark, SECCLASS_PACKET, > > + PACKET__FLOW_IN, NULL); > > + if (err) > > + goto out; > > + > > + if (xfrm_sid) { > > + err = security_transition_sid(xfrm_sid, skb->secmark, > > + > SECCLASS_PACKET, &trans_sid); > > + if (err) > > + goto out; > > + > > + skb->secmark = trans_sid; > > + } > > + /* See if CIPSO can flow in thru the current secmark here */ > > Same nit applies about the use of "CIPSO" vs "NetLabel". Sure. > > > +out: > > + return err ? 0 : 1; > > +}; > > + > > +static int selinux_skb_flow_out(struct sk_buff *skb, u32 nf_secid) > > +{ > > + u32 trans_sid; > > + int err; > > + > > + if (selinux_compat_net) > > + return 1; > > + > > + if (!skb->secmark) { > > + u32 xfrm_sid; > > + > > + selinux_skb_xfrm_sid(skb, &xfrm_sid); > > + > > + if (xfrm_sid) > > + skb->secmark = xfrm_sid; > > + else if (skb->sk) { > > + struct sk_security_struct *sksec = > skb->sk->sk_security; > > + skb->secmark = sksec->sid; > > + } > > + } > > + > > + err = avc_has_perm(skb->secmark, nf_secid, SECCLASS_PACKET, > > + PACKET__FLOW_OUT, NULL); > > While I don't see any explicit mention of it in the documentation or > your comments, I assume we would want a flow_out check for > NetLabel here > as well? I don't believe we do. By this time, the packet is or should already be carrying the CIPSO/NetLabel option which should already be the right one (derived from the socket or flow as appropriate), but you would want to audit the code to make sure. IOW, the label option in the IP header should already be reflecting the secmark on the skb. But again, you may want to audit the code to make sure. > > > +out: > > + return err ? 0 : 1; > > +} > > + > > static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) > > { > > int err = 0; > > @@ -3700,7 +3766,8 @@ out: > > > > #ifdef CONFIG_NETFILTER > > > > -static int selinux_ip_postroute_last_compat(struct sock > *sk, struct net_device *dev, > > +static int selinux_ip_postroute_last_compat(struct sock > *sk, struct sk_buff *skb, > > + struct net_device *dev, > > struct avc_audit_data *ad, > > u16 family, char > *addrp, int len) > > { > > @@ -3710,6 +3777,9 @@ static int selinux_ip_postroute_last_com > > struct inode *inode; > > struct inode_security_struct *isec; > > > > + if (!sk) > > + goto out; > > + > > sock = sk->sk_socket; > > if (!sock) > > goto out; > > @@ -3768,7 +3838,11 @@ static int selinux_ip_postroute_last_com > > > > err = avc_has_perm(isec->sid, port_sid, isec->sclass, > >send_perm, ad); > > + if (err) > > + goto out; > > } > > + > > + err = selinux_xfrm_postroute_last(isec->sid, skb, ad); > > out: > > return err; > > } > > @@ -3782,17 +3856,9 @@ static unsigned int selinux_ip_postroute > > { > > char *addrp; > > int len, err = 0; > > - struct sock *sk; > > struct sk_buff *skb = *pskb; > > struct avc_audit_data ad; > > struct net_device *dev = (struct net_device *)out; > > - struct sk_security_struct *sksec; > > - > > - sk = skb->sk; > > - if (!sk) > > - goto out; > > - > > - sksec = sk->sk_security; > > > > AVC_AUDIT_DATA_INIT(&ad, NET); > > ad.u.net.netif = dev->name; > > @@ -3803,16 +3869,25 @@ static unsigned int selinux_ip_postroute > > goto out; > > > > if (selinux_compat_net) > > - err = selinux_ip_postroute_last_compat(sk, dev, &ad, > > + err = selinux_ip_postroute_last_compat(skb-
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> That's fine by me, I just wanted to make sure something like > that would > be acceptable. So, in summary, we would do the normal flow_in checks > for both IPsec and NetLabel and then set the secmark using the IPsec > label as the "base sid" for the NetLabel's generated SID? That's correct (in short you won't care if IPSec was in use or not, you would just use the secmark at that point as the base sid in coming up with the NetLabel sid, and if it flow controls fine vis a vis the secmark you would replace secmark with the NetLabel sid. The logic flow is quite natural and intuitive for the users as well). - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> I tend to agree, I just can't see it being all that useful in the real > world. However, each time it comes up (including the conference call > earlier this week) it seems that people would prefer to use > both at the > same time. A matter of providing options to users. It seems more of a pain to actually prevent their use at the same time and/or explain strange/unnatural behavior. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> > Unless I'm confusing something, there still may be a need > for transitions > > if we want to support both IPsec and NetLabel labeling on the same > > connection. > > I'd prefer not to support this, as it's too complicated, Actually, from my vantage point, it actually seems "natural". > and > CIPSO is a > legacy protocol. Sure. > > Normal IPsec protection applied to CIPSO: yes, but not IPsec > labeling and > CIPSO labeling on the same connection. One use case example can be one SA for Secret in combination with any/all/none of the compartments. And another SA for Top Secret ... - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
> > Fine with me, unless Venkat has an immediate use case for such > > transitions in the flow_in case (but I think this is mostly > my fault for > > suggesting transitions a while ago). I don't have a use case currently. > > Unless I'm confusing something, there still may be a need for > transitions > if we want to support both IPsec and NetLabel labeling on the same > connection. > If we don't support transitions and allow both labeling methods on the > same connection we'll need to decide how to handle resolving the two - > maybe use a transition is this one case? Since CIPSO doesn't do full contexts currently, it would be just a matter of an additional flow_in check. The base sid used here would be the current secmark at that point (which will be the xfrm sid if xfrm was used). So, no transitions needed here currently. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] secid reconciliation-v03: Enforcement for SELinux
This defines SELinux enforcement of the 2 new LSM hooks as well as related changes elsewhere in the SELinux code. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/hooks.c| 129 +++--- security/selinux/include/xfrm.h |5 + security/selinux/ss/mls.c |2 security/selinux/ss/services.c |2 security/selinux/xfrm.c | 28 ++ 5 files changed, 139 insertions(+), 27 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5a66c4c..143b4b8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3449,8 +3449,12 @@ static int selinux_sock_rcv_skb_compat(s err = avc_has_perm(sock_sid, port_sid, sock_class, recv_perm, ad); + if (err) + goto out; } + err = selinux_xfrm_sock_rcv_skb(sock_sid, skb, ad); + out: return err; } @@ -3489,10 +3493,6 @@ static int selinux_socket_sock_rcv_skb(s goto out; err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad); - if (err) - goto out; - - err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); out: return err; } @@ -3626,13 +3626,16 @@ static int selinux_inet_conn_request(str return 0; } - err = selinux_xfrm_decode_session(skb, &peersid, 0); - BUG_ON(err); + if (selinux_compat_net) { + err = selinux_xfrm_decode_session(skb, &peersid, 0); + BUG_ON(err); - if (peersid == SECSID_NULL) { - req->secid = sksec->sid; - return 0; - } + if (peersid == SECSID_NULL) { + req->secid = sksec->sid; + return 0; + } + } else + peersid = skb->secmark; err = security_sid_mls_copy(sksec->sid, peersid, &newsid); if (err) @@ -3662,6 +3665,69 @@ static void selinux_req_classify_flow(co fl->secid = req->secid; } +static int selinux_skb_flow_in(struct sk_buff *skb, unsigned short family) +{ + u32 xfrm_sid, trans_sid; + int err; + + if (selinux_compat_net) + return 1; + + /* xfrm/cipso inapplicable for loopback traffic */ + if (skb->dev == &loopback_dev) + return 1; + + err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); + BUG_ON(err); + + err = avc_has_perm(xfrm_sid, skb->secmark, SECCLASS_PACKET, + PACKET__FLOW_IN, NULL); + if (err) + goto out; + + if (xfrm_sid) { + err = security_transition_sid(xfrm_sid, skb->secmark, + SECCLASS_PACKET, &trans_sid); + if (err) + goto out; + + skb->secmark = trans_sid; + } + + /* See if CIPSO can flow in thru the current secmark here */ + +out: + return err ? 0 : 1; +}; + +static int selinux_skb_flow_out(struct sk_buff *skb, u32 nf_secid) +{ + u32 trans_sid; + int err; + + if (selinux_compat_net) + return 1; + + if (!skb->secmark) { + u32 xfrm_sid; + + selinux_skb_xfrm_sid(skb, &xfrm_sid); + + if (xfrm_sid) + skb->secmark = xfrm_sid; + else if (skb->sk) { + struct sk_security_struct *sksec = skb->sk->sk_security; + skb->secmark = sksec->sid; + } + } + + err = avc_has_perm(skb->secmark, nf_secid, SECCLASS_PACKET, + PACKET__FLOW_OUT, NULL); + +out: + return err ? 0 : 1; +} + static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -3700,7 +3766,8 @@ out: #ifdef CONFIG_NETFILTER -static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev, +static int selinux_ip_postroute_last_compat(struct sock *sk, struct sk_buff *skb, + struct net_device *dev, struct avc_audit_data *ad, u16 family, char *addrp, int len) { @@ -3710,6 +3777,9 @@ static int selinux_ip_postroute_last_com struct inode *inode; struct inode_security_struct *isec; + if (!sk) + goto out; + sock = sk->sk_socket; if (!sock) goto out; @@ -3768,7 +3838,11 @@ static int selinux_ip_postroute_last_com err = avc_has_perm(isec->sid, port_sid, isec->sclass, send_perm, ad); + if (err) + goto out; } + + err = selinu
[PATCH 4/7] secid reconciliation-v03: Invoke LSM hook for outbound traffic
Invoke the skb_flow_out LSM hook for outbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- net/netfilter/xt_CONNSECMARK.c | 70 +++ net/netfilter/xt_SECMARK.c | 33 +- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 4673862..40b4150 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -17,6 +17,8 @@ */ #include #include +#include +#include #include #include #include @@ -33,34 +35,70 @@ MODULE_ALIAS("ip6t_CONNSECMARK"); * If the packet has a security mark and the connection does not, copy * the security mark from the packet to the connection. */ -static void secmark_save(struct sk_buff *skb) +static void secmark_save(struct sk_buff *skb, unsigned int hooknum, + const struct xt_target *target) { if (skb->secmark) { u32 *connsecmark; enum ip_conntrack_info ctinfo; connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && !*connsecmark) - if (*connsecmark != skb->secmark) + if (connsecmark) + if (*connsecmark != skb->secmark) { *connsecmark = skb->secmark; + } } } /* - * If packet has no security mark, and the connection does, restore the - * security mark from the connection to the packet. + * On the inbound, restore the security mark from the connection to the packet. + * On the outbound, filter based on the current secmark. */ -static void secmark_restore(struct sk_buff *skb) +static unsigned int secmark_restore(struct sk_buff *skb, unsigned int hooknum, + const struct net_device *in, const struct xt_target *target) { - if (!skb->secmark) { - u32 *connsecmark; - enum ip_conntrack_info ctinfo; - - connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && *connsecmark) - if (skb->secmark != *connsecmark) - skb->secmark = *connsecmark; + u32 *psecmark; + enum ip_conntrack_info ctinfo; + + psecmark = nf_ct_get_secmark(skb, &ctinfo); + + if (psecmark && *psecmark) { + +printk(KERN_ERR "IN HOOK (%d) (%u) (%u)\n", hooknum, skb->secmark, *psecmark); + /* Set secmark on inbound and filter it on outbound */ + if ((target->family == AF_INET && + (hooknum == NF_IP_POST_ROUTING || +hooknum == NF_IP_LOCAL_OUT || +hooknum == NF_IP_FORWARD)) || + (target->family == AF_INET6 && + (hooknum == NF_IP6_POST_ROUTING || +hooknum == NF_IP6_LOCAL_OUT || +hooknum == NF_IP6_FORWARD))) { + /* outbound */ + int err; + + err = security_skb_flow_out(skb, *psecmark); +printk(KERN_ERR "ERR (%d) (%u)\n", err, skb->secmark); + if (!err) + return NF_DROP; + } + else/* inbound */ + /* loopback traffic should already be labeled + and any filtering on outbound should suffice */ + if (in == &loopback_dev) + goto out; + + /* inbound or done with outbound check or no LSM hook + for outbound */ + if (skb->secmark != *psecmark) +{ +printk(KERN_ERR "RESTORING FROM (%u) TO (%u) (%u)\n", skb->secmark, *psecmark, 0x); + skb->secmark = *psecmark; +} } + +out: + return XT_CONTINUE; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -73,11 +111,11 @@ static unsigned int target(struct sk_buf switch (info->mode) { case CONNSECMARK_SAVE: - secmark_save(skb); + secmark_save(skb, hooknum, target); break; case CONNSECMARK_RESTORE: - secmark_restore(skb); + return secmark_restore(skb, hooknum, in, target); break; default: diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index add7521..28dc059 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris <[EMAIL PROTECTED]>"); @@ -47,9 +49,36 @@ static
[PATCH 0/7] secid reconciliation-v03: Repost patchset with updates
This patchset is relative to davem's net-2.6.git The following are the changes included in this patchset since the previous post: - Retain secmark (from the originating socket/flow) on loopback traffic; this traffic is now flow controlled on the outbound only. - When multiple iptables labeling rules are present (e.g.: both on PREROUTING and INPUT) INBOUND: The label in the last rule will prevail. OUTBOUND: secmark (from the originating socket) is flow-controlled against the label on the first rule, and, if it passes, the label on the first rule overrides the secmark (from the originating socket). This secmark is flow controlled against labels on the subsequent rules, each time, overridden by those labels. - Forwarded packets: The FORWARD chain is treated as an outbound chain for flow control purposes. e.g: label with PREROUTING and flow-control with FORWARD or POSTROUTING. - Simplification of the flow_out hook for SELinux: deleted the redundant flow_out check against the xfrm secid and the transition between the xfrm secid and the netfilter secid. - SELinux postroute_last hook: unfortunately, the secmark Vs. UNLABELED SID check will now be done for ALL traffic (I couldn't except traffic already processed by (CONN)SECMARK outbound rules; a better understanding of iptabels resulted in realizing that the SECSID_WILD thing attempted in the previous patchset won't work well). Please consider for inclusion in 2.6.19. PATCHES TO BE POSTED BY COB FRIDAY (tomorrow): NOTE: These patches were originally planned/desired to be included in this set but I didn't want to hold this critical patchset up for one more day since it needs a good extensive review. - Create IPSec SAs to be acquired with the creating sock's context as opposed to that of the matching SPD rule, resulting in a simpler SPD as well as policy. - Set peer_sid on tcp sockets to the reconciled secmark so trusted applications can retrieve and service the data at the appropriate context. include/linux/security.h | 35 include/linux/skbuff.h | 29 +++ include/net/ip.h | 32 include/net/request_sock.h | 17 ++ include/net/xfrm.h | 45 ++--- net/dccp/ipv4.c |5 net/ipv4/icmp.c |4 net/ipv4/ip_output.c |6 net/ipv4/tcp_ipv4.c |1 net/ipv6/ip6_output.c|5 net/ipv6/netfilter/ip6t_REJECT.c |2 net/netfilter/xt_CONNSECMARK.c | 70 +++-- net/netfilter/xt_SECMARK.c | 33 security/dummy.c | 13 + security/selinux/hooks.c | 129 + security/selinux/include/av_perm_to_string.h |2 security/selinux/include/av_permissions.h|2 security/selinux/include/xfrm.h |5 security/selinux/ss/mls.c|2 security/selinux/ss/services.c |2 security/selinux/xfrm.c | 28 +++ 21 files changed, 399 insertions(+), 68 deletions(-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] secid reconciliation-v03: Invoke LSM hook for inbound traffic
Invoke the skb_flow_in LSM hook for inbound traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/xfrm.h | 45 +-- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 11e0b1d..8f9c184 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -675,22 +675,18 @@ extern int __xfrm_policy_check(struct so static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { - if (sk && sk->sk_policy[XFRM_POLICY_IN]) - return __xfrm_policy_check(sk, dir, skb, family); - - return (!xfrm_policy_count[dir] && !skb->sp) || - (skb->dst->flags & DST_NOPOLICY) || - __xfrm_policy_check(sk, dir, skb, family); -} - -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET); -} + int ret; -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET6); + if (sk && sk->sk_policy[XFRM_POLICY_IN]) + ret = __xfrm_policy_check(sk, dir, skb, family); + else + ret = (!xfrm_policy_count[dir] && !skb->sp) || + (skb->dst->flags & DST_NOPOLICY) || + __xfrm_policy_check(sk, dir, skb, family); + + if (ret) + ret = security_skb_flow_in(skb, family); + return ret; } extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family); @@ -742,19 +738,22 @@ static inline void xfrm_sk_free_policy(s static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} +static inline int xfrm_policy_check(struct sock *sk, int dir, + struct sk_buff *skb, unsigned short family) +{ + return security_skb_flow_in(skb, family); +} +#endif + static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) { - return 1; + return xfrm_policy_check(sk, dir, skb, AF_INET); } -static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) + +static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) { - return 1; + return xfrm_policy_check(sk, dir, skb, AF_INET6); } -#endif static __inline__ xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] secid reconciliation-v03: Label locally generated IPv4 traffic
This labels the skb(s) for locally generated IPv4 traffic. This will be used in pertinent flow control checks on the outbound later in the LSM hook. This is not as pretty as it is for IPv6, but what to do? Note that skb(s) that derive the secmark from the originating socket do so in the outbound hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/ip.h | 32 include/net/request_sock.h | 17 + net/dccp/ipv4.c|5 + net/ipv4/icmp.c|4 net/ipv4/ip_output.c |6 ++ net/ipv4/tcp_ipv4.c|1 + 6 files changed, 65 insertions(+) diff --git a/include/net/ip.h b/include/net/ip.h index 98f9084..6d23593 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -48,6 +48,9 @@ struct ipcm_cookie u32 addr; int oif; struct ip_options *opt; +#ifdef CONFIG_SECURITY_NETWORK + u32 secid; +#endif /* CONFIG_SECURITY_NETWORK */ }; #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) @@ -383,4 +386,33 @@ #endif extern struct ctl_table ipv4_table[]; +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ + ipc->secid = 0; + ipc->secid = skb->secmark; +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ + skb->secmark = ipc->secid; +} + +#else + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _IP_H */ diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 8e165ca..bba8dba 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -259,4 +259,21 @@ static inline void reqsk_queue_hash_req( write_unlock(&queue->syn_wait_lock); } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ + skb->secmark = req->secid; +} + +#else + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _REQUEST_SOCK_H */ diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 66be29b..57ba542 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -230,6 +230,8 @@ static void dccp_v4_reqsk_send_ack(struc dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); + security_req_classify_skb(req, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, @@ -261,6 +263,7 @@ static int dccp_v4_send_response(struct dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr, ireq->rmt_addr); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + security_req_classify_skb(req, skb); err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt); @@ -743,6 +746,8 @@ static void dccp_v4_ctl_send_reset(struc dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, rxskb->nh.iph->daddr); + security_skb_classify_skb(rxskb, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c2ad07e..956791a 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -389,6 +389,8 @@ static void icmp_reply(struct icmp_bxm * if (icmp_xmit_lock()) return; + security_skb_classify_ipcm(skb, &ipc); + icmp_param->data.icmph.checksum = 0; icmp_out_count(icmp_param->data.icmph.type); @@ -507,6 +509,8 @@ void icmp_send(struct sk_buff *skb_in, i if (icmp_xmit_lock()) return; + security_skb_classify_ipcm(skb_in, &ipc); + /* * Construct source address and options. */ diff --git a/net/ipv4/ip_output.c b/
[PATCH 1/7] secid reconciliation-v03
This patchset helps one leverage secmark in defining fine-grained security check points with support for a. a default place holder domain defined using secmark for each of the check points and b. flow control and reconciliation of domains entering/leaving the system. The reconciliation steps for SELinux are explained in the Labeled Networking document at: http://marc.theaimsgroup.com/?l=linux-netdev&m=115136637800361&w=2 with the change that SELinux transition rules are used when available to arrive at the new secid. Also please refer to the discussion at: http://marc.theaimsgroup.com/?l=selinux&m=115885031311565&w=2 The following are the identifiers handled here: 1. secmark on the skb 2. xfrm security identifier associated with the skb if it used any xfrms, a zero secid otherwise. This patch: Add new flask definitions to SELinux Adds a new avperm "flow_in" to arbitrate among the identifiers on the inbound (input/forward). Also adds a new avperm "flow_out" to enable flow control checks on the outbound (output/forward), addressed in this patch as well. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/include/av_perm_to_string.h |2 ++ security/selinux/include/av_permissions.h|2 ++ 2 files changed, 4 insertions(+) diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 09fc8a2..1e65d28 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h @@ -245,6 +245,8 @@ S_(SECCLASS_PACKET, PACKET__SEND, "send") S_(SECCLASS_PACKET, PACKET__RECV, "recv") S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") + S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in") + S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out") S_(SECCLASS_KEY, KEY__VIEW, "view") S_(SECCLASS_KEY, KEY__READ, "read") S_(SECCLASS_KEY, KEY__WRITE, "write") diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 81f4f52..2faf3d8 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -962,6 +962,8 @@ #define APPLETALK_SOCKET__NAME_BIND #define PACKET__SEND 0x0001UL #define PACKET__RECV 0x0002UL #define PACKET__RELABELTO 0x0004UL +#define PACKET__FLOW_IN 0x0008UL +#define PACKET__FLOW_OUT 0x0010UL #define KEY__VIEW 0x0001UL #define KEY__READ 0x0002UL - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] secid reconciliation-v03: Add LSM hooks
Add skb_policy_check and skb_netfilter_check hooks to LSM to enable reconciliation of the various security identifiers as well as enforce flow control on inbound (PREROUTING/INPUT) and outbound (OUTPUT/FORWARD/POSTROUTING) traffic. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h | 35 +++ security/dummy.c | 13 + 2 files changed, 48 insertions(+) diff --git a/include/linux/security.h b/include/linux/security.h index 9f56fb8..08726e1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -828,6 +828,15 @@ #ifdef CONFIG_SECURITY * Sets the new child socket's sid to the openreq sid. * @req_classify_flow: * Sets the flow's sid to the openreq sid. + * @skb_flow_in: + * Checks to see if security policy would allow skb into the system + * while also reconciling the xfrm secid, cipso, etc, if any, and + * relabeling the skb with the reconciled secid. + * Returns 1 if skb allowed into system, 0 otherwise. + * @skb_flow_out: + * Checks to see if security policy would allow skb to go out of system. + * Returns 1 if skb allowed out of system, 0 if not, and -ENOENT if there's + * no hook defined. * * Security hooks for XFRM operations. * @@ -1372,6 +1381,8 @@ #ifdef CONFIG_SECURITY_NETWORK struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); + int (*skb_flow_in)(struct sk_buff *skb, unsigned short family); + int (*skb_flow_out)(struct sk_buff *skb, u32 nf_secid); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -2946,6 +2957,18 @@ static inline void security_req_classify security_ops->req_classify_flow(req, fl); } +static inline int security_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return security_ops->skb_flow_in(skb, family); +} + +static inline int security_skb_flow_out(struct sk_buff *skb, + u32 nf_secid) +{ + return security_ops->skb_flow_out(skb, nf_secid); +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { security_ops->sock_graft(sk, parent); @@ -3097,6 +3120,18 @@ static inline void security_req_classify { } +static inline int security_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return 1; +} + +static inline int security_skb_flow_out(struct sk_buff *skb, + u32 nf_secid) +{ + return -ENOENT; +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { } diff --git a/security/dummy.c b/security/dummy.c index aeee705..921be56 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -832,6 +832,17 @@ static inline void dummy_req_classify_fl struct flowi *fl) { } + +static inline int dummy_skb_flow_in(struct sk_buff *skb, + unsigned short family) +{ + return -ENOENT; +} + +static inline int dummy_skb_flow_out(struct sk_buff *skb, u32 nf_secid) +{ + return -ENOENT; +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1108,6 +1119,8 @@ #ifdef CONFIG_SECURITY_NETWORK set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); set_to_dummy_if_null(ops, req_classify_flow); + set_to_dummy_if_null(ops, skb_flow_in); + set_to_dummy_if_null(ops, skb_flow_out); #endif/* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM set_to_dummy_if_null(ops, xfrm_policy_alloc_security); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] secid reconciliation-v03: Label locally generated IPv6 traffic
This labels the skb(s) for locally generated IPv6 traffic. This will be used in pertinent flow control checks on the outbound later in the LSM hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/skbuff.h | 29 + net/ipv6/ip6_output.c|5 + net/ipv6/netfilter/ip6t_REJECT.c |2 ++ 3 files changed, 36 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 85577a4..18967f2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -29,6 +29,7 @@ #include #include #include #include +#include #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8)*/ @@ -1499,5 +1500,33 @@ static inline int skb_is_gso(const struc return skb_shinfo(skb)->gso_size; } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ + skb->secmark = from->secmark; +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ + skb->secmark = fl->secid; +} + +#else + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6671691..6648eb3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -170,6 +170,8 @@ int ip6_xmit(struct sock *sk, struct sk_ int hlimit, tclass; u32 mtu; + security_flow_classify_skb(fl, skb); + if (opt) { int head_room; @@ -1150,6 +1152,9 @@ alloc_new_skb: } if (skb == NULL) goto error; + + security_flow_classify_skb(fl, skb); + /* * Fill in the control structures */ diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 311eae8..0508c30 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -128,6 +128,8 @@ static void send_reset(struct sk_buff *o ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); + security_skb_classify_skb(oldskb, nskb); + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); /* Truncate to length (no data) */ tcph->doff = sizeof(struct tcphdr)/4; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v02: Enforcement for SELinux
> > +static int selinux_skb_policy_check(struct sk_buff *skb, > unsigned short > > family) +{ > > + u32 xfrm_sid, trans_sid; > > + int err; > > + > > + if (selinux_compat_net) > > + return 1; > > + > > + err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); > > + BUG_ON(err); > > First, any reason against including the "struct sock *" in > the LSM hook? At a > quick glance it looks like it is available at each place > security_skb_policy_check() is invoked? If there are no > objections I would > like to see it included in the hook. There's no sock available (NULL) for forward, no-sock, time-wait cases, etc. What you are trying to accomplish with the sock here anyway? > > Second, I wonder if it would be better to do a NetLabel/CIPSO > query here using > the xfrm_sid as the NetLabel "base_sid" instead of at the end > of the function > (see your comment)? This way we wouldn't have to duplicate the > avc_has_perm() and security_transition_sid() calls for both xfrm and > NetLabel. There's a need for an additional avc_has_perm check anyway between the cipso label and the ipsec/transition label, to check to make sure the cipso level falls within the range on the IPSec/transition SA. No need for a new transition between ipsec/transition label and the cipso label since the cipso label would be sharing the TE portion with the ipsec/transition label (this could change in the future, when you get round to doing entire SELinux contexts over the wire). For now, you would just set the secmark to the cipso label if the label could come thru (i.e. if the avc_has_perm succeeds). - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 4/7] secid reconciliation-v02: Invoke LSM hook for out bound traffic
See below. > -Original Message- > From: James Morris [mailto:[EMAIL PROTECTED] > Sent: Monday, September 18, 2006 2:12 PM > To: Venkat Yekkirala > Cc: netdev@vger.kernel.org; [EMAIL PROTECTED]; [EMAIL PROTECTED]; > [EMAIL PROTECTED] > Subject: Re: [PATCH 4/7] secid reconciliation-v02: Invoke LSM hook for > outbound traffic > > > On Fri, 8 Sep 2006, Venkat Yekkirala wrote: > > > -static void secmark_restore(struct sk_buff *skb) > > +static unsigned int secmark_restore(struct sk_buff *skb, > unsigned int > > hooknum, > > + const struct xt_target *target) > > { > > - if (!skb->secmark) { > > - u32 *connsecmark; > > - enum ip_conntrack_info ctinfo; > > + u32 *psecmark; > > + u32 secmark = 0; > > + enum ip_conntrack_info ctinfo; > > > > - connsecmark = nf_ct_get_secmark(skb, &ctinfo); > > - if (connsecmark && *connsecmark) > > - if (skb->secmark != *connsecmark) > > - skb->secmark = *connsecmark; > > - } > > + psecmark = nf_ct_get_secmark(skb, &ctinfo); > > + if (psecmark) > > + secmark = *psecmark; > > + > > + if (!secmark) > > + return XT_CONTINUE; > > + > > + /* Set secmark on inbound and filter it on outbound */ > > + if (hooknum == NF_IP_POST_ROUTING || hooknum == > NF_IP6_POST_ROUTING) { > > + if (!security_skb_netfilter_check(skb, secmark)) > > + return NF_DROP; > > + } else > > + if (skb->secmark != secmark) > > + skb->secmark = secmark; > > + > > + return XT_CONTINUE; > > } > > Quite a lot of logic has changed here. > > With the original code, we only restored a secmark once for > the lifetime > of a packet or connetcion (to make behavior deterministic and > security > marks immutable in the face of arbitrarily complex iptables rules). > > With your patch, secmarks are always writable. Hopefully the following thread addressed these concerns. http://marc.theaimsgroup.com/?l=selinux&m=115870100405571&w=2 > > What about packets on the OUTPUT hook? I will check for OUTPUT as well as POSTROUTING to kickoff skb_flow_out(). > > Also, we did not restore a 'null' (zero) secmark to the skb > (while this > should never happen with the current SECMARK target, there may be > non-SELinux extensions later which set a null marking). How do you envision this (i.e. resoring a null secmark) being useful? secmark is anyway zero by default (when no labeling rules exist for the connection) right? > > Why not just do something like: > > > psecmark = nf_ct_get_secmark(skb, &ctinfo); > if (psecmark && *psecmark) { > > ... core of function ... > > } > > return XT_CONTINUE; > > I don't think you need the new secmark variable. Will do. > > You've also changed the logic for the dummy case of > security_skb_netfilter_check() I am not getting this. This is a new function. Did you mean to point to a different function? > > > +static inline int security_skb_netfilter_check(struct sk_buff *skb, > + u32 nf_secid) > +{ > + return 1; > +} > + > > This code does not now behave as it did originally. Keep in > mind that > SELinux is not the only user of SECMARK. Missed this as well (this is a new function in this patch). Please elaborate. > > (The documentation of the hook in security.h doesn't match > the behavior, > either -- it's (re-)labeling, not just filtering). Will fix this. > > I really don't know if connection tracking is the right place > to be doing > policy enforcment, either. Perhaps you should just do the > relabeling here > and enforcement later. We could have done enforcement, in the SELinux postroute_last hook for example, if only there were a place to hold onto the "exit point context", separate from the label already associated with the skb in the secmark field. postroute_last would need BOTH the label of the skb (available in the secmark field) and the "exit point context" to do enforcement. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [redhat-lspp] ipsec acquire has security context although I a m not using it.
This doesn't look right since kzalloc would already have zeroed the structure out. Are you sure you are getting garbage in the acquire from the kernel? If you are, I strongly doubt that this would be the one causing it (unless kzalloc on this arch misbehaved). Or is this a racoon bug? > -Original Message- > From: Joy Latten [mailto:[EMAIL PROTECTED] > Sent: Tuesday, September 19, 2006 4:17 PM > To: netdev@vger.kernel.org; redhat-lspp@redhat.com; > [EMAIL PROTECTED] > Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED] > Subject: [redhat-lspp] ipsec acquire has security context > although I am > not using it. > > > > When using ipsec while selinux is enabled in my kernel, > my racoon daemon fails to establish an SA. I believe the > ACQUIRE sent from kernel has a security context although I > am not using this feature with ipsec. As a result, racoon > fails to establish the SA, because it is looking for a policy > with security context. I noticed the security context > contains garbage. > > I am using a pseries, power5, ppc64 box, and it appears > that since policy->security structure is not really initialized > or zero'd out when not using, it is possible it may contain garbage > on my pseries and a call such as "if (policy->security)" may > come back as true such that security context is included in > my acquire message although I believe it should not be. > > Hopefully, the below patch is acceptable. I have compiled and > tested it. > > Regards, > Joy Latten > > > diff -urpN linux-2.6.17.orig/net/xfrm/xfrm_policy.c > linux-2.6.17.patch/net/xfrm/xfrm_policy.c > --- linux-2.6.17.orig/net/xfrm/xfrm_policy.c 2006-09-19 > 02:11:33.0 -0500 > +++ linux-2.6.17.patch/net/xfrm/xfrm_policy.c 2006-09-19 > 04:33:50.0 -0500 > @@ -319,6 +319,7 @@ struct xfrm_policy *xfrm_policy_alloc(gf > init_timer(&policy->timer); > policy->timer.data = (unsigned long)policy; > policy->timer.function = xfrm_policy_timer; > + policy->security = NULL; > } > return policy; > } > > -- > redhat-lspp mailing list > redhat-lspp@redhat.com > https://www.redhat.com/mailman/listinfo/redhat-lspp > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 7/7] secid reconciliation-v02: Enforcement for SELinux
> On Fri, 8 Sep 2006, Venkat Yekkirala wrote: > > > + if (selinux_compat_net) { > > + err = selinux_xfrm_decode_session(skb, &peersid, 0); > > + BUG_ON(err); > > I'm pretty sure this should not be a BUG_ON. IIUC, you want > to panic the > kernel because one of the nested SAs has a different security context. No, we are sending in 0 for the ckall param by which we are telling the function NOT to do any checks, but to simply set the return param peersid to the secid on the first xfrm if any and succeed by returning 0. Must not fail. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 4/7] secid reconciliation-v02: Invoke LSM hook for out bound traffic
> On Fri, 8 Sep 2006, Venkat Yekkirala wrote: > > > @@ -114,6 +128,9 @@ static struct xt_target xt_connsecmark_t > > .target = target, > > .targetsize = sizeof(struct > xt_connsecmark_target_info), > > .table = "mangle", > > + .hooks = (1 << NF_IP_LOCAL_IN) | > > + (1 << NF_IP_FORWARD) | > > + (1 << NF_IP_POST_ROUTING), > > Why have you added constraints on the hooks? > > This breaks a bunch of things. I was trying to restrict the module usage to these, but later realized I really needn't. Will take these out. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/7] secid reconciliation-v02: Add LSM hooks
> Is there any way you can send patches without "format=flowed" in the > content-type? On two mailers I've tried, the patches get mangled. Yes. I will send them to you in a few minutes with format=flowed disabled. As soon as you let me know you see them fine, I will resend them to the lists. Thanks. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] secid reconciliation-v02: Repost patchset with updates
The following are the changes included in this patchset since the previous post: - Perform flow_in check before (as opposed to after) computing transition secid on inbound; this seems more intuitive and correct. - Implement reconciliation and flow control for outbound traffic (forward case being a sequence of inbound checks followed by outbound checks). - Make selinux_xfrm_postroute_last checks conditional on compat_net. This patchset is relative to David Miller's net-2.6.19.git (last updated on Sep 1st). Please consider for inclusion in 2.6.19. UPCOMING WORK: The following per the discussion at: http://marc.theaimsgroup.com/?l=selinux&m=115755980516072&w=2 - Create IPSec SAs to be acquired with the creating sock's context as opposed to that of the matching SPD rule, resulting in a simpler SPD as well as policy. - Set peer_sid on tcp sockets to the reconciled secmark so trusted applications can retrieve and service the data at the appropriate context. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] secid reconciliation-v02: Invoke LSM hook for inbound traffic
Invoke the skb_policy_check LSM hook for inbound (INPUT/FORWARD) traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/xfrm.h | 50 +++ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bf8e2df..7b020bd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -663,22 +663,20 @@ extern int __xfrm_policy_check(struct so static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { - if (sk && sk->sk_policy[XFRM_POLICY_IN]) - return __xfrm_policy_check(sk, dir, skb, family); - - return (!xfrm_policy_count[dir] && !skb->sp) || - (skb->dst->flags & DST_NOPOLICY) || - __xfrm_policy_check(sk, dir, skb, family); -} - -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET); -} + int ret; -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET6); + if (sk && sk->sk_policy[XFRM_POLICY_IN]) + ret = __xfrm_policy_check(sk, dir, skb, family); + else + ret = (!xfrm_policy_count[dir] && !skb->sp) || + (skb->dst->flags & DST_NOPOLICY) || + __xfrm_policy_check(sk, dir, skb, family); + +#ifdef CONFIG_SECURITY_NETWORK + if (ret) + ret = security_skb_policy_check(skb, family); +#endif /* CONFIG_SECURITY_NETWORK */ + return ret; } extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family); @@ -730,20 +728,26 @@ static inline void xfrm_sk_free_policy(s static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { +#ifdef CONFIG_SECURITY_NETWORK + return security_skb_policy_check(skb, family); +#else return 1; +#endif /* CONFIG_SECURITY_NETWORK */ } #endif +static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return xfrm_policy_check(sk, dir, skb, AF_INET); +} + +static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return xfrm_policy_check(sk, dir, skb, AF_INET6); +} + static __inline__ xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) { - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] secid reconciliation-v02: Label locally generated IPv6 traffic
This labels the skb(s) for locally generated IPv6 traffic. This will be reconciled with xfrm secid as well as used in pertinent flow control checks on the outbound later in the LSM hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/skbuff.h | 29 + net/ipv6/ip6_output.c|5 + net/ipv6/netfilter/ip6t_REJECT.c |2 ++ 3 files changed, 36 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 85577a4..18967f2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -29,6 +29,7 @@ #include #include #include #include +#include #define HAVE_ALLOC_SKB /* For the drivers to know */ #define HAVE_ALIGNABLE_SKB /* Ditto 8)*/ @@ -1499,5 +1500,33 @@ static inline int skb_is_gso(const struc return skb_shinfo(skb)->gso_size; } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ + skb->secmark = from->secmark; +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ + skb->secmark = fl->secid; +} + +#else + +static inline void security_skb_classify_skb(struct sk_buff *from, + struct sk_buff *skb) +{ +} + +static inline void security_flow_classify_skb(struct flowi *fl, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c14ea1e..753e3b4 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -170,6 +170,8 @@ int ip6_xmit(struct sock *sk, struct sk_ int hlimit, tclass; u32 mtu; + security_flow_classify_skb(fl, skb); + if (opt) { int head_room; @@ -1088,6 +1090,9 @@ alloc_new_skb: } if (skb == NULL) goto error; + + security_flow_classify_skb(fl, skb); + /* * Fill in the control structures */ diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 311eae8..0508c30 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -128,6 +128,8 @@ static void send_reset(struct sk_buff *o ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr); + security_skb_classify_skb(oldskb, nskb); + tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); /* Truncate to length (no data) */ tcph->doff = sizeof(struct tcphdr)/4; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] secid reconciliation-v02: Label locally generated IPv4 traffic
This labels the skb(s) for locally generated IPv4 traffic. This will be reconciled with xfrm secid as well as used in pertinent flow control checks on the outbound later in the LSM hook. This is not as pretty as it is for IPv6, but what to do? Note that skb(s) that derive the secmark from the originating socket do so in the outbound hook. NOTE: Forwarded traffic is already labeled with the reconciled secmark on the inbound. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/ip.h | 32 include/net/request_sock.h | 17 + net/dccp/ipv4.c|5 + net/ipv4/icmp.c|4 net/ipv4/ip_output.c |6 ++ net/ipv4/tcp_ipv4.c|1 + 6 files changed, 65 insertions(+) diff --git a/include/net/ip.h b/include/net/ip.h index 98f9084..4646c13 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -48,6 +48,9 @@ struct ipcm_cookie u32 addr; int oif; struct ip_options *opt; +#ifdef CONFIG_SECURITY_NETWORK + __u32 secid; +#endif /* CONFIG_SECURITY_NETWORK */ }; #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) @@ -383,4 +386,33 @@ #endif extern struct ctl_table ipv4_table[]; +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ + ipc->secid = 0; + ipc->secid = skb->secmark; +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ + skb->secmark = ipc->secid; +} + +#else + +static inline void security_skb_classify_ipcm(struct sk_buff *skb, + struct ipcm_cookie *ipc) +{ +} + +static inline void security_ipcm_classify_skb(struct ipcm_cookie *ipc, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _IP_H */ diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 8e165ca..bba8dba 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -259,4 +259,21 @@ static inline void reqsk_queue_hash_req( write_unlock(&queue->syn_wait_lock); } +#ifdef CONFIG_SECURITY_NETWORK + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ + skb->secmark = req->secid; +} + +#else + +static inline void security_req_classify_skb(struct request_sock *req, + struct sk_buff *skb) +{ +} + +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* _REQUEST_SOCK_H */ diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 9a1a76a..526835e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -233,6 +233,8 @@ static void dccp_v4_reqsk_send_ack(struc dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); + security_req_classify_skb(req, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, @@ -264,6 +266,7 @@ static int dccp_v4_send_response(struct dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr, ireq->rmt_addr); memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + security_req_classify_skb(req, skb); err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, ireq->rmt_addr, ireq->opt); @@ -746,6 +749,8 @@ static void dccp_v4_ctl_send_reset(struc dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, rxskb->nh.iph->daddr); + security_skb_classify_skb(rxskb, skb); + bh_lock_sock(dccp_v4_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, rxskb->nh.iph->daddr, diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index c2ad07e..956791a 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -389,6 +389,8 @@ static void icmp_reply(struct icmp_bxm * if (icmp_xmit_lock()) return; + security_skb_classify_ipcm(skb, &ipc); + icmp_param->data.icmph.checksum = 0; icmp_out_count(icmp_param->data.icmph.type); @@ -507,6 +509,8 @@ void icmp_send(struct sk_buff *skb_in, i if (icmp_xmit_lock()) return; + security_skb_classify_ipcm(skb_in, &ipc); + /* * Construct source address and options. */ diff --git a/net/ipv4/ip_output.c b/
[PATCH 1/7] secid reconciliation-v02
Currently a packet accumulates multiple security identifiers, each of a different class, as it enters/leaves the system. This patch set reconciles these identifiers into a single identifier while also allowing LSM (SELinux is addressed in this patch set) to impose flow control checks based on the identifiers. The reconciliation steps for SELinux are explained in the Labeled Networking document at: http://marc.theaimsgroup.com/?l=linux-netdev&m=115136637800361&w=2 with the change that SELinux transition rules are used when available to arrive at the new secid. The following are the identifiers handled here: 1. secmark on the skb 2. xfrm security identifier associated with the skb if it used any xfrms, a zero secid otherwise. This patch: Add new flask definitions to SELinux Adds a new avperm "flow_in" to arbitrate among the identifiers on the inbound (input/forward). Also adds a new avperm "flow_out" to enable flow control checks on the outbound (output/forward), addressed in this patch as well. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/include/av_perm_to_string.h |2 ++ security/selinux/include/av_permissions.h|2 ++ 2 files changed, 4 insertions(+) diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 09fc8a2..1e65d28 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h @@ -245,6 +245,8 @@ S_(SECCLASS_PACKET, PACKET__SEND, "send") S_(SECCLASS_PACKET, PACKET__RECV, "recv") S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") + S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in") + S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out") S_(SECCLASS_KEY, KEY__VIEW, "view") S_(SECCLASS_KEY, KEY__READ, "read") S_(SECCLASS_KEY, KEY__WRITE, "write") diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 81f4f52..2faf3d8 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -962,6 +962,8 @@ #define APPLETALK_SOCKET__NAME_BIND #define PACKET__SEND 0x0001UL #define PACKET__RECV 0x0002UL #define PACKET__RELABELTO 0x0004UL +#define PACKET__FLOW_IN 0x0008UL +#define PACKET__FLOW_OUT 0x0010UL #define KEY__VIEW 0x0001UL #define KEY__READ 0x0002UL - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] secid reconciliation-v02: Invoke LSM hook for outbound traffic
Invoke the skb_netfilter_check LSM hook for outbound (OUTPUT/FORWARD) traffic for secid reconciliation and flow control. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- net/netfilter/xt_CONNSECMARK.c | 44 ++- net/netfilter/xt_SECMARK.c | 20 -- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 4673862..a79bd20 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c @@ -17,6 +17,8 @@ */ #include #include +#include +#include #include #include #include @@ -47,20 +49,32 @@ static void secmark_save(struct sk_buff } /* - * If packet has no security mark, and the connection does, restore the - * security mark from the connection to the packet. + * On the inbound, restore the security mark from the connection to the packet. + * On the outbound, filter based on the current secmark. */ -static void secmark_restore(struct sk_buff *skb) +static unsigned int secmark_restore(struct sk_buff *skb, unsigned int hooknum, + const struct xt_target *target) { - if (!skb->secmark) { - u32 *connsecmark; - enum ip_conntrack_info ctinfo; + u32 *psecmark; + u32 secmark = 0; + enum ip_conntrack_info ctinfo; - connsecmark = nf_ct_get_secmark(skb, &ctinfo); - if (connsecmark && *connsecmark) - if (skb->secmark != *connsecmark) - skb->secmark = *connsecmark; - } + psecmark = nf_ct_get_secmark(skb, &ctinfo); + if (psecmark) + secmark = *psecmark; + + if (!secmark) + return XT_CONTINUE; + + /* Set secmark on inbound and filter it on outbound */ + if (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP6_POST_ROUTING) { + if (!security_skb_netfilter_check(skb, secmark)) + return NF_DROP; + } else + if (skb->secmark != secmark) + skb->secmark = secmark; + + return XT_CONTINUE; } static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -77,7 +91,7 @@ static unsigned int target(struct sk_buf break; case CONNSECMARK_RESTORE: - secmark_restore(skb); + return secmark_restore(skb, hooknum, target); break; default: @@ -114,6 +128,9 @@ static struct xt_target xt_connsecmark_t .target = target, .targetsize = sizeof(struct xt_connsecmark_target_info), .table = "mangle", + .hooks = (1 << NF_IP_LOCAL_IN) | + (1 << NF_IP_FORWARD) | + (1 << NF_IP_POST_ROUTING), .me = THIS_MODULE, }, { @@ -123,6 +140,9 @@ static struct xt_target xt_connsecmark_t .target = target, .targetsize = sizeof(struct xt_connsecmark_target_info), .table = "mangle", + .hooks = (1 << NF_IP6_LOCAL_IN) | + (1 << NF_IP6_FORWARD) | + (1 << NF_IP6_POST_ROUTING), .me = THIS_MODULE, }, }; diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index add7521..de1de45 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -15,8 +15,10 @@ #include #include #include +#include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Morris <[EMAIL PROTECTED]>"); @@ -47,8 +49,16 @@ static unsigned int target(struct sk_buf BUG(); } - if ((*pskb)->secmark != secmark) - (*pskb)->secmark = secmark; + if (!secmark) + return XT_CONTINUE; + + /* Set secmark on inbound and filter it on outbound */ + if (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP6_POST_ROUTING) { + if (!security_skb_netfilter_check(*pskb, secmark)) + return NF_DROP; + } else + if ((*pskb)->secmark != secmark) + (*pskb)->secmark = secmark; return XT_CONTINUE; } @@ -119,6 +129,9 @@ static struct xt_target xt_secmark_targe .target = target, .targetsize = sizeof(struct xt_secmark_target_info), .table = "mangle", + .hooks = (1 << NF_IP_LOCAL_IN) | + (1 << NF_IP_FORWARD) | + (1 << NF_IP_POST_ROUTING), .me = THIS_
[PATCH 2/7] secid reconciliation-v02: Add LSM hooks
Add skb_policy_check and skb_netfilter_check hooks to LSM to enable reconciliation of the various security identifiers as well as enforce flow control on inbound (INPUT/FORWARD) and outbound (OUTPUT/FORWARD) traffic. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/linux/security.h | 32 security/dummy.c | 13 + 2 files changed, 45 insertions(+) diff --git a/include/linux/security.h b/include/linux/security.h index 9f56fb8..032cede 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -828,6 +828,12 @@ #ifdef CONFIG_SECURITY * Sets the new child socket's sid to the openreq sid. * @req_classify_flow: * Sets the flow's sid to the openreq sid. + * @skb_policy_check: + * Checks to see if security policy would allow skb into the system. + * Returns 1 if skb allowed into system, 0 otherwise. + * @skb_netfilter_check: + * Checks to see if security policy would allow skb to go out of system. + * Returns 1 if skb allowed out of system, 0 otherwise. * * Security hooks for XFRM operations. * @@ -1372,6 +1378,8 @@ #ifdef CONFIG_SECURITY_NETWORK struct request_sock *req); void (*inet_csk_clone)(struct sock *newsk, const struct request_sock *req); void (*req_classify_flow)(const struct request_sock *req, struct flowi *fl); + int (*skb_policy_check)(struct sk_buff *skb, unsigned short family); + int (*skb_netfilter_check)(struct sk_buff *skb, u32 nf_secid); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -2946,6 +2954,18 @@ static inline void security_req_classify security_ops->req_classify_flow(req, fl); } +static inline int security_skb_policy_check(struct sk_buff *skb, + unsigned short family) +{ + return security_ops->skb_policy_check(skb, family); +} + +static inline int security_skb_netfilter_check(struct sk_buff *skb, + u32 nf_secid) +{ + return security_ops->skb_netfilter_check(skb, nf_secid); +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { security_ops->sock_graft(sk, parent); @@ -3097,6 +3117,18 @@ static inline void security_req_classify { } +static inline int security_skb_policy_check(struct sk_buff *skb, + unsigned short family) +{ + return 1; +} + +static inline int security_skb_netfilter_check(struct sk_buff *skb, + u32 nf_secid) +{ + return 1; +} + static inline void security_sock_graft(struct sock* sk, struct socket *parent) { } diff --git a/security/dummy.c b/security/dummy.c index aeee705..077d3c9 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -832,6 +832,17 @@ static inline void dummy_req_classify_fl struct flowi *fl) { } + +static inline int dummy_skb_policy_check(struct sk_buff *skb, + unsigned short family) +{ + return 1; +} + +static inline int dummy_skb_netfilter_check(struct sk_buff *skb, u32 nf_secid) +{ + return 1; +} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1108,6 +1119,8 @@ #ifdef CONFIG_SECURITY_NETWORK set_to_dummy_if_null(ops, inet_conn_request); set_to_dummy_if_null(ops, inet_csk_clone); set_to_dummy_if_null(ops, req_classify_flow); + set_to_dummy_if_null(ops, skb_policy_check); + set_to_dummy_if_null(ops, skb_netfilter_check); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM set_to_dummy_if_null(ops, xfrm_policy_alloc_security); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] secid reconciliation-v02: Enforcement for SELinux
This defines SELinux enforcement of the 2 new LSM hooks. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/hooks.c| 125 -- security/selinux/include/xfrm.h |5 + security/selinux/ss/mls.c |2 security/selinux/ss/services.c |2 security/selinux/xfrm.c | 28 ++ 5 files changed, 136 insertions(+), 26 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5a66c4c..044e452 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3449,8 +3449,12 @@ static int selinux_sock_rcv_skb_compat(s err = avc_has_perm(sock_sid, port_sid, sock_class, recv_perm, ad); + if (err) + goto out; } + err = selinux_xfrm_sock_rcv_skb(sock_sid, skb, ad); + out: return err; } @@ -3489,10 +3493,6 @@ static int selinux_socket_sock_rcv_skb(s goto out; err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad); - if (err) - goto out; - - err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); out: return err; } @@ -3626,13 +3626,16 @@ static int selinux_inet_conn_request(str return 0; } - err = selinux_xfrm_decode_session(skb, &peersid, 0); - BUG_ON(err); + if (selinux_compat_net) { + err = selinux_xfrm_decode_session(skb, &peersid, 0); + BUG_ON(err); - if (peersid == SECSID_NULL) { - req->secid = sksec->sid; - return 0; - } + if (peersid == SECSID_NULL) { + req->secid = sksec->sid; + return 0; + } + } else + peersid = skb->secmark; err = security_sid_mls_copy(sksec->sid, peersid, &newsid); if (err) @@ -3662,6 +3665,78 @@ static void selinux_req_classify_flow(co fl->secid = req->secid; } +static int selinux_skb_policy_check(struct sk_buff *skb, unsigned short family) +{ + u32 xfrm_sid, trans_sid; + int err; + + if (selinux_compat_net) + return 1; + + err = selinux_xfrm_decode_session(skb, &xfrm_sid, 0); + BUG_ON(err); + + err = avc_has_perm(xfrm_sid, skb->secmark, SECCLASS_PACKET, + PACKET__FLOW_IN, NULL); + if (err) + goto out; + + if (xfrm_sid) { + err = security_transition_sid(xfrm_sid, skb->secmark, + SECCLASS_PACKET, &trans_sid); + if (err) + goto out; + + skb->secmark = trans_sid; + } + + /* See if CIPSO can flow in thru the current secmark here */ + +out: + return err ? 0 : 1; +}; + +static int selinux_skb_netfilter_check(struct sk_buff *skb, u32 nf_secid) +{ + u32 xfrm_sid; + u32 trans_sid; + int err; + + if (selinux_compat_net) + return 1; + + if (!skb->secmark && skb->sk) { + struct sk_security_struct *sksec = skb->sk->sk_security; + skb->secmark = sksec->sid; + } + + selinux_skb_xfrm_sid(skb, &xfrm_sid); + + err = avc_has_perm(skb->secmark, xfrm_sid, SECCLASS_PACKET, + PACKET__FLOW_OUT, NULL); + + if (err) + goto out; + + if (xfrm_sid) { + err = security_transition_sid(xfrm_sid, skb->secmark, + SECCLASS_PACKET, &trans_sid); + if (err) + goto out; + + skb->secmark = trans_sid; + } + + err = avc_has_perm(skb->secmark, nf_secid, SECCLASS_PACKET, + PACKET__FLOW_OUT, NULL); + +out: + /* Signal postroute_last that we are done with this skb */ + skb->secmark = SECSID_WILD; + + return err ? 0 : 1; +} + static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -3700,7 +3775,8 @@ out: #ifdef CONFIG_NETFILTER -static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev, +static int selinux_ip_postroute_last_compat(struct sock *sk, struct sk_buff *skb, + struct net_device *dev, struct avc_audit_data *ad, u16 family, char *addrp, int len) { @@ -3710,6 +3786,9 @@ static int selinux_ip_postroute_last_com struct inode *inode; struct inode_security_struct *isec; + if (!sk) + goto out; + sock = sk->sk_socket; if (!sock) goto out; @@ -3768,7 +3847,11 @@ static int selinux_ip_postroute_last_c
RE: [PATCH 0/3] secid reconciliation-v01: Repost patchset with up dates
> Assuming the permission is granted the packet's secmark is > replaced with > the updated context. This updated secmark context would then > be used in > sock_rcv_skb() to make an access decision, yes? You got it. > > >> The ability to make access decisions based on the process > >>consuming the data and the data itself it one of the nicer > >>qualities of > >>NetLabel in my opinion. > > > > This nicer quality ends up being preserved as explained above :) > > It wasn't clear to me from your patch or the "master plan" what you > intended to do with the NetLabel context. I thought the "/* See if > CIPSO can flow in thru the current secmark here */" comment in your > patch was rather cryptic. That was a test for you :) > > > We just need to get out of the mindset of viewing netlabel > separately > > once we are past the reconciliation point. > > Agreed. Although to be honest, I think the NetLabel context can be > reconciled with the secmark and XFRM contexts just as easily using the > existing sock_rcv_skb() hook. Nope. That won't work for forwarded traffic. > I guess I need to see where the > xfrm[4|6]_policy_check() hooks are called from in the stack to better > understand ... You are on the right path here. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] secid reconciliation-v01: Repost patchset with up dates
> My main concern with these patches is that moving the > NetLabel check out > of selinux_socket_sock_rcv_skb() and into > selinux_skb_policy_check() (as > it is currently written) would force us to compare a packet's NetLabel > with either the IPsec label or the secmark label Yes you would do these checks (while using a netlabel based off of the secmark at that point) to enforce flow control and when they succeed, you will copy netlabel into secmark. > and not the socket's > label. The socket Vs. secmark check that happens later in rcv_skb will in fact be looking at the cipso label that is by then a part of the secmark context. > The ability to make access decisions based on the process > consuming the data and the data itself it one of the nicer > qualities of > NetLabel in my opinion. This nicer quality ends up being preserved as explained above :) We just need to get out of the mindset of viewing netlabel separately once we are past the reconciliation point. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 0/3] secid reconciliation-v01: Repost patchset with up dates
> I like these changes, but wondering why you haven't supplied > code for the > outbound case ? > > > - James The code for the outbound is still in the works. I hope to have it out in a week or so. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] secid reconciliation-v01: core networking changes
Invoke the skb_policy_check LSM hook from within networking code. This is being done at the same time and as a part of checking xfrm policy. This is hopefully adequate (not anticipating IP protos that don't use xfrm). Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- include/net/xfrm.h | 50 +++ 1 file changed, 27 insertions(+), 23 deletions(-) --- net-2.6.19.sid2/include/net/xfrm.h 2006-08-24 09:19:13.0 -0500 +++ net-2.6.19.sid3/include/net/xfrm.h 2006-08-24 11:00:27.0 -0500 @@ -663,22 +663,20 @@ extern int __xfrm_policy_check(struct so static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { - if (sk && sk->sk_policy[XFRM_POLICY_IN]) - return __xfrm_policy_check(sk, dir, skb, family); - - return (!xfrm_policy_count[dir] && !skb->sp) || - (skb->dst->flags & DST_NOPOLICY) || - __xfrm_policy_check(sk, dir, skb, family); -} - -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET); -} + int ret; -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return xfrm_policy_check(sk, dir, skb, AF_INET6); + if (sk && sk->sk_policy[XFRM_POLICY_IN]) + ret = __xfrm_policy_check(sk, dir, skb, family); + else + ret = (!xfrm_policy_count[dir] && !skb->sp) || + (skb->dst->flags & DST_NOPOLICY) || + __xfrm_policy_check(sk, dir, skb, family); + +#ifdef CONFIG_SECURITY_NETWORK + if (ret) + ret = security_skb_policy_check(skb, family); +#endif /* CONFIG_SECURITY_NETWORK */ + return ret; } extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family); @@ -730,20 +728,26 @@ static inline void xfrm_sk_free_policy(s static inline int xfrm_sk_clone_policy(struct sock *sk) { return 0; } static inline int xfrm6_route_forward(struct sk_buff *skb) { return 1; } static inline int xfrm4_route_forward(struct sk_buff *skb) { return 1; } -static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} -static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) -{ - return 1; -} static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family) { +#ifdef CONFIG_SECURITY_NETWORK + return security_skb_policy_check(skb, family); +#else return 1; +#endif /* CONFIG_SECURITY_NETWORK */ } #endif +static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return xfrm_policy_check(sk, dir, skb, AF_INET); +} + +static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *skb) +{ + return xfrm_policy_check(sk, dir, skb, AF_INET6); +} + static __inline__ xfrm_address_t *xfrm_flowi_daddr(struct flowi *fl, unsigned short family) { - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] secid reconciliation-v01
Currently a packet accumulates multiple security identifiers, each of a different class, as it enters the system. This patch set reconciles these identifiers into a single identifier while also allowing LSM (SELinux is addressed in this patch set) to impose flow control checks based on the identifiers. The reconciliation steps for SELinux are explained in the Labeled Networking document at: http://marc.theaimsgroup.com/?l=linux-netdev&m=115136637800361&w=2 with the change that SELinux transition rules are used when available to arrive at the new secid. The following are the identifiers handled here: 1. secmark on the skb 2. xfrm security identifier associated with the skb if it used any xfrms, a zero secid otherwise. This patch: Add new flask definitions to SELinux Adds a new avperm "come_thru" to arbitrate among the identifiers on the inbound (input/forward). Also adds a new avperm "go_thru" to enable flow control checks on the outbound (output/forward), addressed in a later patch. Signed-off-by: Venkat Yekkirala <[EMAIL PROTECTED]> --- security/selinux/include/av_perm_to_string.h |2 ++ security/selinux/include/av_permissions.h|2 ++ 2 files changed, 4 insertions(+) --- net-2.6.19.orig/security/selinux/include/av_permissions.h 2006-08-24 09:19:13.0 -0500 +++ net-2.6.19.sid1/security/selinux/include/av_permissions.h 2006-08-24 09:43:09.0 -0500 @@ -962,6 +962,8 @@ #define PACKET__SEND 0x0001UL #define PACKET__RECV 0x0002UL #define PACKET__RELABELTO 0x0004UL +#define PACKET__FLOW_IN 0x0008UL +#define PACKET__FLOW_OUT 0x0010UL #define KEY__VIEW 0x0001UL #define KEY__READ 0x0002UL --- net-2.6.19.orig/security/selinux/include/av_perm_to_string.h 2006-08-24 09:19:13.0 -0500 +++ net-2.6.19.sid1/security/selinux/include/av_perm_to_string.h 2006-08-24 09:43:09.0 -0500 @@ -245,6 +245,8 @@ S_(SECCLASS_PACKET, PACKET__SEND, "send") S_(SECCLASS_PACKET, PACKET__RECV, "recv") S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto") + S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in") + S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out") S_(SECCLASS_KEY, KEY__VIEW, "view") S_(SECCLASS_KEY, KEY__READ, "read") S_(SECCLASS_KEY, KEY__WRITE, "write") - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html