diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 1222 |
1 files changed, 437 insertions, 785 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 7ce683259357..2f82a54f8703 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -79,7 +79,6 @@ | |||
79 | #include <linux/personality.h> | 79 | #include <linux/personality.h> |
80 | #include <linux/audit.h> | 80 | #include <linux/audit.h> |
81 | #include <linux/string.h> | 81 | #include <linux/string.h> |
82 | #include <linux/selinux.h> | ||
83 | #include <linux/mutex.h> | 82 | #include <linux/mutex.h> |
84 | #include <linux/posix-timers.h> | 83 | #include <linux/posix-timers.h> |
85 | #include <linux/syslog.h> | 84 | #include <linux/syslog.h> |
@@ -88,6 +87,7 @@ | |||
88 | #include <linux/msg.h> | 87 | #include <linux/msg.h> |
89 | #include <linux/shm.h> | 88 | #include <linux/shm.h> |
90 | #include <linux/bpf.h> | 89 | #include <linux/bpf.h> |
90 | #include <uapi/linux/mount.h> | ||
91 | 91 | ||
92 | #include "avc.h" | 92 | #include "avc.h" |
93 | #include "objsec.h" | 93 | #include "objsec.h" |
@@ -120,9 +120,8 @@ __setup("enforcing=", enforcing_setup); | |||
120 | #define selinux_enforcing_boot 1 | 120 | #define selinux_enforcing_boot 1 |
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | int selinux_enabled __lsm_ro_after_init = 1; | ||
123 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | 124 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM |
124 | int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; | ||
125 | |||
126 | static int __init selinux_enabled_setup(char *str) | 125 | static int __init selinux_enabled_setup(char *str) |
127 | { | 126 | { |
128 | unsigned long enabled; | 127 | unsigned long enabled; |
@@ -131,8 +130,6 @@ static int __init selinux_enabled_setup(char *str) | |||
131 | return 1; | 130 | return 1; |
132 | } | 131 | } |
133 | __setup("selinux=", selinux_enabled_setup); | 132 | __setup("selinux=", selinux_enabled_setup); |
134 | #else | ||
135 | int selinux_enabled = 1; | ||
136 | #endif | 133 | #endif |
137 | 134 | ||
138 | static unsigned int selinux_checkreqprot_boot = | 135 | static unsigned int selinux_checkreqprot_boot = |
@@ -148,9 +145,6 @@ static int __init checkreqprot_setup(char *str) | |||
148 | } | 145 | } |
149 | __setup("checkreqprot=", checkreqprot_setup); | 146 | __setup("checkreqprot=", checkreqprot_setup); |
150 | 147 | ||
151 | static struct kmem_cache *sel_inode_cache; | ||
152 | static struct kmem_cache *file_security_cache; | ||
153 | |||
154 | /** | 148 | /** |
155 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled | 149 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled |
156 | * | 150 | * |
@@ -213,12 +207,8 @@ static void cred_init_security(void) | |||
213 | struct cred *cred = (struct cred *) current->real_cred; | 207 | struct cred *cred = (struct cred *) current->real_cred; |
214 | struct task_security_struct *tsec; | 208 | struct task_security_struct *tsec; |
215 | 209 | ||
216 | tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL); | 210 | tsec = selinux_cred(cred); |
217 | if (!tsec) | ||
218 | panic("SELinux: Failed to initialize initial task.\n"); | ||
219 | |||
220 | tsec->osid = tsec->sid = SECINITSID_KERNEL; | 211 | tsec->osid = tsec->sid = SECINITSID_KERNEL; |
221 | cred->security = tsec; | ||
222 | } | 212 | } |
223 | 213 | ||
224 | /* | 214 | /* |
@@ -228,7 +218,7 @@ static inline u32 cred_sid(const struct cred *cred) | |||
228 | { | 218 | { |
229 | const struct task_security_struct *tsec; | 219 | const struct task_security_struct *tsec; |
230 | 220 | ||
231 | tsec = cred->security; | 221 | tsec = selinux_cred(cred); |
232 | return tsec->sid; | 222 | return tsec->sid; |
233 | } | 223 | } |
234 | 224 | ||
@@ -249,13 +239,9 @@ static inline u32 task_sid(const struct task_struct *task) | |||
249 | 239 | ||
250 | static int inode_alloc_security(struct inode *inode) | 240 | static int inode_alloc_security(struct inode *inode) |
251 | { | 241 | { |
252 | struct inode_security_struct *isec; | 242 | struct inode_security_struct *isec = selinux_inode(inode); |
253 | u32 sid = current_sid(); | 243 | u32 sid = current_sid(); |
254 | 244 | ||
255 | isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); | ||
256 | if (!isec) | ||
257 | return -ENOMEM; | ||
258 | |||
259 | spin_lock_init(&isec->lock); | 245 | spin_lock_init(&isec->lock); |
260 | INIT_LIST_HEAD(&isec->list); | 246 | INIT_LIST_HEAD(&isec->list); |
261 | isec->inode = inode; | 247 | isec->inode = inode; |
@@ -263,7 +249,6 @@ static int inode_alloc_security(struct inode *inode) | |||
263 | isec->sclass = SECCLASS_FILE; | 249 | isec->sclass = SECCLASS_FILE; |
264 | isec->task_sid = sid; | 250 | isec->task_sid = sid; |
265 | isec->initialized = LABEL_INVALID; | 251 | isec->initialized = LABEL_INVALID; |
266 | inode->i_security = isec; | ||
267 | 252 | ||
268 | return 0; | 253 | return 0; |
269 | } | 254 | } |
@@ -280,7 +265,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
280 | struct dentry *dentry, | 265 | struct dentry *dentry, |
281 | bool may_sleep) | 266 | bool may_sleep) |
282 | { | 267 | { |
283 | struct inode_security_struct *isec = inode->i_security; | 268 | struct inode_security_struct *isec = selinux_inode(inode); |
284 | 269 | ||
285 | might_sleep_if(may_sleep); | 270 | might_sleep_if(may_sleep); |
286 | 271 | ||
@@ -301,7 +286,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
301 | 286 | ||
302 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) | 287 | static struct inode_security_struct *inode_security_novalidate(struct inode *inode) |
303 | { | 288 | { |
304 | return inode->i_security; | 289 | return selinux_inode(inode); |
305 | } | 290 | } |
306 | 291 | ||
307 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) | 292 | static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) |
@@ -311,7 +296,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
311 | error = __inode_security_revalidate(inode, NULL, !rcu); | 296 | error = __inode_security_revalidate(inode, NULL, !rcu); |
312 | if (error) | 297 | if (error) |
313 | return ERR_PTR(error); | 298 | return ERR_PTR(error); |
314 | return inode->i_security; | 299 | return selinux_inode(inode); |
315 | } | 300 | } |
316 | 301 | ||
317 | /* | 302 | /* |
@@ -320,14 +305,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo | |||
320 | static struct inode_security_struct *inode_security(struct inode *inode) | 305 | static struct inode_security_struct *inode_security(struct inode *inode) |
321 | { | 306 | { |
322 | __inode_security_revalidate(inode, NULL, true); | 307 | __inode_security_revalidate(inode, NULL, true); |
323 | return inode->i_security; | 308 | return selinux_inode(inode); |
324 | } | 309 | } |
325 | 310 | ||
326 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) | 311 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) |
327 | { | 312 | { |
328 | struct inode *inode = d_backing_inode(dentry); | 313 | struct inode *inode = d_backing_inode(dentry); |
329 | 314 | ||
330 | return inode->i_security; | 315 | return selinux_inode(inode); |
331 | } | 316 | } |
332 | 317 | ||
333 | /* | 318 | /* |
@@ -338,22 +323,17 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr | |||
338 | struct inode *inode = d_backing_inode(dentry); | 323 | struct inode *inode = d_backing_inode(dentry); |
339 | 324 | ||
340 | __inode_security_revalidate(inode, dentry, true); | 325 | __inode_security_revalidate(inode, dentry, true); |
341 | return inode->i_security; | 326 | return selinux_inode(inode); |
342 | } | ||
343 | |||
344 | static void inode_free_rcu(struct rcu_head *head) | ||
345 | { | ||
346 | struct inode_security_struct *isec; | ||
347 | |||
348 | isec = container_of(head, struct inode_security_struct, rcu); | ||
349 | kmem_cache_free(sel_inode_cache, isec); | ||
350 | } | 327 | } |
351 | 328 | ||
352 | static void inode_free_security(struct inode *inode) | 329 | static void inode_free_security(struct inode *inode) |
353 | { | 330 | { |
354 | struct inode_security_struct *isec = inode->i_security; | 331 | struct inode_security_struct *isec = selinux_inode(inode); |
355 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | 332 | struct superblock_security_struct *sbsec; |
356 | 333 | ||
334 | if (!isec) | ||
335 | return; | ||
336 | sbsec = inode->i_sb->s_security; | ||
357 | /* | 337 | /* |
358 | * As not all inode security structures are in a list, we check for | 338 | * As not all inode security structures are in a list, we check for |
359 | * empty list outside of the lock to make sure that we won't waste | 339 | * empty list outside of the lock to make sure that we won't waste |
@@ -369,42 +349,19 @@ static void inode_free_security(struct inode *inode) | |||
369 | list_del_init(&isec->list); | 349 | list_del_init(&isec->list); |
370 | spin_unlock(&sbsec->isec_lock); | 350 | spin_unlock(&sbsec->isec_lock); |
371 | } | 351 | } |
372 | |||
373 | /* | ||
374 | * The inode may still be referenced in a path walk and | ||
375 | * a call to selinux_inode_permission() can be made | ||
376 | * after inode_free_security() is called. Ideally, the VFS | ||
377 | * wouldn't do this, but fixing that is a much harder | ||
378 | * job. For now, simply free the i_security via RCU, and | ||
379 | * leave the current inode->i_security pointer intact. | ||
380 | * The inode will be freed after the RCU grace period too. | ||
381 | */ | ||
382 | call_rcu(&isec->rcu, inode_free_rcu); | ||
383 | } | 352 | } |
384 | 353 | ||
385 | static int file_alloc_security(struct file *file) | 354 | static int file_alloc_security(struct file *file) |
386 | { | 355 | { |
387 | struct file_security_struct *fsec; | 356 | struct file_security_struct *fsec = selinux_file(file); |
388 | u32 sid = current_sid(); | 357 | u32 sid = current_sid(); |
389 | 358 | ||
390 | fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL); | ||
391 | if (!fsec) | ||
392 | return -ENOMEM; | ||
393 | |||
394 | fsec->sid = sid; | 359 | fsec->sid = sid; |
395 | fsec->fown_sid = sid; | 360 | fsec->fown_sid = sid; |
396 | file->f_security = fsec; | ||
397 | 361 | ||
398 | return 0; | 362 | return 0; |
399 | } | 363 | } |
400 | 364 | ||
401 | static void file_free_security(struct file *file) | ||
402 | { | ||
403 | struct file_security_struct *fsec = file->f_security; | ||
404 | file->f_security = NULL; | ||
405 | kmem_cache_free(file_security_cache, fsec); | ||
406 | } | ||
407 | |||
408 | static int superblock_alloc_security(struct super_block *sb) | 365 | static int superblock_alloc_security(struct super_block *sb) |
409 | { | 366 | { |
410 | struct superblock_security_struct *sbsec; | 367 | struct superblock_security_struct *sbsec; |
@@ -432,6 +389,20 @@ static void superblock_free_security(struct super_block *sb) | |||
432 | kfree(sbsec); | 389 | kfree(sbsec); |
433 | } | 390 | } |
434 | 391 | ||
392 | struct selinux_mnt_opts { | ||
393 | const char *fscontext, *context, *rootcontext, *defcontext; | ||
394 | }; | ||
395 | |||
396 | static void selinux_free_mnt_opts(void *mnt_opts) | ||
397 | { | ||
398 | struct selinux_mnt_opts *opts = mnt_opts; | ||
399 | kfree(opts->fscontext); | ||
400 | kfree(opts->context); | ||
401 | kfree(opts->rootcontext); | ||
402 | kfree(opts->defcontext); | ||
403 | kfree(opts); | ||
404 | } | ||
405 | |||
435 | static inline int inode_doinit(struct inode *inode) | 406 | static inline int inode_doinit(struct inode *inode) |
436 | { | 407 | { |
437 | return inode_doinit_with_dentry(inode, NULL); | 408 | return inode_doinit_with_dentry(inode, NULL); |
@@ -443,20 +414,42 @@ enum { | |||
443 | Opt_fscontext = 2, | 414 | Opt_fscontext = 2, |
444 | Opt_defcontext = 3, | 415 | Opt_defcontext = 3, |
445 | Opt_rootcontext = 4, | 416 | Opt_rootcontext = 4, |
446 | Opt_labelsupport = 5, | 417 | Opt_seclabel = 5, |
447 | Opt_nextmntopt = 6, | ||
448 | }; | 418 | }; |
449 | 419 | ||
450 | #define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1) | 420 | #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} |
451 | 421 | static struct { | |
452 | static const match_table_t tokens = { | 422 | const char *name; |
453 | {Opt_context, CONTEXT_STR "%s"}, | 423 | int len; |
454 | {Opt_fscontext, FSCONTEXT_STR "%s"}, | 424 | int opt; |
455 | {Opt_defcontext, DEFCONTEXT_STR "%s"}, | 425 | bool has_arg; |
456 | {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, | 426 | } tokens[] = { |
457 | {Opt_labelsupport, LABELSUPP_STR}, | 427 | A(context, true), |
458 | {Opt_error, NULL}, | 428 | A(fscontext, true), |
429 | A(defcontext, true), | ||
430 | A(rootcontext, true), | ||
431 | A(seclabel, false), | ||
459 | }; | 432 | }; |
433 | #undef A | ||
434 | |||
435 | static int match_opt_prefix(char *s, int l, char **arg) | ||
436 | { | ||
437 | int i; | ||
438 | |||
439 | for (i = 0; i < ARRAY_SIZE(tokens); i++) { | ||
440 | size_t len = tokens[i].len; | ||
441 | if (len > l || memcmp(s, tokens[i].name, len)) | ||
442 | continue; | ||
443 | if (tokens[i].has_arg) { | ||
444 | if (len == l || s[len] != '=') | ||
445 | continue; | ||
446 | *arg = s + len + 1; | ||
447 | } else if (len != l) | ||
448 | continue; | ||
449 | return tokens[i].opt; | ||
450 | } | ||
451 | return Opt_error; | ||
452 | } | ||
460 | 453 | ||
461 | #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" | 454 | #define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" |
462 | 455 | ||
@@ -464,7 +457,7 @@ static int may_context_mount_sb_relabel(u32 sid, | |||
464 | struct superblock_security_struct *sbsec, | 457 | struct superblock_security_struct *sbsec, |
465 | const struct cred *cred) | 458 | const struct cred *cred) |
466 | { | 459 | { |
467 | const struct task_security_struct *tsec = cred->security; | 460 | const struct task_security_struct *tsec = selinux_cred(cred); |
468 | int rc; | 461 | int rc; |
469 | 462 | ||
470 | rc = avc_has_perm(&selinux_state, | 463 | rc = avc_has_perm(&selinux_state, |
@@ -483,7 +476,7 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
483 | struct superblock_security_struct *sbsec, | 476 | struct superblock_security_struct *sbsec, |
484 | const struct cred *cred) | 477 | const struct cred *cred) |
485 | { | 478 | { |
486 | const struct task_security_struct *tsec = cred->security; | 479 | const struct task_security_struct *tsec = selinux_cred(cred); |
487 | int rc; | 480 | int rc; |
488 | rc = avc_has_perm(&selinux_state, | 481 | rc = avc_has_perm(&selinux_state, |
489 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, | 482 | tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, |
@@ -497,16 +490,10 @@ static int may_context_mount_inode_relabel(u32 sid, | |||
497 | return rc; | 490 | return rc; |
498 | } | 491 | } |
499 | 492 | ||
500 | static int selinux_is_sblabel_mnt(struct super_block *sb) | 493 | static int selinux_is_genfs_special_handling(struct super_block *sb) |
501 | { | 494 | { |
502 | struct superblock_security_struct *sbsec = sb->s_security; | 495 | /* Special handling. Genfs but also in-core setxattr handler */ |
503 | 496 | return !strcmp(sb->s_type->name, "sysfs") || | |
504 | return sbsec->behavior == SECURITY_FS_USE_XATTR || | ||
505 | sbsec->behavior == SECURITY_FS_USE_TRANS || | ||
506 | sbsec->behavior == SECURITY_FS_USE_TASK || | ||
507 | sbsec->behavior == SECURITY_FS_USE_NATIVE || | ||
508 | /* Special handling. Genfs but also in-core setxattr handler */ | ||
509 | !strcmp(sb->s_type->name, "sysfs") || | ||
510 | !strcmp(sb->s_type->name, "pstore") || | 497 | !strcmp(sb->s_type->name, "pstore") || |
511 | !strcmp(sb->s_type->name, "debugfs") || | 498 | !strcmp(sb->s_type->name, "debugfs") || |
512 | !strcmp(sb->s_type->name, "tracefs") || | 499 | !strcmp(sb->s_type->name, "tracefs") || |
@@ -516,6 +503,34 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
516 | !strcmp(sb->s_type->name, "cgroup2"))); | 503 | !strcmp(sb->s_type->name, "cgroup2"))); |
517 | } | 504 | } |
518 | 505 | ||
506 | static int selinux_is_sblabel_mnt(struct super_block *sb) | ||
507 | { | ||
508 | struct superblock_security_struct *sbsec = sb->s_security; | ||
509 | |||
510 | /* | ||
511 | * IMPORTANT: Double-check logic in this function when adding a new | ||
512 | * SECURITY_FS_USE_* definition! | ||
513 | */ | ||
514 | BUILD_BUG_ON(SECURITY_FS_USE_MAX != 7); | ||
515 | |||
516 | switch (sbsec->behavior) { | ||
517 | case SECURITY_FS_USE_XATTR: | ||
518 | case SECURITY_FS_USE_TRANS: | ||
519 | case SECURITY_FS_USE_TASK: | ||
520 | case SECURITY_FS_USE_NATIVE: | ||
521 | return 1; | ||
522 | |||
523 | case SECURITY_FS_USE_GENFS: | ||
524 | return selinux_is_genfs_special_handling(sb); | ||
525 | |||
526 | /* Never allow relabeling on context mounts */ | ||
527 | case SECURITY_FS_USE_MNTPOINT: | ||
528 | case SECURITY_FS_USE_NONE: | ||
529 | default: | ||
530 | return 0; | ||
531 | } | ||
532 | } | ||
533 | |||
519 | static int sb_finish_set_opts(struct super_block *sb) | 534 | static int sb_finish_set_opts(struct super_block *sb) |
520 | { | 535 | { |
521 | struct superblock_security_struct *sbsec = sb->s_security; | 536 | struct superblock_security_struct *sbsec = sb->s_security; |
@@ -570,10 +585,9 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
570 | during get_sb by a pseudo filesystem that directly | 585 | during get_sb by a pseudo filesystem that directly |
571 | populates itself. */ | 586 | populates itself. */ |
572 | spin_lock(&sbsec->isec_lock); | 587 | spin_lock(&sbsec->isec_lock); |
573 | next_inode: | 588 | while (!list_empty(&sbsec->isec_head)) { |
574 | if (!list_empty(&sbsec->isec_head)) { | ||
575 | struct inode_security_struct *isec = | 589 | struct inode_security_struct *isec = |
576 | list_entry(sbsec->isec_head.next, | 590 | list_first_entry(&sbsec->isec_head, |
577 | struct inode_security_struct, list); | 591 | struct inode_security_struct, list); |
578 | struct inode *inode = isec->inode; | 592 | struct inode *inode = isec->inode; |
579 | list_del_init(&isec->list); | 593 | list_del_init(&isec->list); |
@@ -585,112 +599,12 @@ next_inode: | |||
585 | iput(inode); | 599 | iput(inode); |
586 | } | 600 | } |
587 | spin_lock(&sbsec->isec_lock); | 601 | spin_lock(&sbsec->isec_lock); |
588 | goto next_inode; | ||
589 | } | 602 | } |
590 | spin_unlock(&sbsec->isec_lock); | 603 | spin_unlock(&sbsec->isec_lock); |
591 | out: | 604 | out: |
592 | return rc; | 605 | return rc; |
593 | } | 606 | } |
594 | 607 | ||
595 | /* | ||
596 | * This function should allow an FS to ask what it's mount security | ||
597 | * options were so it can use those later for submounts, displaying | ||
598 | * mount options, or whatever. | ||
599 | */ | ||
600 | static int selinux_get_mnt_opts(const struct super_block *sb, | ||
601 | struct security_mnt_opts *opts) | ||
602 | { | ||
603 | int rc = 0, i; | ||
604 | struct superblock_security_struct *sbsec = sb->s_security; | ||
605 | char *context = NULL; | ||
606 | u32 len; | ||
607 | char tmp; | ||
608 | |||
609 | security_init_mnt_opts(opts); | ||
610 | |||
611 | if (!(sbsec->flags & SE_SBINITIALIZED)) | ||
612 | return -EINVAL; | ||
613 | |||
614 | if (!selinux_state.initialized) | ||
615 | return -EINVAL; | ||
616 | |||
617 | /* make sure we always check enough bits to cover the mask */ | ||
618 | BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS)); | ||
619 | |||
620 | tmp = sbsec->flags & SE_MNTMASK; | ||
621 | /* count the number of mount options for this sb */ | ||
622 | for (i = 0; i < NUM_SEL_MNT_OPTS; i++) { | ||
623 | if (tmp & 0x01) | ||
624 | opts->num_mnt_opts++; | ||
625 | tmp >>= 1; | ||
626 | } | ||
627 | /* Check if the Label support flag is set */ | ||
628 | if (sbsec->flags & SBLABEL_MNT) | ||
629 | opts->num_mnt_opts++; | ||
630 | |||
631 | opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); | ||
632 | if (!opts->mnt_opts) { | ||
633 | rc = -ENOMEM; | ||
634 | goto out_free; | ||
635 | } | ||
636 | |||
637 | opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); | ||
638 | if (!opts->mnt_opts_flags) { | ||
639 | rc = -ENOMEM; | ||
640 | goto out_free; | ||
641 | } | ||
642 | |||
643 | i = 0; | ||
644 | if (sbsec->flags & FSCONTEXT_MNT) { | ||
645 | rc = security_sid_to_context(&selinux_state, sbsec->sid, | ||
646 | &context, &len); | ||
647 | if (rc) | ||
648 | goto out_free; | ||
649 | opts->mnt_opts[i] = context; | ||
650 | opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; | ||
651 | } | ||
652 | if (sbsec->flags & CONTEXT_MNT) { | ||
653 | rc = security_sid_to_context(&selinux_state, | ||
654 | sbsec->mntpoint_sid, | ||
655 | &context, &len); | ||
656 | if (rc) | ||
657 | goto out_free; | ||
658 | opts->mnt_opts[i] = context; | ||
659 | opts->mnt_opts_flags[i++] = CONTEXT_MNT; | ||
660 | } | ||
661 | if (sbsec->flags & DEFCONTEXT_MNT) { | ||
662 | rc = security_sid_to_context(&selinux_state, sbsec->def_sid, | ||
663 | &context, &len); | ||
664 | if (rc) | ||
665 | goto out_free; | ||
666 | opts->mnt_opts[i] = context; | ||
667 | opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; | ||
668 | } | ||
669 | if (sbsec->flags & ROOTCONTEXT_MNT) { | ||
670 | struct dentry *root = sbsec->sb->s_root; | ||
671 | struct inode_security_struct *isec = backing_inode_security(root); | ||
672 | |||
673 | rc = security_sid_to_context(&selinux_state, isec->sid, | ||
674 | &context, &len); | ||
675 | if (rc) | ||
676 | goto out_free; | ||
677 | opts->mnt_opts[i] = context; | ||
678 | opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; | ||
679 | } | ||
680 | if (sbsec->flags & SBLABEL_MNT) { | ||
681 | opts->mnt_opts[i] = NULL; | ||
682 | opts->mnt_opts_flags[i++] = SBLABEL_MNT; | ||
683 | } | ||
684 | |||
685 | BUG_ON(i != opts->num_mnt_opts); | ||
686 | |||
687 | return 0; | ||
688 | |||
689 | out_free: | ||
690 | security_free_mnt_opts(opts); | ||
691 | return rc; | ||
692 | } | ||
693 | |||
694 | static int bad_option(struct superblock_security_struct *sbsec, char flag, | 608 | static int bad_option(struct superblock_security_struct *sbsec, char flag, |
695 | u32 old_sid, u32 new_sid) | 609 | u32 old_sid, u32 new_sid) |
696 | { | 610 | { |
@@ -711,31 +625,39 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, | |||
711 | return 0; | 625 | return 0; |
712 | } | 626 | } |
713 | 627 | ||
628 | static int parse_sid(struct super_block *sb, const char *s, u32 *sid) | ||
629 | { | ||
630 | int rc = security_context_str_to_sid(&selinux_state, s, | ||
631 | sid, GFP_KERNEL); | ||
632 | if (rc) | ||
633 | pr_warn("SELinux: security_context_str_to_sid" | ||
634 | "(%s) failed for (dev %s, type %s) errno=%d\n", | ||
635 | s, sb->s_id, sb->s_type->name, rc); | ||
636 | return rc; | ||
637 | } | ||
638 | |||
714 | /* | 639 | /* |
715 | * Allow filesystems with binary mount data to explicitly set mount point | 640 | * Allow filesystems with binary mount data to explicitly set mount point |
716 | * labeling information. | 641 | * labeling information. |
717 | */ | 642 | */ |
718 | static int selinux_set_mnt_opts(struct super_block *sb, | 643 | static int selinux_set_mnt_opts(struct super_block *sb, |
719 | struct security_mnt_opts *opts, | 644 | void *mnt_opts, |
720 | unsigned long kern_flags, | 645 | unsigned long kern_flags, |
721 | unsigned long *set_kern_flags) | 646 | unsigned long *set_kern_flags) |
722 | { | 647 | { |
723 | const struct cred *cred = current_cred(); | 648 | const struct cred *cred = current_cred(); |
724 | int rc = 0, i; | ||
725 | struct superblock_security_struct *sbsec = sb->s_security; | 649 | struct superblock_security_struct *sbsec = sb->s_security; |
726 | const char *name = sb->s_type->name; | ||
727 | struct dentry *root = sbsec->sb->s_root; | 650 | struct dentry *root = sbsec->sb->s_root; |
651 | struct selinux_mnt_opts *opts = mnt_opts; | ||
728 | struct inode_security_struct *root_isec; | 652 | struct inode_security_struct *root_isec; |
729 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 653 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
730 | u32 defcontext_sid = 0; | 654 | u32 defcontext_sid = 0; |
731 | char **mount_options = opts->mnt_opts; | 655 | int rc = 0; |
732 | int *flags = opts->mnt_opts_flags; | ||
733 | int num_opts = opts->num_mnt_opts; | ||
734 | 656 | ||
735 | mutex_lock(&sbsec->lock); | 657 | mutex_lock(&sbsec->lock); |
736 | 658 | ||
737 | if (!selinux_state.initialized) { | 659 | if (!selinux_state.initialized) { |
738 | if (!num_opts) { | 660 | if (!opts) { |
739 | /* Defer initialization until selinux_complete_init, | 661 | /* Defer initialization until selinux_complete_init, |
740 | after the initial policy is loaded and the security | 662 | after the initial policy is loaded and the security |
741 | server is ready to handle calls. */ | 663 | server is ready to handle calls. */ |
@@ -765,7 +687,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
765 | * will be used for both mounts) | 687 | * will be used for both mounts) |
766 | */ | 688 | */ |
767 | if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | 689 | if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) |
768 | && (num_opts == 0)) | 690 | && !opts) |
769 | goto out; | 691 | goto out; |
770 | 692 | ||
771 | root_isec = backing_inode_security_novalidate(root); | 693 | root_isec = backing_inode_security_novalidate(root); |
@@ -775,68 +697,48 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
775 | * also check if someone is trying to mount the same sb more | 697 | * also check if someone is trying to mount the same sb more |
776 | * than once with different security options. | 698 | * than once with different security options. |
777 | */ | 699 | */ |
778 | for (i = 0; i < num_opts; i++) { | 700 | if (opts) { |
779 | u32 sid; | 701 | if (opts->fscontext) { |
780 | 702 | rc = parse_sid(sb, opts->fscontext, &fscontext_sid); | |
781 | if (flags[i] == SBLABEL_MNT) | 703 | if (rc) |
782 | continue; | 704 | goto out; |
783 | rc = security_context_str_to_sid(&selinux_state, | ||
784 | mount_options[i], &sid, | ||
785 | GFP_KERNEL); | ||
786 | if (rc) { | ||
787 | pr_warn("SELinux: security_context_str_to_sid" | ||
788 | "(%s) failed for (dev %s, type %s) errno=%d\n", | ||
789 | mount_options[i], sb->s_id, name, rc); | ||
790 | goto out; | ||
791 | } | ||
792 | switch (flags[i]) { | ||
793 | case FSCONTEXT_MNT: | ||
794 | fscontext_sid = sid; | ||
795 | |||
796 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, | 705 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, |
797 | fscontext_sid)) | 706 | fscontext_sid)) |
798 | goto out_double_mount; | 707 | goto out_double_mount; |
799 | |||
800 | sbsec->flags |= FSCONTEXT_MNT; | 708 | sbsec->flags |= FSCONTEXT_MNT; |
801 | break; | 709 | } |
802 | case CONTEXT_MNT: | 710 | if (opts->context) { |
803 | context_sid = sid; | 711 | rc = parse_sid(sb, opts->context, &context_sid); |
804 | 712 | if (rc) | |
713 | goto out; | ||
805 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, | 714 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, |
806 | context_sid)) | 715 | context_sid)) |
807 | goto out_double_mount; | 716 | goto out_double_mount; |
808 | |||
809 | sbsec->flags |= CONTEXT_MNT; | 717 | sbsec->flags |= CONTEXT_MNT; |
810 | break; | 718 | } |
811 | case ROOTCONTEXT_MNT: | 719 | if (opts->rootcontext) { |
812 | rootcontext_sid = sid; | 720 | rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid); |
813 | 721 | if (rc) | |
722 | goto out; | ||
814 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, | 723 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, |
815 | rootcontext_sid)) | 724 | rootcontext_sid)) |
816 | goto out_double_mount; | 725 | goto out_double_mount; |
817 | |||
818 | sbsec->flags |= ROOTCONTEXT_MNT; | 726 | sbsec->flags |= ROOTCONTEXT_MNT; |
819 | 727 | } | |
820 | break; | 728 | if (opts->defcontext) { |
821 | case DEFCONTEXT_MNT: | 729 | rc = parse_sid(sb, opts->defcontext, &defcontext_sid); |
822 | defcontext_sid = sid; | 730 | if (rc) |
823 | 731 | goto out; | |
824 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, | 732 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, |
825 | defcontext_sid)) | 733 | defcontext_sid)) |
826 | goto out_double_mount; | 734 | goto out_double_mount; |
827 | |||
828 | sbsec->flags |= DEFCONTEXT_MNT; | 735 | sbsec->flags |= DEFCONTEXT_MNT; |
829 | |||
830 | break; | ||
831 | default: | ||
832 | rc = -EINVAL; | ||
833 | goto out; | ||
834 | } | 736 | } |
835 | } | 737 | } |
836 | 738 | ||
837 | if (sbsec->flags & SE_SBINITIALIZED) { | 739 | if (sbsec->flags & SE_SBINITIALIZED) { |
838 | /* previously mounted with options, but not on this attempt? */ | 740 | /* previously mounted with options, but not on this attempt? */ |
839 | if ((sbsec->flags & SE_MNTMASK) && !num_opts) | 741 | if ((sbsec->flags & SE_MNTMASK) && !opts) |
840 | goto out_double_mount; | 742 | goto out_double_mount; |
841 | rc = 0; | 743 | rc = 0; |
842 | goto out; | 744 | goto out; |
@@ -969,7 +871,8 @@ out: | |||
969 | out_double_mount: | 871 | out_double_mount: |
970 | rc = -EINVAL; | 872 | rc = -EINVAL; |
971 | pr_warn("SELinux: mount invalid. Same superblock, different " | 873 | pr_warn("SELinux: mount invalid. Same superblock, different " |
972 | "security settings for (dev %s, type %s)\n", sb->s_id, name); | 874 | "security settings for (dev %s, type %s)\n", sb->s_id, |
875 | sb->s_type->name); | ||
973 | goto out; | 876 | goto out; |
974 | } | 877 | } |
975 | 878 | ||
@@ -1081,218 +984,145 @@ out: | |||
1081 | return rc; | 984 | return rc; |
1082 | } | 985 | } |
1083 | 986 | ||
1084 | static int selinux_parse_opts_str(char *options, | 987 | static int selinux_add_opt(int token, const char *s, void **mnt_opts) |
1085 | struct security_mnt_opts *opts) | ||
1086 | { | 988 | { |
1087 | char *p; | 989 | struct selinux_mnt_opts *opts = *mnt_opts; |
1088 | char *context = NULL, *defcontext = NULL; | ||
1089 | char *fscontext = NULL, *rootcontext = NULL; | ||
1090 | int rc, num_mnt_opts = 0; | ||
1091 | 990 | ||
1092 | opts->num_mnt_opts = 0; | 991 | if (token == Opt_seclabel) /* eaten and completely ignored */ |
1093 | 992 | return 0; | |
1094 | /* Standard string-based options. */ | ||
1095 | while ((p = strsep(&options, "|")) != NULL) { | ||
1096 | int token; | ||
1097 | substring_t args[MAX_OPT_ARGS]; | ||
1098 | |||
1099 | if (!*p) | ||
1100 | continue; | ||
1101 | |||
1102 | token = match_token(p, tokens, args); | ||
1103 | |||
1104 | switch (token) { | ||
1105 | case Opt_context: | ||
1106 | if (context || defcontext) { | ||
1107 | rc = -EINVAL; | ||
1108 | pr_warn(SEL_MOUNT_FAIL_MSG); | ||
1109 | goto out_err; | ||
1110 | } | ||
1111 | context = match_strdup(&args[0]); | ||
1112 | if (!context) { | ||
1113 | rc = -ENOMEM; | ||
1114 | goto out_err; | ||
1115 | } | ||
1116 | break; | ||
1117 | |||
1118 | case Opt_fscontext: | ||
1119 | if (fscontext) { | ||
1120 | rc = -EINVAL; | ||
1121 | pr_warn(SEL_MOUNT_FAIL_MSG); | ||
1122 | goto out_err; | ||
1123 | } | ||
1124 | fscontext = match_strdup(&args[0]); | ||
1125 | if (!fscontext) { | ||
1126 | rc = -ENOMEM; | ||
1127 | goto out_err; | ||
1128 | } | ||
1129 | break; | ||
1130 | |||
1131 | case Opt_rootcontext: | ||
1132 | if (rootcontext) { | ||
1133 | rc = -EINVAL; | ||
1134 | pr_warn(SEL_MOUNT_FAIL_MSG); | ||
1135 | goto out_err; | ||
1136 | } | ||
1137 | rootcontext = match_strdup(&args[0]); | ||
1138 | if (!rootcontext) { | ||
1139 | rc = -ENOMEM; | ||
1140 | goto out_err; | ||
1141 | } | ||
1142 | break; | ||
1143 | |||
1144 | case Opt_defcontext: | ||
1145 | if (context || defcontext) { | ||
1146 | rc = -EINVAL; | ||
1147 | pr_warn(SEL_MOUNT_FAIL_MSG); | ||
1148 | goto out_err; | ||
1149 | } | ||
1150 | defcontext = match_strdup(&args[0]); | ||
1151 | if (!defcontext) { | ||
1152 | rc = -ENOMEM; | ||
1153 | goto out_err; | ||
1154 | } | ||
1155 | break; | ||
1156 | case Opt_labelsupport: | ||
1157 | break; | ||
1158 | default: | ||
1159 | rc = -EINVAL; | ||
1160 | pr_warn("SELinux: unknown mount option\n"); | ||
1161 | goto out_err; | ||
1162 | |||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | rc = -ENOMEM; | ||
1167 | opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_KERNEL); | ||
1168 | if (!opts->mnt_opts) | ||
1169 | goto out_err; | ||
1170 | |||
1171 | opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), | ||
1172 | GFP_KERNEL); | ||
1173 | if (!opts->mnt_opts_flags) | ||
1174 | goto out_err; | ||
1175 | 993 | ||
1176 | if (fscontext) { | 994 | if (!opts) { |
1177 | opts->mnt_opts[num_mnt_opts] = fscontext; | 995 | opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); |
1178 | opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; | 996 | if (!opts) |
1179 | } | 997 | return -ENOMEM; |
1180 | if (context) { | 998 | *mnt_opts = opts; |
1181 | opts->mnt_opts[num_mnt_opts] = context; | ||
1182 | opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; | ||
1183 | } | ||
1184 | if (rootcontext) { | ||
1185 | opts->mnt_opts[num_mnt_opts] = rootcontext; | ||
1186 | opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; | ||
1187 | } | 999 | } |
1188 | if (defcontext) { | 1000 | if (!s) |
1189 | opts->mnt_opts[num_mnt_opts] = defcontext; | 1001 | return -ENOMEM; |
1190 | opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; | 1002 | switch (token) { |
1003 | case Opt_context: | ||
1004 | if (opts->context || opts->defcontext) | ||
1005 | goto Einval; | ||
1006 | opts->context = s; | ||
1007 | break; | ||
1008 | case Opt_fscontext: | ||
1009 | if (opts->fscontext) | ||
1010 | goto Einval; | ||
1011 | opts->fscontext = s; | ||
1012 | break; | ||
1013 | case Opt_rootcontext: | ||
1014 | if (opts->rootcontext) | ||
1015 | goto Einval; | ||
1016 | opts->rootcontext = s; | ||
1017 | break; | ||
1018 | case Opt_defcontext: | ||
1019 | if (opts->context || opts->defcontext) | ||
1020 | goto Einval; | ||
1021 | opts->defcontext = s; | ||
1022 | break; | ||
1191 | } | 1023 | } |
1192 | |||
1193 | opts->num_mnt_opts = num_mnt_opts; | ||
1194 | return 0; | 1024 | return 0; |
1195 | 1025 | Einval: | |
1196 | out_err: | 1026 | pr_warn(SEL_MOUNT_FAIL_MSG); |
1197 | security_free_mnt_opts(opts); | 1027 | return -EINVAL; |
1198 | kfree(context); | ||
1199 | kfree(defcontext); | ||
1200 | kfree(fscontext); | ||
1201 | kfree(rootcontext); | ||
1202 | return rc; | ||
1203 | } | 1028 | } |
1204 | /* | ||
1205 | * string mount options parsing and call set the sbsec | ||
1206 | */ | ||
1207 | static int superblock_doinit(struct super_block *sb, void *data) | ||
1208 | { | ||
1209 | int rc = 0; | ||
1210 | char *options = data; | ||
1211 | struct security_mnt_opts opts; | ||
1212 | |||
1213 | security_init_mnt_opts(&opts); | ||
1214 | |||
1215 | if (!data) | ||
1216 | goto out; | ||
1217 | 1029 | ||
1218 | BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); | 1030 | static int selinux_add_mnt_opt(const char *option, const char *val, int len, |
1031 | void **mnt_opts) | ||
1032 | { | ||
1033 | int token = Opt_error; | ||
1034 | int rc, i; | ||
1219 | 1035 | ||
1220 | rc = selinux_parse_opts_str(options, &opts); | 1036 | for (i = 0; i < ARRAY_SIZE(tokens); i++) { |
1221 | if (rc) | 1037 | if (strcmp(option, tokens[i].name) == 0) { |
1222 | goto out_err; | 1038 | token = tokens[i].opt; |
1039 | break; | ||
1040 | } | ||
1041 | } | ||
1223 | 1042 | ||
1224 | out: | 1043 | if (token == Opt_error) |
1225 | rc = selinux_set_mnt_opts(sb, &opts, 0, NULL); | 1044 | return -EINVAL; |
1226 | 1045 | ||
1227 | out_err: | 1046 | if (token != Opt_seclabel) |
1228 | security_free_mnt_opts(&opts); | 1047 | val = kmemdup_nul(val, len, GFP_KERNEL); |
1048 | rc = selinux_add_opt(token, val, mnt_opts); | ||
1049 | if (unlikely(rc)) { | ||
1050 | kfree(val); | ||
1051 | if (*mnt_opts) { | ||
1052 | selinux_free_mnt_opts(*mnt_opts); | ||
1053 | *mnt_opts = NULL; | ||
1054 | } | ||
1055 | } | ||
1229 | return rc; | 1056 | return rc; |
1230 | } | 1057 | } |
1231 | 1058 | ||
1232 | static void selinux_write_opts(struct seq_file *m, | 1059 | static int show_sid(struct seq_file *m, u32 sid) |
1233 | struct security_mnt_opts *opts) | ||
1234 | { | 1060 | { |
1235 | int i; | 1061 | char *context = NULL; |
1236 | char *prefix; | 1062 | u32 len; |
1237 | 1063 | int rc; | |
1238 | for (i = 0; i < opts->num_mnt_opts; i++) { | ||
1239 | char *has_comma; | ||
1240 | 1064 | ||
1241 | if (opts->mnt_opts[i]) | 1065 | rc = security_sid_to_context(&selinux_state, sid, |
1242 | has_comma = strchr(opts->mnt_opts[i], ','); | 1066 | &context, &len); |
1243 | else | 1067 | if (!rc) { |
1244 | has_comma = NULL; | 1068 | bool has_comma = context && strchr(context, ','); |
1245 | 1069 | ||
1246 | switch (opts->mnt_opts_flags[i]) { | ||
1247 | case CONTEXT_MNT: | ||
1248 | prefix = CONTEXT_STR; | ||
1249 | break; | ||
1250 | case FSCONTEXT_MNT: | ||
1251 | prefix = FSCONTEXT_STR; | ||
1252 | break; | ||
1253 | case ROOTCONTEXT_MNT: | ||
1254 | prefix = ROOTCONTEXT_STR; | ||
1255 | break; | ||
1256 | case DEFCONTEXT_MNT: | ||
1257 | prefix = DEFCONTEXT_STR; | ||
1258 | break; | ||
1259 | case SBLABEL_MNT: | ||
1260 | seq_putc(m, ','); | ||
1261 | seq_puts(m, LABELSUPP_STR); | ||
1262 | continue; | ||
1263 | default: | ||
1264 | BUG(); | ||
1265 | return; | ||
1266 | }; | ||
1267 | /* we need a comma before each option */ | ||
1268 | seq_putc(m, ','); | ||
1269 | seq_puts(m, prefix); | ||
1270 | if (has_comma) | 1070 | if (has_comma) |
1271 | seq_putc(m, '\"'); | 1071 | seq_putc(m, '\"'); |
1272 | seq_escape(m, opts->mnt_opts[i], "\"\n\\"); | 1072 | seq_escape(m, context, "\"\n\\"); |
1273 | if (has_comma) | 1073 | if (has_comma) |
1274 | seq_putc(m, '\"'); | 1074 | seq_putc(m, '\"'); |
1275 | } | 1075 | } |
1076 | kfree(context); | ||
1077 | return rc; | ||
1276 | } | 1078 | } |
1277 | 1079 | ||
1278 | static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) | 1080 | static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) |
1279 | { | 1081 | { |
1280 | struct security_mnt_opts opts; | 1082 | struct superblock_security_struct *sbsec = sb->s_security; |
1281 | int rc; | 1083 | int rc; |
1282 | 1084 | ||
1283 | rc = selinux_get_mnt_opts(sb, &opts); | 1085 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
1284 | if (rc) { | 1086 | return 0; |
1285 | /* before policy load we may get EINVAL, don't show anything */ | ||
1286 | if (rc == -EINVAL) | ||
1287 | rc = 0; | ||
1288 | return rc; | ||
1289 | } | ||
1290 | |||
1291 | selinux_write_opts(m, &opts); | ||
1292 | 1087 | ||
1293 | security_free_mnt_opts(&opts); | 1088 | if (!selinux_state.initialized) |
1089 | return 0; | ||
1294 | 1090 | ||
1295 | return rc; | 1091 | if (sbsec->flags & FSCONTEXT_MNT) { |
1092 | seq_putc(m, ','); | ||
1093 | seq_puts(m, FSCONTEXT_STR); | ||
1094 | rc = show_sid(m, sbsec->sid); | ||
1095 | if (rc) | ||
1096 | return rc; | ||
1097 | } | ||
1098 | if (sbsec->flags & CONTEXT_MNT) { | ||
1099 | seq_putc(m, ','); | ||
1100 | seq_puts(m, CONTEXT_STR); | ||
1101 | rc = show_sid(m, sbsec->mntpoint_sid); | ||
1102 | if (rc) | ||
1103 | return rc; | ||
1104 | } | ||
1105 | if (sbsec->flags & DEFCONTEXT_MNT) { | ||
1106 | seq_putc(m, ','); | ||
1107 | seq_puts(m, DEFCONTEXT_STR); | ||
1108 | rc = show_sid(m, sbsec->def_sid); | ||
1109 | if (rc) | ||
1110 | return rc; | ||
1111 | } | ||
1112 | if (sbsec->flags & ROOTCONTEXT_MNT) { | ||
1113 | struct dentry *root = sbsec->sb->s_root; | ||
1114 | struct inode_security_struct *isec = backing_inode_security(root); | ||
1115 | seq_putc(m, ','); | ||
1116 | seq_puts(m, ROOTCONTEXT_STR); | ||
1117 | rc = show_sid(m, isec->sid); | ||
1118 | if (rc) | ||
1119 | return rc; | ||
1120 | } | ||
1121 | if (sbsec->flags & SBLABEL_MNT) { | ||
1122 | seq_putc(m, ','); | ||
1123 | seq_puts(m, LABELSUPP_STR); | ||
1124 | } | ||
1125 | return 0; | ||
1296 | } | 1126 | } |
1297 | 1127 | ||
1298 | static inline u16 inode_mode_to_security_class(umode_t mode) | 1128 | static inline u16 inode_mode_to_security_class(umode_t mode) |
@@ -1522,7 +1352,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry, | |||
1522 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) | 1352 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) |
1523 | { | 1353 | { |
1524 | struct superblock_security_struct *sbsec = NULL; | 1354 | struct superblock_security_struct *sbsec = NULL; |
1525 | struct inode_security_struct *isec = inode->i_security; | 1355 | struct inode_security_struct *isec = selinux_inode(inode); |
1526 | u32 task_sid, sid = 0; | 1356 | u32 task_sid, sid = 0; |
1527 | u16 sclass; | 1357 | u16 sclass; |
1528 | struct dentry *dentry; | 1358 | struct dentry *dentry; |
@@ -1769,7 +1599,7 @@ static inline u32 signal_to_av(int sig) | |||
1769 | 1599 | ||
1770 | /* Check whether a task is allowed to use a capability. */ | 1600 | /* Check whether a task is allowed to use a capability. */ |
1771 | static int cred_has_capability(const struct cred *cred, | 1601 | static int cred_has_capability(const struct cred *cred, |
1772 | int cap, int audit, bool initns) | 1602 | int cap, unsigned int opts, bool initns) |
1773 | { | 1603 | { |
1774 | struct common_audit_data ad; | 1604 | struct common_audit_data ad; |
1775 | struct av_decision avd; | 1605 | struct av_decision avd; |
@@ -1796,7 +1626,7 @@ static int cred_has_capability(const struct cred *cred, | |||
1796 | 1626 | ||
1797 | rc = avc_has_perm_noaudit(&selinux_state, | 1627 | rc = avc_has_perm_noaudit(&selinux_state, |
1798 | sid, sid, sclass, av, 0, &avd); | 1628 | sid, sid, sclass, av, 0, &avd); |
1799 | if (audit == SECURITY_CAP_AUDIT) { | 1629 | if (!(opts & CAP_OPT_NOAUDIT)) { |
1800 | int rc2 = avc_audit(&selinux_state, | 1630 | int rc2 = avc_audit(&selinux_state, |
1801 | sid, sid, sclass, av, &avd, rc, &ad, 0); | 1631 | sid, sid, sclass, av, &avd, rc, &ad, 0); |
1802 | if (rc2) | 1632 | if (rc2) |
@@ -1822,7 +1652,7 @@ static int inode_has_perm(const struct cred *cred, | |||
1822 | return 0; | 1652 | return 0; |
1823 | 1653 | ||
1824 | sid = cred_sid(cred); | 1654 | sid = cred_sid(cred); |
1825 | isec = inode->i_security; | 1655 | isec = selinux_inode(inode); |
1826 | 1656 | ||
1827 | return avc_has_perm(&selinux_state, | 1657 | return avc_has_perm(&selinux_state, |
1828 | sid, isec->sid, isec->sclass, perms, adp); | 1658 | sid, isec->sid, isec->sclass, perms, adp); |
@@ -1888,7 +1718,7 @@ static int file_has_perm(const struct cred *cred, | |||
1888 | struct file *file, | 1718 | struct file *file, |
1889 | u32 av) | 1719 | u32 av) |
1890 | { | 1720 | { |
1891 | struct file_security_struct *fsec = file->f_security; | 1721 | struct file_security_struct *fsec = selinux_file(file); |
1892 | struct inode *inode = file_inode(file); | 1722 | struct inode *inode = file_inode(file); |
1893 | struct common_audit_data ad; | 1723 | struct common_audit_data ad; |
1894 | u32 sid = cred_sid(cred); | 1724 | u32 sid = cred_sid(cred); |
@@ -1954,7 +1784,7 @@ static int may_create(struct inode *dir, | |||
1954 | struct dentry *dentry, | 1784 | struct dentry *dentry, |
1955 | u16 tclass) | 1785 | u16 tclass) |
1956 | { | 1786 | { |
1957 | const struct task_security_struct *tsec = current_security(); | 1787 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
1958 | struct inode_security_struct *dsec; | 1788 | struct inode_security_struct *dsec; |
1959 | struct superblock_security_struct *sbsec; | 1789 | struct superblock_security_struct *sbsec; |
1960 | u32 sid, newsid; | 1790 | u32 sid, newsid; |
@@ -1976,7 +1806,7 @@ static int may_create(struct inode *dir, | |||
1976 | if (rc) | 1806 | if (rc) |
1977 | return rc; | 1807 | return rc; |
1978 | 1808 | ||
1979 | rc = selinux_determine_inode_label(current_security(), dir, | 1809 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir, |
1980 | &dentry->d_name, tclass, &newsid); | 1810 | &dentry->d_name, tclass, &newsid); |
1981 | if (rc) | 1811 | if (rc) |
1982 | return rc; | 1812 | return rc; |
@@ -2232,7 +2062,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2232 | struct file *file) | 2062 | struct file *file) |
2233 | { | 2063 | { |
2234 | u32 sid = task_sid(to); | 2064 | u32 sid = task_sid(to); |
2235 | struct file_security_struct *fsec = file->f_security; | 2065 | struct file_security_struct *fsec = selinux_file(file); |
2236 | struct dentry *dentry = file->f_path.dentry; | 2066 | struct dentry *dentry = file->f_path.dentry; |
2237 | struct inode_security_struct *isec; | 2067 | struct inode_security_struct *isec; |
2238 | struct common_audit_data ad; | 2068 | struct common_audit_data ad; |
@@ -2316,9 +2146,9 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
2316 | */ | 2146 | */ |
2317 | 2147 | ||
2318 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2148 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
2319 | int cap, int audit) | 2149 | int cap, unsigned int opts) |
2320 | { | 2150 | { |
2321 | return cred_has_capability(cred, cap, audit, ns == &init_user_ns); | 2151 | return cred_has_capability(cred, cap, opts, ns == &init_user_ns); |
2322 | } | 2152 | } |
2323 | 2153 | ||
2324 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 2154 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
@@ -2392,7 +2222,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2392 | int rc, cap_sys_admin = 0; | 2222 | int rc, cap_sys_admin = 0; |
2393 | 2223 | ||
2394 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, | 2224 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
2395 | SECURITY_CAP_NOAUDIT, true); | 2225 | CAP_OPT_NOAUDIT, true); |
2396 | if (rc == 0) | 2226 | if (rc == 0) |
2397 | cap_sys_admin = 1; | 2227 | cap_sys_admin = 1; |
2398 | 2228 | ||
@@ -2483,8 +2313,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2483 | if (bprm->called_set_creds) | 2313 | if (bprm->called_set_creds) |
2484 | return 0; | 2314 | return 0; |
2485 | 2315 | ||
2486 | old_tsec = current_security(); | 2316 | old_tsec = selinux_cred(current_cred()); |
2487 | new_tsec = bprm->cred->security; | 2317 | new_tsec = selinux_cred(bprm->cred); |
2488 | isec = inode_security(inode); | 2318 | isec = inode_security(inode); |
2489 | 2319 | ||
2490 | /* Default to the current task SID. */ | 2320 | /* Default to the current task SID. */ |
@@ -2648,7 +2478,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
2648 | struct rlimit *rlim, *initrlim; | 2478 | struct rlimit *rlim, *initrlim; |
2649 | int rc, i; | 2479 | int rc, i; |
2650 | 2480 | ||
2651 | new_tsec = bprm->cred->security; | 2481 | new_tsec = selinux_cred(bprm->cred); |
2652 | if (new_tsec->sid == new_tsec->osid) | 2482 | if (new_tsec->sid == new_tsec->osid) |
2653 | return; | 2483 | return; |
2654 | 2484 | ||
@@ -2691,7 +2521,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) | |||
2691 | */ | 2521 | */ |
2692 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) | 2522 | static void selinux_bprm_committed_creds(struct linux_binprm *bprm) |
2693 | { | 2523 | { |
2694 | const struct task_security_struct *tsec = current_security(); | 2524 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
2695 | struct itimerval itimer; | 2525 | struct itimerval itimer; |
2696 | u32 osid, sid; | 2526 | u32 osid, sid; |
2697 | int rc, i; | 2527 | int rc, i; |
@@ -2747,195 +2577,129 @@ static void selinux_sb_free_security(struct super_block *sb) | |||
2747 | superblock_free_security(sb); | 2577 | superblock_free_security(sb); |
2748 | } | 2578 | } |
2749 | 2579 | ||
2750 | static inline int match_prefix(char *prefix, int plen, char *option, int olen) | 2580 | static inline int opt_len(const char *s) |
2751 | { | ||
2752 | if (plen > olen) | ||
2753 | return 0; | ||
2754 | |||
2755 | return !memcmp(prefix, option, plen); | ||
2756 | } | ||
2757 | |||
2758 | static inline int selinux_option(char *option, int len) | ||
2759 | { | 2581 | { |
2760 | return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || | 2582 | bool open_quote = false; |
2761 | match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || | 2583 | int len; |
2762 | match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || | 2584 | char c; |
2763 | match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) || | ||
2764 | match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len)); | ||
2765 | } | ||
2766 | 2585 | ||
2767 | static inline void take_option(char **to, char *from, int *first, int len) | 2586 | for (len = 0; (c = s[len]) != '\0'; len++) { |
2768 | { | 2587 | if (c == '"') |
2769 | if (!*first) { | 2588 | open_quote = !open_quote; |
2770 | **to = ','; | 2589 | if (c == ',' && !open_quote) |
2771 | *to += 1; | 2590 | break; |
2772 | } else | ||
2773 | *first = 0; | ||
2774 | memcpy(*to, from, len); | ||
2775 | *to += len; | ||
2776 | } | ||
2777 | |||
2778 | static inline void take_selinux_option(char **to, char *from, int *first, | ||
2779 | int len) | ||
2780 | { | ||
2781 | int current_size = 0; | ||
2782 | |||
2783 | if (!*first) { | ||
2784 | **to = '|'; | ||
2785 | *to += 1; | ||
2786 | } else | ||
2787 | *first = 0; | ||
2788 | |||
2789 | while (current_size < len) { | ||
2790 | if (*from != '"') { | ||
2791 | **to = *from; | ||
2792 | *to += 1; | ||
2793 | } | ||
2794 | from += 1; | ||
2795 | current_size += 1; | ||
2796 | } | 2591 | } |
2592 | return len; | ||
2797 | } | 2593 | } |
2798 | 2594 | ||
2799 | static int selinux_sb_copy_data(char *orig, char *copy) | 2595 | static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) |
2800 | { | 2596 | { |
2801 | int fnosec, fsec, rc = 0; | 2597 | char *from = options; |
2802 | char *in_save, *in_curr, *in_end; | 2598 | char *to = options; |
2803 | char *sec_curr, *nosec_save, *nosec; | 2599 | bool first = true; |
2804 | int open_quote = 0; | ||
2805 | 2600 | ||
2806 | in_curr = orig; | 2601 | while (1) { |
2807 | sec_curr = copy; | 2602 | int len = opt_len(from); |
2603 | int token, rc; | ||
2604 | char *arg = NULL; | ||
2808 | 2605 | ||
2809 | nosec = (char *)get_zeroed_page(GFP_KERNEL); | 2606 | token = match_opt_prefix(from, len, &arg); |
2810 | if (!nosec) { | ||
2811 | rc = -ENOMEM; | ||
2812 | goto out; | ||
2813 | } | ||
2814 | |||
2815 | nosec_save = nosec; | ||
2816 | fnosec = fsec = 1; | ||
2817 | in_save = in_end = orig; | ||
2818 | |||
2819 | do { | ||
2820 | if (*in_end == '"') | ||
2821 | open_quote = !open_quote; | ||
2822 | if ((*in_end == ',' && open_quote == 0) || | ||
2823 | *in_end == '\0') { | ||
2824 | int len = in_end - in_curr; | ||
2825 | 2607 | ||
2826 | if (selinux_option(in_curr, len)) | 2608 | if (token != Opt_error) { |
2827 | take_selinux_option(&sec_curr, in_curr, &fsec, len); | 2609 | char *p, *q; |
2828 | else | ||
2829 | take_option(&nosec, in_curr, &fnosec, len); | ||
2830 | 2610 | ||
2831 | in_curr = in_end + 1; | 2611 | /* strip quotes */ |
2612 | if (arg) { | ||
2613 | for (p = q = arg; p < from + len; p++) { | ||
2614 | char c = *p; | ||
2615 | if (c != '"') | ||
2616 | *q++ = c; | ||
2617 | } | ||
2618 | arg = kmemdup_nul(arg, q - arg, GFP_KERNEL); | ||
2619 | } | ||
2620 | rc = selinux_add_opt(token, arg, mnt_opts); | ||
2621 | if (unlikely(rc)) { | ||
2622 | kfree(arg); | ||
2623 | if (*mnt_opts) { | ||
2624 | selinux_free_mnt_opts(*mnt_opts); | ||
2625 | *mnt_opts = NULL; | ||
2626 | } | ||
2627 | return rc; | ||
2628 | } | ||
2629 | } else { | ||
2630 | if (!first) { // copy with preceding comma | ||
2631 | from--; | ||
2632 | len++; | ||
2633 | } | ||
2634 | if (to != from) | ||
2635 | memmove(to, from, len); | ||
2636 | to += len; | ||
2637 | first = false; | ||
2832 | } | 2638 | } |
2833 | } while (*in_end++); | 2639 | if (!from[len]) |
2834 | 2640 | break; | |
2835 | strcpy(in_save, nosec_save); | 2641 | from += len + 1; |
2836 | free_page((unsigned long)nosec_save); | 2642 | } |
2837 | out: | 2643 | *to = '\0'; |
2838 | return rc; | 2644 | return 0; |
2839 | } | 2645 | } |
2840 | 2646 | ||
2841 | static int selinux_sb_remount(struct super_block *sb, void *data) | 2647 | static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) |
2842 | { | 2648 | { |
2843 | int rc, i, *flags; | 2649 | struct selinux_mnt_opts *opts = mnt_opts; |
2844 | struct security_mnt_opts opts; | ||
2845 | char *secdata, **mount_options; | ||
2846 | struct superblock_security_struct *sbsec = sb->s_security; | 2650 | struct superblock_security_struct *sbsec = sb->s_security; |
2651 | u32 sid; | ||
2652 | int rc; | ||
2847 | 2653 | ||
2848 | if (!(sbsec->flags & SE_SBINITIALIZED)) | 2654 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
2849 | return 0; | 2655 | return 0; |
2850 | 2656 | ||
2851 | if (!data) | 2657 | if (!opts) |
2852 | return 0; | ||
2853 | |||
2854 | if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | ||
2855 | return 0; | 2658 | return 0; |
2856 | 2659 | ||
2857 | security_init_mnt_opts(&opts); | 2660 | if (opts->fscontext) { |
2858 | secdata = alloc_secdata(); | 2661 | rc = parse_sid(sb, opts->fscontext, &sid); |
2859 | if (!secdata) | 2662 | if (rc) |
2860 | return -ENOMEM; | 2663 | return rc; |
2861 | rc = selinux_sb_copy_data(data, secdata); | 2664 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) |
2862 | if (rc) | 2665 | goto out_bad_option; |
2863 | goto out_free_secdata; | ||
2864 | |||
2865 | rc = selinux_parse_opts_str(secdata, &opts); | ||
2866 | if (rc) | ||
2867 | goto out_free_secdata; | ||
2868 | |||
2869 | mount_options = opts.mnt_opts; | ||
2870 | flags = opts.mnt_opts_flags; | ||
2871 | |||
2872 | for (i = 0; i < opts.num_mnt_opts; i++) { | ||
2873 | u32 sid; | ||
2874 | |||
2875 | if (flags[i] == SBLABEL_MNT) | ||
2876 | continue; | ||
2877 | rc = security_context_str_to_sid(&selinux_state, | ||
2878 | mount_options[i], &sid, | ||
2879 | GFP_KERNEL); | ||
2880 | if (rc) { | ||
2881 | pr_warn("SELinux: security_context_str_to_sid" | ||
2882 | "(%s) failed for (dev %s, type %s) errno=%d\n", | ||
2883 | mount_options[i], sb->s_id, sb->s_type->name, rc); | ||
2884 | goto out_free_opts; | ||
2885 | } | ||
2886 | rc = -EINVAL; | ||
2887 | switch (flags[i]) { | ||
2888 | case FSCONTEXT_MNT: | ||
2889 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) | ||
2890 | goto out_bad_option; | ||
2891 | break; | ||
2892 | case CONTEXT_MNT: | ||
2893 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) | ||
2894 | goto out_bad_option; | ||
2895 | break; | ||
2896 | case ROOTCONTEXT_MNT: { | ||
2897 | struct inode_security_struct *root_isec; | ||
2898 | root_isec = backing_inode_security(sb->s_root); | ||
2899 | |||
2900 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | ||
2901 | goto out_bad_option; | ||
2902 | break; | ||
2903 | } | ||
2904 | case DEFCONTEXT_MNT: | ||
2905 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) | ||
2906 | goto out_bad_option; | ||
2907 | break; | ||
2908 | default: | ||
2909 | goto out_free_opts; | ||
2910 | } | ||
2911 | } | 2666 | } |
2667 | if (opts->context) { | ||
2668 | rc = parse_sid(sb, opts->context, &sid); | ||
2669 | if (rc) | ||
2670 | return rc; | ||
2671 | if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) | ||
2672 | goto out_bad_option; | ||
2673 | } | ||
2674 | if (opts->rootcontext) { | ||
2675 | struct inode_security_struct *root_isec; | ||
2676 | root_isec = backing_inode_security(sb->s_root); | ||
2677 | rc = parse_sid(sb, opts->rootcontext, &sid); | ||
2678 | if (rc) | ||
2679 | return rc; | ||
2680 | if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) | ||
2681 | goto out_bad_option; | ||
2682 | } | ||
2683 | if (opts->defcontext) { | ||
2684 | rc = parse_sid(sb, opts->defcontext, &sid); | ||
2685 | if (rc) | ||
2686 | return rc; | ||
2687 | if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) | ||
2688 | goto out_bad_option; | ||
2689 | } | ||
2690 | return 0; | ||
2912 | 2691 | ||
2913 | rc = 0; | ||
2914 | out_free_opts: | ||
2915 | security_free_mnt_opts(&opts); | ||
2916 | out_free_secdata: | ||
2917 | free_secdata(secdata); | ||
2918 | return rc; | ||
2919 | out_bad_option: | 2692 | out_bad_option: |
2920 | pr_warn("SELinux: unable to change security options " | 2693 | pr_warn("SELinux: unable to change security options " |
2921 | "during remount (dev %s, type=%s)\n", sb->s_id, | 2694 | "during remount (dev %s, type=%s)\n", sb->s_id, |
2922 | sb->s_type->name); | 2695 | sb->s_type->name); |
2923 | goto out_free_opts; | 2696 | return -EINVAL; |
2924 | } | 2697 | } |
2925 | 2698 | ||
2926 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | 2699 | static int selinux_sb_kern_mount(struct super_block *sb) |
2927 | { | 2700 | { |
2928 | const struct cred *cred = current_cred(); | 2701 | const struct cred *cred = current_cred(); |
2929 | struct common_audit_data ad; | 2702 | struct common_audit_data ad; |
2930 | int rc; | ||
2931 | |||
2932 | rc = superblock_doinit(sb, data); | ||
2933 | if (rc) | ||
2934 | return rc; | ||
2935 | |||
2936 | /* Allow all mounts performed by the kernel */ | ||
2937 | if (flags & MS_KERNMOUNT) | ||
2938 | return 0; | ||
2939 | 2703 | ||
2940 | ad.type = LSM_AUDIT_DATA_DENTRY; | 2704 | ad.type = LSM_AUDIT_DATA_DENTRY; |
2941 | ad.u.dentry = sb->s_root; | 2705 | ad.u.dentry = sb->s_root; |
@@ -2994,7 +2758,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, | |||
2994 | u32 newsid; | 2758 | u32 newsid; |
2995 | int rc; | 2759 | int rc; |
2996 | 2760 | ||
2997 | rc = selinux_determine_inode_label(current_security(), | 2761 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
2998 | d_inode(dentry->d_parent), name, | 2762 | d_inode(dentry->d_parent), name, |
2999 | inode_mode_to_security_class(mode), | 2763 | inode_mode_to_security_class(mode), |
3000 | &newsid); | 2764 | &newsid); |
@@ -3014,14 +2778,14 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, | |||
3014 | int rc; | 2778 | int rc; |
3015 | struct task_security_struct *tsec; | 2779 | struct task_security_struct *tsec; |
3016 | 2780 | ||
3017 | rc = selinux_determine_inode_label(old->security, | 2781 | rc = selinux_determine_inode_label(selinux_cred(old), |
3018 | d_inode(dentry->d_parent), name, | 2782 | d_inode(dentry->d_parent), name, |
3019 | inode_mode_to_security_class(mode), | 2783 | inode_mode_to_security_class(mode), |
3020 | &newsid); | 2784 | &newsid); |
3021 | if (rc) | 2785 | if (rc) |
3022 | return rc; | 2786 | return rc; |
3023 | 2787 | ||
3024 | tsec = new->security; | 2788 | tsec = selinux_cred(new); |
3025 | tsec->create_sid = newsid; | 2789 | tsec->create_sid = newsid; |
3026 | return 0; | 2790 | return 0; |
3027 | } | 2791 | } |
@@ -3031,7 +2795,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
3031 | const char **name, | 2795 | const char **name, |
3032 | void **value, size_t *len) | 2796 | void **value, size_t *len) |
3033 | { | 2797 | { |
3034 | const struct task_security_struct *tsec = current_security(); | 2798 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
3035 | struct superblock_security_struct *sbsec; | 2799 | struct superblock_security_struct *sbsec; |
3036 | u32 newsid, clen; | 2800 | u32 newsid, clen; |
3037 | int rc; | 2801 | int rc; |
@@ -3041,7 +2805,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
3041 | 2805 | ||
3042 | newsid = tsec->create_sid; | 2806 | newsid = tsec->create_sid; |
3043 | 2807 | ||
3044 | rc = selinux_determine_inode_label(current_security(), | 2808 | rc = selinux_determine_inode_label(selinux_cred(current_cred()), |
3045 | dir, qstr, | 2809 | dir, qstr, |
3046 | inode_mode_to_security_class(inode->i_mode), | 2810 | inode_mode_to_security_class(inode->i_mode), |
3047 | &newsid); | 2811 | &newsid); |
@@ -3050,7 +2814,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
3050 | 2814 | ||
3051 | /* Possibly defer initialization to selinux_complete_init. */ | 2815 | /* Possibly defer initialization to selinux_complete_init. */ |
3052 | if (sbsec->flags & SE_SBINITIALIZED) { | 2816 | if (sbsec->flags & SE_SBINITIALIZED) { |
3053 | struct inode_security_struct *isec = inode->i_security; | 2817 | struct inode_security_struct *isec = selinux_inode(inode); |
3054 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 2818 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
3055 | isec->sid = newsid; | 2819 | isec->sid = newsid; |
3056 | isec->initialized = LABEL_INITIALIZED; | 2820 | isec->initialized = LABEL_INITIALIZED; |
@@ -3139,9 +2903,8 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, | |||
3139 | if (IS_ERR(isec)) | 2903 | if (IS_ERR(isec)) |
3140 | return PTR_ERR(isec); | 2904 | return PTR_ERR(isec); |
3141 | 2905 | ||
3142 | return avc_has_perm_flags(&selinux_state, | 2906 | return avc_has_perm(&selinux_state, |
3143 | sid, isec->sid, isec->sclass, FILE__READ, &ad, | 2907 | sid, isec->sid, isec->sclass, FILE__READ, &ad); |
3144 | rcu ? MAY_NOT_BLOCK : 0); | ||
3145 | } | 2908 | } |
3146 | 2909 | ||
3147 | static noinline int audit_inode_permission(struct inode *inode, | 2910 | static noinline int audit_inode_permission(struct inode *inode, |
@@ -3150,7 +2913,7 @@ static noinline int audit_inode_permission(struct inode *inode, | |||
3150 | unsigned flags) | 2913 | unsigned flags) |
3151 | { | 2914 | { |
3152 | struct common_audit_data ad; | 2915 | struct common_audit_data ad; |
3153 | struct inode_security_struct *isec = inode->i_security; | 2916 | struct inode_security_struct *isec = selinux_inode(inode); |
3154 | int rc; | 2917 | int rc; |
3155 | 2918 | ||
3156 | ad.type = LSM_AUDIT_DATA_INODE; | 2919 | ad.type = LSM_AUDIT_DATA_INODE; |
@@ -3196,7 +2959,9 @@ static int selinux_inode_permission(struct inode *inode, int mask) | |||
3196 | return PTR_ERR(isec); | 2959 | return PTR_ERR(isec); |
3197 | 2960 | ||
3198 | rc = avc_has_perm_noaudit(&selinux_state, | 2961 | rc = avc_has_perm_noaudit(&selinux_state, |
3199 | sid, isec->sid, isec->sclass, perms, 0, &avd); | 2962 | sid, isec->sid, isec->sclass, perms, |
2963 | (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, | ||
2964 | &avd); | ||
3200 | audited = avc_audit_required(perms, &avd, rc, | 2965 | audited = avc_audit_required(perms, &avd, rc, |
3201 | from_access ? FILE__AUDIT_ACCESS : 0, | 2966 | from_access ? FILE__AUDIT_ACCESS : 0, |
3202 | &denied); | 2967 | &denied); |
@@ -3245,11 +3010,11 @@ static int selinux_inode_getattr(const struct path *path) | |||
3245 | static bool has_cap_mac_admin(bool audit) | 3010 | static bool has_cap_mac_admin(bool audit) |
3246 | { | 3011 | { |
3247 | const struct cred *cred = current_cred(); | 3012 | const struct cred *cred = current_cred(); |
3248 | int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT; | 3013 | unsigned int opts = audit ? CAP_OPT_NONE : CAP_OPT_NOAUDIT; |
3249 | 3014 | ||
3250 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit)) | 3015 | if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts)) |
3251 | return false; | 3016 | return false; |
3252 | if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true)) | 3017 | if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true)) |
3253 | return false; | 3018 | return false; |
3254 | return true; | 3019 | return true; |
3255 | } | 3020 | } |
@@ -3455,12 +3220,16 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3455 | const void *value, size_t size, int flags) | 3220 | const void *value, size_t size, int flags) |
3456 | { | 3221 | { |
3457 | struct inode_security_struct *isec = inode_security_novalidate(inode); | 3222 | struct inode_security_struct *isec = inode_security_novalidate(inode); |
3223 | struct superblock_security_struct *sbsec = inode->i_sb->s_security; | ||
3458 | u32 newsid; | 3224 | u32 newsid; |
3459 | int rc; | 3225 | int rc; |
3460 | 3226 | ||
3461 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 3227 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
3462 | return -EOPNOTSUPP; | 3228 | return -EOPNOTSUPP; |
3463 | 3229 | ||
3230 | if (!(sbsec->flags & SBLABEL_MNT)) | ||
3231 | return -EOPNOTSUPP; | ||
3232 | |||
3464 | if (!value || !size) | 3233 | if (!value || !size) |
3465 | return -EACCES; | 3234 | return -EACCES; |
3466 | 3235 | ||
@@ -3503,7 +3272,7 @@ static int selinux_inode_copy_up(struct dentry *src, struct cred **new) | |||
3503 | return -ENOMEM; | 3272 | return -ENOMEM; |
3504 | } | 3273 | } |
3505 | 3274 | ||
3506 | tsec = new_creds->security; | 3275 | tsec = selinux_cred(new_creds); |
3507 | /* Get label from overlay inode and set it in create_sid */ | 3276 | /* Get label from overlay inode and set it in create_sid */ |
3508 | selinux_inode_getsecid(d_inode(src), &sid); | 3277 | selinux_inode_getsecid(d_inode(src), &sid); |
3509 | tsec->create_sid = sid; | 3278 | tsec->create_sid = sid; |
@@ -3544,7 +3313,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
3544 | static int selinux_file_permission(struct file *file, int mask) | 3313 | static int selinux_file_permission(struct file *file, int mask) |
3545 | { | 3314 | { |
3546 | struct inode *inode = file_inode(file); | 3315 | struct inode *inode = file_inode(file); |
3547 | struct file_security_struct *fsec = file->f_security; | 3316 | struct file_security_struct *fsec = selinux_file(file); |
3548 | struct inode_security_struct *isec; | 3317 | struct inode_security_struct *isec; |
3549 | u32 sid = current_sid(); | 3318 | u32 sid = current_sid(); |
3550 | 3319 | ||
@@ -3566,11 +3335,6 @@ static int selinux_file_alloc_security(struct file *file) | |||
3566 | return file_alloc_security(file); | 3335 | return file_alloc_security(file); |
3567 | } | 3336 | } |
3568 | 3337 | ||
3569 | static void selinux_file_free_security(struct file *file) | ||
3570 | { | ||
3571 | file_free_security(file); | ||
3572 | } | ||
3573 | |||
3574 | /* | 3338 | /* |
3575 | * Check whether a task has the ioctl permission and cmd | 3339 | * Check whether a task has the ioctl permission and cmd |
3576 | * operation to an inode. | 3340 | * operation to an inode. |
@@ -3579,7 +3343,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
3579 | u32 requested, u16 cmd) | 3343 | u32 requested, u16 cmd) |
3580 | { | 3344 | { |
3581 | struct common_audit_data ad; | 3345 | struct common_audit_data ad; |
3582 | struct file_security_struct *fsec = file->f_security; | 3346 | struct file_security_struct *fsec = selinux_file(file); |
3583 | struct inode *inode = file_inode(file); | 3347 | struct inode *inode = file_inode(file); |
3584 | struct inode_security_struct *isec; | 3348 | struct inode_security_struct *isec; |
3585 | struct lsm_ioctlop_audit ioctl; | 3349 | struct lsm_ioctlop_audit ioctl; |
@@ -3649,7 +3413,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
3649 | case KDSKBENT: | 3413 | case KDSKBENT: |
3650 | case KDSKBSENT: | 3414 | case KDSKBSENT: |
3651 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, | 3415 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
3652 | SECURITY_CAP_AUDIT, true); | 3416 | CAP_OPT_NONE, true); |
3653 | break; | 3417 | break; |
3654 | 3418 | ||
3655 | /* default case assumes that the command will go | 3419 | /* default case assumes that the command will go |
@@ -3831,7 +3595,7 @@ static void selinux_file_set_fowner(struct file *file) | |||
3831 | { | 3595 | { |
3832 | struct file_security_struct *fsec; | 3596 | struct file_security_struct *fsec; |
3833 | 3597 | ||
3834 | fsec = file->f_security; | 3598 | fsec = selinux_file(file); |
3835 | fsec->fown_sid = current_sid(); | 3599 | fsec->fown_sid = current_sid(); |
3836 | } | 3600 | } |
3837 | 3601 | ||
@@ -3846,7 +3610,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, | |||
3846 | /* struct fown_struct is never outside the context of a struct file */ | 3610 | /* struct fown_struct is never outside the context of a struct file */ |
3847 | file = container_of(fown, struct file, f_owner); | 3611 | file = container_of(fown, struct file, f_owner); |
3848 | 3612 | ||
3849 | fsec = file->f_security; | 3613 | fsec = selinux_file(file); |
3850 | 3614 | ||
3851 | if (!signum) | 3615 | if (!signum) |
3852 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ | 3616 | perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ |
@@ -3870,7 +3634,7 @@ static int selinux_file_open(struct file *file) | |||
3870 | struct file_security_struct *fsec; | 3634 | struct file_security_struct *fsec; |
3871 | struct inode_security_struct *isec; | 3635 | struct inode_security_struct *isec; |
3872 | 3636 | ||
3873 | fsec = file->f_security; | 3637 | fsec = selinux_file(file); |
3874 | isec = inode_security(file_inode(file)); | 3638 | isec = inode_security(file_inode(file)); |
3875 | /* | 3639 | /* |
3876 | * Save inode label and policy sequence number | 3640 | * Save inode label and policy sequence number |
@@ -3904,52 +3668,15 @@ static int selinux_task_alloc(struct task_struct *task, | |||
3904 | } | 3668 | } |
3905 | 3669 | ||
3906 | /* | 3670 | /* |
3907 | * allocate the SELinux part of blank credentials | ||
3908 | */ | ||
3909 | static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) | ||
3910 | { | ||
3911 | struct task_security_struct *tsec; | ||
3912 | |||
3913 | tsec = kzalloc(sizeof(struct task_security_struct), gfp); | ||
3914 | if (!tsec) | ||
3915 | return -ENOMEM; | ||
3916 | |||
3917 | cred->security = tsec; | ||
3918 | return 0; | ||
3919 | } | ||
3920 | |||
3921 | /* | ||
3922 | * detach and free the LSM part of a set of credentials | ||
3923 | */ | ||
3924 | static void selinux_cred_free(struct cred *cred) | ||
3925 | { | ||
3926 | struct task_security_struct *tsec = cred->security; | ||
3927 | |||
3928 | /* | ||
3929 | * cred->security == NULL if security_cred_alloc_blank() or | ||
3930 | * security_prepare_creds() returned an error. | ||
3931 | */ | ||
3932 | BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); | ||
3933 | cred->security = (void *) 0x7UL; | ||
3934 | kfree(tsec); | ||
3935 | } | ||
3936 | |||
3937 | /* | ||
3938 | * prepare a new set of credentials for modification | 3671 | * prepare a new set of credentials for modification |
3939 | */ | 3672 | */ |
3940 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, | 3673 | static int selinux_cred_prepare(struct cred *new, const struct cred *old, |
3941 | gfp_t gfp) | 3674 | gfp_t gfp) |
3942 | { | 3675 | { |
3943 | const struct task_security_struct *old_tsec; | 3676 | const struct task_security_struct *old_tsec = selinux_cred(old); |
3944 | struct task_security_struct *tsec; | 3677 | struct task_security_struct *tsec = selinux_cred(new); |
3945 | 3678 | ||
3946 | old_tsec = old->security; | 3679 | *tsec = *old_tsec; |
3947 | |||
3948 | tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp); | ||
3949 | if (!tsec) | ||
3950 | return -ENOMEM; | ||
3951 | |||
3952 | new->security = tsec; | ||
3953 | return 0; | 3680 | return 0; |
3954 | } | 3681 | } |
3955 | 3682 | ||
@@ -3958,8 +3685,8 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, | |||
3958 | */ | 3685 | */ |
3959 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) | 3686 | static void selinux_cred_transfer(struct cred *new, const struct cred *old) |
3960 | { | 3687 | { |
3961 | const struct task_security_struct *old_tsec = old->security; | 3688 | const struct task_security_struct *old_tsec = selinux_cred(old); |
3962 | struct task_security_struct *tsec = new->security; | 3689 | struct task_security_struct *tsec = selinux_cred(new); |
3963 | 3690 | ||
3964 | *tsec = *old_tsec; | 3691 | *tsec = *old_tsec; |
3965 | } | 3692 | } |
@@ -3975,7 +3702,7 @@ static void selinux_cred_getsecid(const struct cred *c, u32 *secid) | |||
3975 | */ | 3702 | */ |
3976 | static int selinux_kernel_act_as(struct cred *new, u32 secid) | 3703 | static int selinux_kernel_act_as(struct cred *new, u32 secid) |
3977 | { | 3704 | { |
3978 | struct task_security_struct *tsec = new->security; | 3705 | struct task_security_struct *tsec = selinux_cred(new); |
3979 | u32 sid = current_sid(); | 3706 | u32 sid = current_sid(); |
3980 | int ret; | 3707 | int ret; |
3981 | 3708 | ||
@@ -4000,7 +3727,7 @@ static int selinux_kernel_act_as(struct cred *new, u32 secid) | |||
4000 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | 3727 | static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) |
4001 | { | 3728 | { |
4002 | struct inode_security_struct *isec = inode_security(inode); | 3729 | struct inode_security_struct *isec = inode_security(inode); |
4003 | struct task_security_struct *tsec = new->security; | 3730 | struct task_security_struct *tsec = selinux_cred(new); |
4004 | u32 sid = current_sid(); | 3731 | u32 sid = current_sid(); |
4005 | int ret; | 3732 | int ret; |
4006 | 3733 | ||
@@ -4046,7 +3773,7 @@ static int selinux_kernel_module_from_file(struct file *file) | |||
4046 | ad.type = LSM_AUDIT_DATA_FILE; | 3773 | ad.type = LSM_AUDIT_DATA_FILE; |
4047 | ad.u.file = file; | 3774 | ad.u.file = file; |
4048 | 3775 | ||
4049 | fsec = file->f_security; | 3776 | fsec = selinux_file(file); |
4050 | if (sid != fsec->sid) { | 3777 | if (sid != fsec->sid) { |
4051 | rc = avc_has_perm(&selinux_state, | 3778 | rc = avc_has_perm(&selinux_state, |
4052 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); | 3779 | sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); |
@@ -4212,7 +3939,7 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info, | |||
4212 | static void selinux_task_to_inode(struct task_struct *p, | 3939 | static void selinux_task_to_inode(struct task_struct *p, |
4213 | struct inode *inode) | 3940 | struct inode *inode) |
4214 | { | 3941 | { |
4215 | struct inode_security_struct *isec = inode->i_security; | 3942 | struct inode_security_struct *isec = selinux_inode(inode); |
4216 | u32 sid = task_sid(p); | 3943 | u32 sid = task_sid(p); |
4217 | 3944 | ||
4218 | spin_lock(&isec->lock); | 3945 | spin_lock(&isec->lock); |
@@ -4549,7 +4276,7 @@ static int sock_has_perm(struct sock *sk, u32 perms) | |||
4549 | static int selinux_socket_create(int family, int type, | 4276 | static int selinux_socket_create(int family, int type, |
4550 | int protocol, int kern) | 4277 | int protocol, int kern) |
4551 | { | 4278 | { |
4552 | const struct task_security_struct *tsec = current_security(); | 4279 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
4553 | u32 newsid; | 4280 | u32 newsid; |
4554 | u16 secclass; | 4281 | u16 secclass; |
4555 | int rc; | 4282 | int rc; |
@@ -4569,7 +4296,7 @@ static int selinux_socket_create(int family, int type, | |||
4569 | static int selinux_socket_post_create(struct socket *sock, int family, | 4296 | static int selinux_socket_post_create(struct socket *sock, int family, |
4570 | int type, int protocol, int kern) | 4297 | int type, int protocol, int kern) |
4571 | { | 4298 | { |
4572 | const struct task_security_struct *tsec = current_security(); | 4299 | const struct task_security_struct *tsec = selinux_cred(current_cred()); |
4573 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); | 4300 | struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock)); |
4574 | struct sk_security_struct *sksec; | 4301 | struct sk_security_struct *sksec; |
4575 | u16 sclass = socket_type_to_security_class(family, type, protocol); | 4302 | u16 sclass = socket_type_to_security_class(family, type, protocol); |
@@ -5318,6 +5045,9 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
5318 | addr_buf = address; | 5045 | addr_buf = address; |
5319 | 5046 | ||
5320 | while (walk_size < addrlen) { | 5047 | while (walk_size < addrlen) { |
5048 | if (walk_size + sizeof(sa_family_t) > addrlen) | ||
5049 | return -EINVAL; | ||
5050 | |||
5321 | addr = addr_buf; | 5051 | addr = addr_buf; |
5322 | switch (addr->sa_family) { | 5052 | switch (addr->sa_family) { |
5323 | case AF_UNSPEC: | 5053 | case AF_UNSPEC: |
@@ -5447,7 +5177,7 @@ static int selinux_secmark_relabel_packet(u32 sid) | |||
5447 | const struct task_security_struct *__tsec; | 5177 | const struct task_security_struct *__tsec; |
5448 | u32 tsid; | 5178 | u32 tsid; |
5449 | 5179 | ||
5450 | __tsec = current_security(); | 5180 | __tsec = selinux_cred(current_cred()); |
5451 | tsid = __tsec->sid; | 5181 | tsid = __tsec->sid; |
5452 | 5182 | ||
5453 | return avc_has_perm(&selinux_state, | 5183 | return avc_has_perm(&selinux_state, |
@@ -5922,51 +5652,22 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
5922 | return selinux_nlmsg_perm(sk, skb); | 5652 | return selinux_nlmsg_perm(sk, skb); |
5923 | } | 5653 | } |
5924 | 5654 | ||
5925 | static int ipc_alloc_security(struct kern_ipc_perm *perm, | 5655 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
5926 | u16 sclass) | ||
5927 | { | 5656 | { |
5928 | struct ipc_security_struct *isec; | ||
5929 | |||
5930 | isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); | ||
5931 | if (!isec) | ||
5932 | return -ENOMEM; | ||
5933 | |||
5934 | isec->sclass = sclass; | 5657 | isec->sclass = sclass; |
5935 | isec->sid = current_sid(); | 5658 | isec->sid = current_sid(); |
5936 | perm->security = isec; | ||
5937 | |||
5938 | return 0; | ||
5939 | } | ||
5940 | |||
5941 | static void ipc_free_security(struct kern_ipc_perm *perm) | ||
5942 | { | ||
5943 | struct ipc_security_struct *isec = perm->security; | ||
5944 | perm->security = NULL; | ||
5945 | kfree(isec); | ||
5946 | } | 5659 | } |
5947 | 5660 | ||
5948 | static int msg_msg_alloc_security(struct msg_msg *msg) | 5661 | static int msg_msg_alloc_security(struct msg_msg *msg) |
5949 | { | 5662 | { |
5950 | struct msg_security_struct *msec; | 5663 | struct msg_security_struct *msec; |
5951 | 5664 | ||
5952 | msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); | 5665 | msec = selinux_msg_msg(msg); |
5953 | if (!msec) | ||
5954 | return -ENOMEM; | ||
5955 | |||
5956 | msec->sid = SECINITSID_UNLABELED; | 5666 | msec->sid = SECINITSID_UNLABELED; |
5957 | msg->security = msec; | ||
5958 | 5667 | ||
5959 | return 0; | 5668 | return 0; |
5960 | } | 5669 | } |
5961 | 5670 | ||
5962 | static void msg_msg_free_security(struct msg_msg *msg) | ||
5963 | { | ||
5964 | struct msg_security_struct *msec = msg->security; | ||
5965 | |||
5966 | msg->security = NULL; | ||
5967 | kfree(msec); | ||
5968 | } | ||
5969 | |||
5970 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | 5671 | static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, |
5971 | u32 perms) | 5672 | u32 perms) |
5972 | { | 5673 | { |
@@ -5974,7 +5675,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
5974 | struct common_audit_data ad; | 5675 | struct common_audit_data ad; |
5975 | u32 sid = current_sid(); | 5676 | u32 sid = current_sid(); |
5976 | 5677 | ||
5977 | isec = ipc_perms->security; | 5678 | isec = selinux_ipc(ipc_perms); |
5978 | 5679 | ||
5979 | ad.type = LSM_AUDIT_DATA_IPC; | 5680 | ad.type = LSM_AUDIT_DATA_IPC; |
5980 | ad.u.ipc_id = ipc_perms->key; | 5681 | ad.u.ipc_id = ipc_perms->key; |
@@ -5988,11 +5689,6 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg) | |||
5988 | return msg_msg_alloc_security(msg); | 5689 | return msg_msg_alloc_security(msg); |
5989 | } | 5690 | } |
5990 | 5691 | ||
5991 | static void selinux_msg_msg_free_security(struct msg_msg *msg) | ||
5992 | { | ||
5993 | msg_msg_free_security(msg); | ||
5994 | } | ||
5995 | |||
5996 | /* message queue security operations */ | 5692 | /* message queue security operations */ |
5997 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | 5693 | static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) |
5998 | { | 5694 | { |
@@ -6001,11 +5697,8 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
6001 | u32 sid = current_sid(); | 5697 | u32 sid = current_sid(); |
6002 | int rc; | 5698 | int rc; |
6003 | 5699 | ||
6004 | rc = ipc_alloc_security(msq, SECCLASS_MSGQ); | 5700 | isec = selinux_ipc(msq); |
6005 | if (rc) | 5701 | ipc_init_security(isec, SECCLASS_MSGQ); |
6006 | return rc; | ||
6007 | |||
6008 | isec = msq->security; | ||
6009 | 5702 | ||
6010 | ad.type = LSM_AUDIT_DATA_IPC; | 5703 | ad.type = LSM_AUDIT_DATA_IPC; |
6011 | ad.u.ipc_id = msq->key; | 5704 | ad.u.ipc_id = msq->key; |
@@ -6013,16 +5706,7 @@ static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) | |||
6013 | rc = avc_has_perm(&selinux_state, | 5706 | rc = avc_has_perm(&selinux_state, |
6014 | sid, isec->sid, SECCLASS_MSGQ, | 5707 | sid, isec->sid, SECCLASS_MSGQ, |
6015 | MSGQ__CREATE, &ad); | 5708 | MSGQ__CREATE, &ad); |
6016 | if (rc) { | 5709 | return rc; |
6017 | ipc_free_security(msq); | ||
6018 | return rc; | ||
6019 | } | ||
6020 | return 0; | ||
6021 | } | ||
6022 | |||
6023 | static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) | ||
6024 | { | ||
6025 | ipc_free_security(msq); | ||
6026 | } | 5710 | } |
6027 | 5711 | ||
6028 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | 5712 | static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) |
@@ -6031,7 +5715,7 @@ static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) | |||
6031 | struct common_audit_data ad; | 5715 | struct common_audit_data ad; |
6032 | u32 sid = current_sid(); | 5716 | u32 sid = current_sid(); |
6033 | 5717 | ||
6034 | isec = msq->security; | 5718 | isec = selinux_ipc(msq); |
6035 | 5719 | ||
6036 | ad.type = LSM_AUDIT_DATA_IPC; | 5720 | ad.type = LSM_AUDIT_DATA_IPC; |
6037 | ad.u.ipc_id = msq->key; | 5721 | ad.u.ipc_id = msq->key; |
@@ -6080,8 +5764,8 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m | |||
6080 | u32 sid = current_sid(); | 5764 | u32 sid = current_sid(); |
6081 | int rc; | 5765 | int rc; |
6082 | 5766 | ||
6083 | isec = msq->security; | 5767 | isec = selinux_ipc(msq); |
6084 | msec = msg->security; | 5768 | msec = selinux_msg_msg(msg); |
6085 | 5769 | ||
6086 | /* | 5770 | /* |
6087 | * First time through, need to assign label to the message | 5771 | * First time through, need to assign label to the message |
@@ -6128,8 +5812,8 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m | |||
6128 | u32 sid = task_sid(target); | 5812 | u32 sid = task_sid(target); |
6129 | int rc; | 5813 | int rc; |
6130 | 5814 | ||
6131 | isec = msq->security; | 5815 | isec = selinux_ipc(msq); |
6132 | msec = msg->security; | 5816 | msec = selinux_msg_msg(msg); |
6133 | 5817 | ||
6134 | ad.type = LSM_AUDIT_DATA_IPC; | 5818 | ad.type = LSM_AUDIT_DATA_IPC; |
6135 | ad.u.ipc_id = msq->key; | 5819 | ad.u.ipc_id = msq->key; |
@@ -6152,11 +5836,8 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
6152 | u32 sid = current_sid(); | 5836 | u32 sid = current_sid(); |
6153 | int rc; | 5837 | int rc; |
6154 | 5838 | ||
6155 | rc = ipc_alloc_security(shp, SECCLASS_SHM); | 5839 | isec = selinux_ipc(shp); |
6156 | if (rc) | 5840 | ipc_init_security(isec, SECCLASS_SHM); |
6157 | return rc; | ||
6158 | |||
6159 | isec = shp->security; | ||
6160 | 5841 | ||
6161 | ad.type = LSM_AUDIT_DATA_IPC; | 5842 | ad.type = LSM_AUDIT_DATA_IPC; |
6162 | ad.u.ipc_id = shp->key; | 5843 | ad.u.ipc_id = shp->key; |
@@ -6164,16 +5845,7 @@ static int selinux_shm_alloc_security(struct kern_ipc_perm *shp) | |||
6164 | rc = avc_has_perm(&selinux_state, | 5845 | rc = avc_has_perm(&selinux_state, |
6165 | sid, isec->sid, SECCLASS_SHM, | 5846 | sid, isec->sid, SECCLASS_SHM, |
6166 | SHM__CREATE, &ad); | 5847 | SHM__CREATE, &ad); |
6167 | if (rc) { | 5848 | return rc; |
6168 | ipc_free_security(shp); | ||
6169 | return rc; | ||
6170 | } | ||
6171 | return 0; | ||
6172 | } | ||
6173 | |||
6174 | static void selinux_shm_free_security(struct kern_ipc_perm *shp) | ||
6175 | { | ||
6176 | ipc_free_security(shp); | ||
6177 | } | 5849 | } |
6178 | 5850 | ||
6179 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | 5851 | static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) |
@@ -6182,7 +5854,7 @@ static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) | |||
6182 | struct common_audit_data ad; | 5854 | struct common_audit_data ad; |
6183 | u32 sid = current_sid(); | 5855 | u32 sid = current_sid(); |
6184 | 5856 | ||
6185 | isec = shp->security; | 5857 | isec = selinux_ipc(shp); |
6186 | 5858 | ||
6187 | ad.type = LSM_AUDIT_DATA_IPC; | 5859 | ad.type = LSM_AUDIT_DATA_IPC; |
6188 | ad.u.ipc_id = shp->key; | 5860 | ad.u.ipc_id = shp->key; |
@@ -6249,11 +5921,8 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
6249 | u32 sid = current_sid(); | 5921 | u32 sid = current_sid(); |
6250 | int rc; | 5922 | int rc; |
6251 | 5923 | ||
6252 | rc = ipc_alloc_security(sma, SECCLASS_SEM); | 5924 | isec = selinux_ipc(sma); |
6253 | if (rc) | 5925 | ipc_init_security(isec, SECCLASS_SEM); |
6254 | return rc; | ||
6255 | |||
6256 | isec = sma->security; | ||
6257 | 5926 | ||
6258 | ad.type = LSM_AUDIT_DATA_IPC; | 5927 | ad.type = LSM_AUDIT_DATA_IPC; |
6259 | ad.u.ipc_id = sma->key; | 5928 | ad.u.ipc_id = sma->key; |
@@ -6261,16 +5930,7 @@ static int selinux_sem_alloc_security(struct kern_ipc_perm *sma) | |||
6261 | rc = avc_has_perm(&selinux_state, | 5930 | rc = avc_has_perm(&selinux_state, |
6262 | sid, isec->sid, SECCLASS_SEM, | 5931 | sid, isec->sid, SECCLASS_SEM, |
6263 | SEM__CREATE, &ad); | 5932 | SEM__CREATE, &ad); |
6264 | if (rc) { | 5933 | return rc; |
6265 | ipc_free_security(sma); | ||
6266 | return rc; | ||
6267 | } | ||
6268 | return 0; | ||
6269 | } | ||
6270 | |||
6271 | static void selinux_sem_free_security(struct kern_ipc_perm *sma) | ||
6272 | { | ||
6273 | ipc_free_security(sma); | ||
6274 | } | 5934 | } |
6275 | 5935 | ||
6276 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | 5936 | static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) |
@@ -6279,7 +5939,7 @@ static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) | |||
6279 | struct common_audit_data ad; | 5939 | struct common_audit_data ad; |
6280 | u32 sid = current_sid(); | 5940 | u32 sid = current_sid(); |
6281 | 5941 | ||
6282 | isec = sma->security; | 5942 | isec = selinux_ipc(sma); |
6283 | 5943 | ||
6284 | ad.type = LSM_AUDIT_DATA_IPC; | 5944 | ad.type = LSM_AUDIT_DATA_IPC; |
6285 | ad.u.ipc_id = sma->key; | 5945 | ad.u.ipc_id = sma->key; |
@@ -6365,7 +6025,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
6365 | 6025 | ||
6366 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | 6026 | static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) |
6367 | { | 6027 | { |
6368 | struct ipc_security_struct *isec = ipcp->security; | 6028 | struct ipc_security_struct *isec = selinux_ipc(ipcp); |
6369 | *secid = isec->sid; | 6029 | *secid = isec->sid; |
6370 | } | 6030 | } |
6371 | 6031 | ||
@@ -6384,7 +6044,7 @@ static int selinux_getprocattr(struct task_struct *p, | |||
6384 | unsigned len; | 6044 | unsigned len; |
6385 | 6045 | ||
6386 | rcu_read_lock(); | 6046 | rcu_read_lock(); |
6387 | __tsec = __task_cred(p)->security; | 6047 | __tsec = selinux_cred(__task_cred(p)); |
6388 | 6048 | ||
6389 | if (current != p) { | 6049 | if (current != p) { |
6390 | error = avc_has_perm(&selinux_state, | 6050 | error = avc_has_perm(&selinux_state, |
@@ -6507,7 +6167,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
6507 | operation. See selinux_bprm_set_creds for the execve | 6167 | operation. See selinux_bprm_set_creds for the execve |
6508 | checks and may_create for the file creation checks. The | 6168 | checks and may_create for the file creation checks. The |
6509 | operation will then fail if the context is not permitted. */ | 6169 | operation will then fail if the context is not permitted. */ |
6510 | tsec = new->security; | 6170 | tsec = selinux_cred(new); |
6511 | if (!strcmp(name, "exec")) { | 6171 | if (!strcmp(name, "exec")) { |
6512 | tsec->exec_sid = sid; | 6172 | tsec->exec_sid = sid; |
6513 | } else if (!strcmp(name, "fscreate")) { | 6173 | } else if (!strcmp(name, "fscreate")) { |
@@ -6591,7 +6251,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen) | |||
6591 | 6251 | ||
6592 | static void selinux_inode_invalidate_secctx(struct inode *inode) | 6252 | static void selinux_inode_invalidate_secctx(struct inode *inode) |
6593 | { | 6253 | { |
6594 | struct inode_security_struct *isec = inode->i_security; | 6254 | struct inode_security_struct *isec = selinux_inode(inode); |
6595 | 6255 | ||
6596 | spin_lock(&isec->lock); | 6256 | spin_lock(&isec->lock); |
6597 | isec->initialized = LABEL_INVALID; | 6257 | isec->initialized = LABEL_INVALID; |
@@ -6603,7 +6263,10 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) | |||
6603 | */ | 6263 | */ |
6604 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 6264 | static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
6605 | { | 6265 | { |
6606 | return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); | 6266 | int rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, |
6267 | ctx, ctxlen, 0); | ||
6268 | /* Do not return error when suppressing label (SBLABEL_MNT not set). */ | ||
6269 | return rc == -EOPNOTSUPP ? 0 : rc; | ||
6607 | } | 6270 | } |
6608 | 6271 | ||
6609 | /* | 6272 | /* |
@@ -6636,7 +6299,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, | |||
6636 | if (!ksec) | 6299 | if (!ksec) |
6637 | return -ENOMEM; | 6300 | return -ENOMEM; |
6638 | 6301 | ||
6639 | tsec = cred->security; | 6302 | tsec = selinux_cred(cred); |
6640 | if (tsec->keycreate_sid) | 6303 | if (tsec->keycreate_sid) |
6641 | ksec->sid = tsec->keycreate_sid; | 6304 | ksec->sid = tsec->keycreate_sid; |
6642 | else | 6305 | else |
@@ -6899,6 +6562,14 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) | |||
6899 | } | 6562 | } |
6900 | #endif | 6563 | #endif |
6901 | 6564 | ||
6565 | struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { | ||
6566 | .lbs_cred = sizeof(struct task_security_struct), | ||
6567 | .lbs_file = sizeof(struct file_security_struct), | ||
6568 | .lbs_inode = sizeof(struct inode_security_struct), | ||
6569 | .lbs_ipc = sizeof(struct ipc_security_struct), | ||
6570 | .lbs_msg_msg = sizeof(struct msg_security_struct), | ||
6571 | }; | ||
6572 | |||
6902 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | 6573 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { |
6903 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), | 6574 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
6904 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | 6575 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), |
@@ -6923,7 +6594,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6923 | 6594 | ||
6924 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), | 6595 | LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), |
6925 | LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), | 6596 | LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), |
6926 | LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data), | 6597 | LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), |
6598 | LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts), | ||
6927 | LSM_HOOK_INIT(sb_remount, selinux_sb_remount), | 6599 | LSM_HOOK_INIT(sb_remount, selinux_sb_remount), |
6928 | LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), | 6600 | LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), |
6929 | LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), | 6601 | LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), |
@@ -6932,7 +6604,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6932 | LSM_HOOK_INIT(sb_umount, selinux_umount), | 6604 | LSM_HOOK_INIT(sb_umount, selinux_umount), |
6933 | LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts), | 6605 | LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts), |
6934 | LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts), | 6606 | LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts), |
6935 | LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str), | 6607 | LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt), |
6936 | 6608 | ||
6937 | LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security), | 6609 | LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security), |
6938 | LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as), | 6610 | LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as), |
@@ -6967,7 +6639,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6967 | 6639 | ||
6968 | LSM_HOOK_INIT(file_permission, selinux_file_permission), | 6640 | LSM_HOOK_INIT(file_permission, selinux_file_permission), |
6969 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), | 6641 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), |
6970 | LSM_HOOK_INIT(file_free_security, selinux_file_free_security), | ||
6971 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), | 6642 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), |
6972 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), | 6643 | LSM_HOOK_INIT(mmap_file, selinux_mmap_file), |
6973 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), | 6644 | LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), |
@@ -6981,8 +6652,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6981 | LSM_HOOK_INIT(file_open, selinux_file_open), | 6652 | LSM_HOOK_INIT(file_open, selinux_file_open), |
6982 | 6653 | ||
6983 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), | 6654 | LSM_HOOK_INIT(task_alloc, selinux_task_alloc), |
6984 | LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), | ||
6985 | LSM_HOOK_INIT(cred_free, selinux_cred_free), | ||
6986 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), | 6655 | LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), |
6987 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), | 6656 | LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer), |
6988 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), | 6657 | LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid), |
@@ -7010,24 +6679,20 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
7010 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), | 6679 | LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), |
7011 | 6680 | ||
7012 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), | 6681 | LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), |
7013 | LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), | ||
7014 | 6682 | ||
7015 | LSM_HOOK_INIT(msg_queue_alloc_security, | 6683 | LSM_HOOK_INIT(msg_queue_alloc_security, |
7016 | selinux_msg_queue_alloc_security), | 6684 | selinux_msg_queue_alloc_security), |
7017 | LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), | ||
7018 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), | 6685 | LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), |
7019 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), | 6686 | LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), |
7020 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), | 6687 | LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), |
7021 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), | 6688 | LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), |
7022 | 6689 | ||
7023 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), | 6690 | LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), |
7024 | LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), | ||
7025 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), | 6691 | LSM_HOOK_INIT(shm_associate, selinux_shm_associate), |
7026 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), | 6692 | LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), |
7027 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), | 6693 | LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), |
7028 | 6694 | ||
7029 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), | 6695 | LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), |
7030 | LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), | ||
7031 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), | 6696 | LSM_HOOK_INIT(sem_associate, selinux_sem_associate), |
7032 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), | 6697 | LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), |
7033 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), | 6698 | LSM_HOOK_INIT(sem_semop, selinux_sem_semop), |
@@ -7138,16 +6803,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
7138 | 6803 | ||
7139 | static __init int selinux_init(void) | 6804 | static __init int selinux_init(void) |
7140 | { | 6805 | { |
7141 | if (!security_module_enable("selinux")) { | ||
7142 | selinux_enabled = 0; | ||
7143 | return 0; | ||
7144 | } | ||
7145 | |||
7146 | if (!selinux_enabled) { | ||
7147 | pr_info("SELinux: Disabled at boot.\n"); | ||
7148 | return 0; | ||
7149 | } | ||
7150 | |||
7151 | pr_info("SELinux: Initializing.\n"); | 6806 | pr_info("SELinux: Initializing.\n"); |
7152 | 6807 | ||
7153 | memset(&selinux_state, 0, sizeof(selinux_state)); | 6808 | memset(&selinux_state, 0, sizeof(selinux_state)); |
@@ -7161,12 +6816,6 @@ static __init int selinux_init(void) | |||
7161 | 6816 | ||
7162 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); | 6817 | default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); |
7163 | 6818 | ||
7164 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | ||
7165 | sizeof(struct inode_security_struct), | ||
7166 | 0, SLAB_PANIC, NULL); | ||
7167 | file_security_cache = kmem_cache_create("selinux_file_security", | ||
7168 | sizeof(struct file_security_struct), | ||
7169 | 0, SLAB_PANIC, NULL); | ||
7170 | avc_init(); | 6819 | avc_init(); |
7171 | 6820 | ||
7172 | avtab_cache_init(); | 6821 | avtab_cache_init(); |
@@ -7193,7 +6842,7 @@ static __init int selinux_init(void) | |||
7193 | 6842 | ||
7194 | static void delayed_superblock_init(struct super_block *sb, void *unused) | 6843 | static void delayed_superblock_init(struct super_block *sb, void *unused) |
7195 | { | 6844 | { |
7196 | superblock_doinit(sb, NULL); | 6845 | selinux_set_mnt_opts(sb, NULL, 0, NULL); |
7197 | } | 6846 | } |
7198 | 6847 | ||
7199 | void selinux_complete_init(void) | 6848 | void selinux_complete_init(void) |
@@ -7209,6 +6858,9 @@ void selinux_complete_init(void) | |||
7209 | all processes and objects when they are created. */ | 6858 | all processes and objects when they are created. */ |
7210 | DEFINE_LSM(selinux) = { | 6859 | DEFINE_LSM(selinux) = { |
7211 | .name = "selinux", | 6860 | .name = "selinux", |
6861 | .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, | ||
6862 | .enabled = &selinux_enabled, | ||
6863 | .blobs = &selinux_blob_sizes, | ||
7212 | .init = selinux_init, | 6864 | .init = selinux_init, |
7213 | }; | 6865 | }; |
7214 | 6866 | ||