diff options
author | Casey Schaufler <casey@schaufler-ca.com> | 2012-06-18 22:01:36 -0400 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2012-07-13 18:49:24 -0400 |
commit | 3518721a8932b2a243f415c374aef020380efc9d (patch) | |
tree | f16a039687aaf395e6751b7a9edda85e83b52502 /security/smack/smackfs.c | |
parent | 1880eff77e7a7cb46c68fae7cfa33f72f0a6e70e (diff) |
Smack: user access check bounds
Some of the bounds checking used on the /smack/access
interface was lost when support for long labels was
added. No kernel access checks are affected, however
this is a case where /smack/access could be used
incorrectly and fail to detect the error. This patch
reintroduces the original checks.
Targeted for git://git.gitorious.org/smack-next/kernel.git
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r-- | security/smack/smackfs.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 21529658662b..29b760d6b746 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -215,28 +215,27 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list, | |||
215 | * @access: access string | 215 | * @access: access string |
216 | * @rule: Smack rule | 216 | * @rule: Smack rule |
217 | * @import: if non-zero, import labels | 217 | * @import: if non-zero, import labels |
218 | * @len: label length limit | ||
218 | * | 219 | * |
219 | * Returns 0 on success, -1 on failure | 220 | * Returns 0 on success, -1 on failure |
220 | */ | 221 | */ |
221 | static int smk_fill_rule(const char *subject, const char *object, | 222 | static int smk_fill_rule(const char *subject, const char *object, |
222 | const char *access, struct smack_rule *rule, | 223 | const char *access, struct smack_rule *rule, |
223 | int import) | 224 | int import, int len) |
224 | { | 225 | { |
225 | int rc = -1; | ||
226 | int done; | ||
227 | const char *cp; | 226 | const char *cp; |
228 | struct smack_known *skp; | 227 | struct smack_known *skp; |
229 | 228 | ||
230 | if (import) { | 229 | if (import) { |
231 | rule->smk_subject = smk_import(subject, 0); | 230 | rule->smk_subject = smk_import(subject, len); |
232 | if (rule->smk_subject == NULL) | 231 | if (rule->smk_subject == NULL) |
233 | return -1; | 232 | return -1; |
234 | 233 | ||
235 | rule->smk_object = smk_import(object, 0); | 234 | rule->smk_object = smk_import(object, len); |
236 | if (rule->smk_object == NULL) | 235 | if (rule->smk_object == NULL) |
237 | return -1; | 236 | return -1; |
238 | } else { | 237 | } else { |
239 | cp = smk_parse_smack(subject, 0); | 238 | cp = smk_parse_smack(subject, len); |
240 | if (cp == NULL) | 239 | if (cp == NULL) |
241 | return -1; | 240 | return -1; |
242 | skp = smk_find_entry(cp); | 241 | skp = smk_find_entry(cp); |
@@ -245,7 +244,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
245 | return -1; | 244 | return -1; |
246 | rule->smk_subject = skp->smk_known; | 245 | rule->smk_subject = skp->smk_known; |
247 | 246 | ||
248 | cp = smk_parse_smack(object, 0); | 247 | cp = smk_parse_smack(object, len); |
249 | if (cp == NULL) | 248 | if (cp == NULL) |
250 | return -1; | 249 | return -1; |
251 | skp = smk_find_entry(cp); | 250 | skp = smk_find_entry(cp); |
@@ -257,7 +256,7 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
257 | 256 | ||
258 | rule->smk_access = 0; | 257 | rule->smk_access = 0; |
259 | 258 | ||
260 | for (cp = access, done = 0; *cp && !done; cp++) { | 259 | for (cp = access; *cp != '\0'; cp++) { |
261 | switch (*cp) { | 260 | switch (*cp) { |
262 | case '-': | 261 | case '-': |
263 | break; | 262 | break; |
@@ -282,13 +281,11 @@ static int smk_fill_rule(const char *subject, const char *object, | |||
282 | rule->smk_access |= MAY_TRANSMUTE; | 281 | rule->smk_access |= MAY_TRANSMUTE; |
283 | break; | 282 | break; |
284 | default: | 283 | default: |
285 | done = 1; | 284 | return 0; |
286 | break; | ||
287 | } | 285 | } |
288 | } | 286 | } |
289 | rc = 0; | ||
290 | 287 | ||
291 | return rc; | 288 | return 0; |
292 | } | 289 | } |
293 | 290 | ||
294 | /** | 291 | /** |
@@ -304,7 +301,8 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule, int import) | |||
304 | int rc; | 301 | int rc; |
305 | 302 | ||
306 | rc = smk_fill_rule(data, data + SMK_LABELLEN, | 303 | rc = smk_fill_rule(data, data + SMK_LABELLEN, |
307 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import); | 304 | data + SMK_LABELLEN + SMK_LABELLEN, rule, import, |
305 | SMK_LABELLEN); | ||
308 | return rc; | 306 | return rc; |
309 | } | 307 | } |
310 | 308 | ||
@@ -340,7 +338,7 @@ static int smk_parse_long_rule(const char *data, struct smack_rule *rule, | |||
340 | goto free_out_o; | 338 | goto free_out_o; |
341 | 339 | ||
342 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) | 340 | if (sscanf(data, "%s %s %s", subject, object, access) == 3) |
343 | rc = smk_fill_rule(subject, object, access, rule, import); | 341 | rc = smk_fill_rule(subject, object, access, rule, import, 0); |
344 | 342 | ||
345 | kfree(access); | 343 | kfree(access); |
346 | free_out_o: | 344 | free_out_o: |