diff options
Diffstat (limited to 'security')
| -rw-r--r-- | security/dummy.c | 3 | ||||
| -rw-r--r-- | security/selinux/include/xfrm.h | 3 | ||||
| -rw-r--r-- | security/selinux/xfrm.c | 53 |
3 files changed, 45 insertions, 14 deletions
diff --git a/security/dummy.c b/security/dummy.c index aeee70565509..43874c1e6e23 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
| @@ -881,7 +881,8 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x, | |||
| 881 | return 1; | 881 | return 1; |
| 882 | } | 882 | } |
| 883 | 883 | ||
| 884 | static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 884 | static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
| 885 | struct xfrm_policy *xp) | ||
| 885 | { | 886 | { |
| 886 | return 1; | 887 | return 1; |
| 887 | } | 888 | } |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 81eb59890162..526b28019aca 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
| @@ -19,7 +19,8 @@ int selinux_xfrm_state_delete(struct xfrm_state *x); | |||
| 19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); |
| 20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, |
| 21 | struct xfrm_policy *xp, struct flowi *fl); | 21 | struct xfrm_policy *xp, struct flowi *fl); |
| 22 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); | 22 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
| 23 | struct xfrm_policy *xp); | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 25 | /* | 26 | /* |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 3e742b850af6..675b995a67c3 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
| @@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | |||
| 77 | */ | 77 | */ |
| 78 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 78 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) |
| 79 | { | 79 | { |
| 80 | int rc = 0; | 80 | int rc; |
| 81 | u32 sel_sid = SECINITSID_UNLABELED; | 81 | u32 sel_sid; |
| 82 | struct xfrm_sec_ctx *ctx; | 82 | struct xfrm_sec_ctx *ctx; |
| 83 | 83 | ||
| 84 | /* Context sid is either set to label or ANY_ASSOC */ | 84 | /* Context sid is either set to label or ANY_ASSOC */ |
| @@ -88,11 +88,21 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | |||
| 88 | 88 | ||
| 89 | sel_sid = ctx->ctx_sid; | 89 | sel_sid = ctx->ctx_sid; |
| 90 | } | 90 | } |
| 91 | else | ||
| 92 | /* | ||
| 93 | * All flows should be treated as polmatch'ing an | ||
| 94 | * otherwise applicable "non-labeled" policy. This | ||
| 95 | * would prevent inadvertent "leaks". | ||
| 96 | */ | ||
| 97 | return 0; | ||
| 91 | 98 | ||
| 92 | rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, | 99 | rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, |
| 93 | ASSOCIATION__POLMATCH, | 100 | ASSOCIATION__POLMATCH, |
| 94 | NULL); | 101 | NULL); |
| 95 | 102 | ||
| 103 | if (rc == -EACCES) | ||
| 104 | rc = -ESRCH; | ||
| 105 | |||
| 96 | return rc; | 106 | return rc; |
| 97 | } | 107 | } |
| 98 | 108 | ||
| @@ -108,15 +118,20 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
| 108 | u32 pol_sid; | 118 | u32 pol_sid; |
| 109 | int err; | 119 | int err; |
| 110 | 120 | ||
| 111 | if (x->security) | 121 | if (xp->security) { |
| 112 | state_sid = x->security->ctx_sid; | 122 | if (!x->security) |
| 113 | else | 123 | /* unlabeled SA and labeled policy can't match */ |
| 114 | state_sid = SECINITSID_UNLABELED; | 124 | return 0; |
| 115 | 125 | else | |
| 116 | if (xp->security) | 126 | state_sid = x->security->ctx_sid; |
| 117 | pol_sid = xp->security->ctx_sid; | 127 | pol_sid = xp->security->ctx_sid; |
| 118 | else | 128 | } else |
| 119 | pol_sid = SECINITSID_UNLABELED; | 129 | if (x->security) |
| 130 | /* unlabeled policy and labeled SA can't match */ | ||
| 131 | return 0; | ||
| 132 | else | ||
| 133 | /* unlabeled policy and unlabeled SA match all flows */ | ||
| 134 | return 1; | ||
| 120 | 135 | ||
| 121 | err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, | 136 | err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, |
| 122 | ASSOCIATION__POLMATCH, | 137 | ASSOCIATION__POLMATCH, |
| @@ -125,7 +140,11 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
| 125 | if (err) | 140 | if (err) |
| 126 | return 0; | 141 | return 0; |
| 127 | 142 | ||
| 128 | return selinux_xfrm_flow_state_match(fl, x); | 143 | err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION, |
| 144 | ASSOCIATION__SENDTO, | ||
| 145 | NULL)? 0:1; | ||
| 146 | |||
| 147 | return err; | ||
| 129 | } | 148 | } |
| 130 | 149 | ||
| 131 | /* | 150 | /* |
| @@ -133,12 +152,22 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
| 133 | * can use a given security association. | 152 | * can use a given security association. |
| 134 | */ | 153 | */ |
| 135 | 154 | ||
| 136 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 155 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
| 156 | struct xfrm_policy *xp) | ||
| 137 | { | 157 | { |
| 138 | int rc = 0; | 158 | int rc = 0; |
| 139 | u32 sel_sid = SECINITSID_UNLABELED; | 159 | u32 sel_sid = SECINITSID_UNLABELED; |
| 140 | struct xfrm_sec_ctx *ctx; | 160 | struct xfrm_sec_ctx *ctx; |
| 141 | 161 | ||
| 162 | if (!xp->security) | ||
| 163 | if (!xfrm->security) | ||
| 164 | return 1; | ||
| 165 | else | ||
| 166 | return 0; | ||
| 167 | else | ||
| 168 | if (!xfrm->security) | ||
| 169 | return 0; | ||
| 170 | |||
| 142 | /* Context sid is either set to label or ANY_ASSOC */ | 171 | /* Context sid is either set to label or ANY_ASSOC */ |
| 143 | if ((ctx = xfrm->security)) { | 172 | if ((ctx = xfrm->security)) { |
| 144 | if (!selinux_authorizable_ctx(ctx)) | 173 | if (!selinux_authorizable_ctx(ctx)) |
