summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2020-09-28 05:38:26 +0300
committerPaul Moore <paul@paul-moore.com>2020-11-24 02:36:21 +0300
commit3df98d79215ace13d1e91ddfc5a67a0f5acbd83f (patch)
tree3e0db692f0d85f9a73ec0e2dd4298bda62f57b8b /security
parentb2d99bcb27225fe420a8923b21861aef2bb43d9b (diff)
downloadlinux-3df98d79215ace13d1e91ddfc5a67a0f5acbd83f.tar.xz
lsm,selinux: pass flowi_common instead of flowi to the LSM hooks
As pointed out by Herbert in a recent related patch, the LSM hooks do not have the necessary address family information to use the flowi struct safely. As none of the LSMs currently use any of the protocol specific flowi information, replace the flowi pointers with pointers to the address family independent flowi_common struct. Reported-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: James Morris <jamorris@linux.microsoft.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security')
-rw-r--r--security/security.c17
-rw-r--r--security/selinux/hooks.c4
-rw-r--r--security/selinux/include/xfrm.h2
-rw-r--r--security/selinux/xfrm.c13
4 files changed, 19 insertions, 17 deletions
diff --git a/security/security.c b/security/security.c
index a28045dc9e7f..c08e0eec8b9e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2207,15 +2207,16 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk)
}
EXPORT_SYMBOL(security_sk_clone);
-void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
+void security_sk_classify_flow(struct sock *sk, struct flowi_common *flic)
{
- call_void_hook(sk_getsecid, sk, &fl->flowi_secid);
+ call_void_hook(sk_getsecid, sk, &flic->flowic_secid);
}
EXPORT_SYMBOL(security_sk_classify_flow);
-void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
+void security_req_classify_flow(const struct request_sock *req,
+ struct flowi_common *flic)
{
- call_void_hook(req_classify_flow, req, fl);
+ call_void_hook(req_classify_flow, req, flic);
}
EXPORT_SYMBOL(security_req_classify_flow);
@@ -2407,7 +2408,7 @@ int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
struct xfrm_policy *xp,
- const struct flowi *fl)
+ const struct flowi_common *flic)
{
struct security_hook_list *hp;
int rc = LSM_RET_DEFAULT(xfrm_state_pol_flow_match);
@@ -2423,7 +2424,7 @@ int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
*/
hlist_for_each_entry(hp, &security_hook_heads.xfrm_state_pol_flow_match,
list) {
- rc = hp->hook.xfrm_state_pol_flow_match(x, xp, fl);
+ rc = hp->hook.xfrm_state_pol_flow_match(x, xp, flic);
break;
}
return rc;
@@ -2434,9 +2435,9 @@ int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
return call_int_hook(xfrm_decode_session, 0, skb, secid, 1);
}
-void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
+void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic)
{
- int rc = call_int_hook(xfrm_decode_session, 0, skb, &fl->flowi_secid,
+ int rc = call_int_hook(xfrm_decode_session, 0, skb, &flic->flowic_secid,
0);
BUG_ON(rc);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 943c2693cec7..a515abdf115b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5437,9 +5437,9 @@ static void selinux_secmark_refcount_dec(void)
}
static void selinux_req_classify_flow(const struct request_sock *req,
- struct flowi *fl)
+ struct flowi_common *flic)
{
- fl->flowi_secid = req->secid;
+ flic->flowic_secid = req->secid;
}
static int selinux_tun_dev_alloc_security(void **security)
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index a0b465316292..0a6f34a7a971 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -26,7 +26,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x);
int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
struct xfrm_policy *xp,
- const struct flowi *fl);
+ const struct flowi_common *flic);
#ifdef CONFIG_SECURITY_NETWORK_XFRM
extern atomic_t selinux_xfrm_refcount;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 7314196185d1..c367d36965d4 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -175,9 +175,10 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
*/
int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
struct xfrm_policy *xp,
- const struct flowi *fl)
+ const struct flowi_common *flic)
{
u32 state_sid;
+ u32 flic_sid;
if (!xp->security)
if (x->security)
@@ -196,17 +197,17 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
return 0;
state_sid = x->security->ctx_sid;
+ flic_sid = flic->flowic_secid;
- if (fl->flowi_secid != state_sid)
+ if (flic_sid != state_sid)
return 0;
/* We don't need a separate SA Vs. policy polmatch check since the SA
* is now of the same label as the flow and a flow Vs. policy polmatch
* check had already happened in selinux_xfrm_policy_lookup() above. */
- return (avc_has_perm(&selinux_state,
- fl->flowi_secid, state_sid,
- SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
- NULL) ? 0 : 1);
+ return (avc_has_perm(&selinux_state, flic_sid, state_sid,
+ SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
+ NULL) ? 0 : 1);
}
static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)