hooks.c (c312feb2931ded0582378712727b7ea017a951bd) hooks.c (0808925ea5684a0ce25483b30e94d4f398804978)
1/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux hook function implementations.
5 *
6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
7 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com>

--- 306 unchanged lines hidden (view full) ---

315{
316 return inode_doinit_with_dentry(inode, NULL);
317}
318
319enum {
320 Opt_context = 1,
321 Opt_fscontext = 2,
322 Opt_defcontext = 4,
1/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux hook function implementations.
5 *
6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
7 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com>

--- 306 unchanged lines hidden (view full) ---

315{
316 return inode_doinit_with_dentry(inode, NULL);
317}
318
319enum {
320 Opt_context = 1,
321 Opt_fscontext = 2,
322 Opt_defcontext = 4,
323 Opt_rootcontext = 8,
323};
324
325static match_table_t tokens = {
326 {Opt_context, "context=%s"},
327 {Opt_fscontext, "fscontext=%s"},
328 {Opt_defcontext, "defcontext=%s"},
324};
325
326static match_table_t tokens = {
327 {Opt_context, "context=%s"},
328 {Opt_fscontext, "fscontext=%s"},
329 {Opt_defcontext, "defcontext=%s"},
330 {Opt_rootcontext, "rootcontext=%s"},
329};
330
331#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
332
333static int may_context_mount_sb_relabel(u32 sid,
334 struct superblock_security_struct *sbsec,
335 struct task_security_struct *tsec)
336{

--- 4 unchanged lines hidden (view full) ---

341 if (rc)
342 return rc;
343
344 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
345 FILESYSTEM__RELABELTO, NULL);
346 return rc;
347}
348
331};
332
333#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
334
335static int may_context_mount_sb_relabel(u32 sid,
336 struct superblock_security_struct *sbsec,
337 struct task_security_struct *tsec)
338{

--- 4 unchanged lines hidden (view full) ---

343 if (rc)
344 return rc;
345
346 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
347 FILESYSTEM__RELABELTO, NULL);
348 return rc;
349}
350
351static int may_context_mount_inode_relabel(u32 sid,
352 struct superblock_security_struct *sbsec,
353 struct task_security_struct *tsec)
354{
355 int rc;
356 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
357 FILESYSTEM__RELABELFROM, NULL);
358 if (rc)
359 return rc;
360
361 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
362 FILESYSTEM__ASSOCIATE, NULL);
363 return rc;
364}
365
349static int try_context_mount(struct super_block *sb, void *data)
350{
351 char *context = NULL, *defcontext = NULL;
366static int try_context_mount(struct super_block *sb, void *data)
367{
368 char *context = NULL, *defcontext = NULL;
352 char *fscontext = NULL;
369 char *fscontext = NULL, *rootcontext = NULL;
353 const char *name;
354 u32 sid;
355 int alloc = 0, rc = 0, seen = 0;
356 struct task_security_struct *tsec = current->security;
357 struct superblock_security_struct *sbsec = sb->s_security;
358
359 if (!data)
360 goto out;

--- 57 unchanged lines hidden (view full) ---

418 rc = -ENOMEM;
419 goto out_free;
420 }
421 if (!alloc)
422 alloc = 1;
423 seen |= Opt_fscontext;
424 break;
425
370 const char *name;
371 u32 sid;
372 int alloc = 0, rc = 0, seen = 0;
373 struct task_security_struct *tsec = current->security;
374 struct superblock_security_struct *sbsec = sb->s_security;
375
376 if (!data)
377 goto out;

--- 57 unchanged lines hidden (view full) ---

435 rc = -ENOMEM;
436 goto out_free;
437 }
438 if (!alloc)
439 alloc = 1;
440 seen |= Opt_fscontext;
441 break;
442
443 case Opt_rootcontext:
444 if (seen & Opt_rootcontext) {
445 rc = -EINVAL;
446 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
447 goto out_free;
448 }
449 rootcontext = match_strdup(&args[0]);
450 if (!rootcontext) {
451 rc = -ENOMEM;
452 goto out_free;
453 }
454 if (!alloc)
455 alloc = 1;
456 seen |= Opt_rootcontext;
457 break;
458
426 case Opt_defcontext:
427 if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
428 rc = -EINVAL;
429 printk(KERN_WARNING "SELinux: "
430 "defcontext option is invalid "
431 "for this filesystem type\n");
432 goto out_free;
433 }

--- 62 unchanged lines hidden (view full) ---

496
497 if (!fscontext)
498 sbsec->sid = sid;
499 sbsec->mntpoint_sid = sid;
500
501 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
502 }
503
459 case Opt_defcontext:
460 if (sbsec->behavior != SECURITY_FS_USE_XATTR) {
461 rc = -EINVAL;
462 printk(KERN_WARNING "SELinux: "
463 "defcontext option is invalid "
464 "for this filesystem type\n");
465 goto out_free;
466 }

--- 62 unchanged lines hidden (view full) ---

529
530 if (!fscontext)
531 sbsec->sid = sid;
532 sbsec->mntpoint_sid = sid;
533
534 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
535 }
536
537 if (rootcontext) {
538 struct inode *inode = sb->s_root->d_inode;
539 struct inode_security_struct *isec = inode->i_security;
540 rc = security_context_to_sid(rootcontext, strlen(rootcontext), &sid);
541 if (rc) {
542 printk(KERN_WARNING "SELinux: security_context_to_sid"
543 "(%s) failed for (dev %s, type %s) errno=%d\n",
544 rootcontext, sb->s_id, name, rc);
545 goto out_free;
546 }
547
548 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
549 if (rc)
550 goto out_free;
551
552 isec->sid = sid;
553 isec->initialized = 1;
554 }
555
504 if (defcontext) {
505 rc = security_context_to_sid(defcontext, strlen(defcontext), &sid);
506 if (rc) {
507 printk(KERN_WARNING "SELinux: security_context_to_sid"
508 "(%s) failed for (dev %s, type %s) errno=%d\n",
509 defcontext, sb->s_id, name, rc);
510 goto out_free;
511 }
512
513 if (sid == sbsec->def_sid)
514 goto out_free;
515
556 if (defcontext) {
557 rc = security_context_to_sid(defcontext, strlen(defcontext), &sid);
558 if (rc) {
559 printk(KERN_WARNING "SELinux: security_context_to_sid"
560 "(%s) failed for (dev %s, type %s) errno=%d\n",
561 defcontext, sb->s_id, name, rc);
562 goto out_free;
563 }
564
565 if (sid == sbsec->def_sid)
566 goto out_free;
567
516 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
517 FILESYSTEM__RELABELFROM, NULL);
568 rc = may_context_mount_inode_relabel(sid, sbsec, tsec);
518 if (rc)
519 goto out_free;
520
569 if (rc)
570 goto out_free;
571
521 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
522 FILESYSTEM__ASSOCIATE, NULL);
523 if (rc)
524 goto out_free;
525
526 sbsec->def_sid = sid;
527 }
528
529out_free:
530 if (alloc) {
531 kfree(context);
532 kfree(defcontext);
533 kfree(fscontext);
572 sbsec->def_sid = sid;
573 }
574
575out_free:
576 if (alloc) {
577 kfree(context);
578 kfree(defcontext);
579 kfree(fscontext);
580 kfree(rootcontext);
534 }
535out:
536 return rc;
537}
538
539static int superblock_doinit(struct super_block *sb, void *data)
540{
541 struct superblock_security_struct *sbsec = sb->s_security;

--- 1335 unchanged lines hidden (view full) ---

1877
1878 return !memcmp(prefix, option, plen);
1879}
1880
1881static inline int selinux_option(char *option, int len)
1882{
1883 return (match_prefix("context=", sizeof("context=")-1, option, len) ||
1884 match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
581 }
582out:
583 return rc;
584}
585
586static int superblock_doinit(struct super_block *sb, void *data)
587{
588 struct superblock_security_struct *sbsec = sb->s_security;

--- 1335 unchanged lines hidden (view full) ---

1924
1925 return !memcmp(prefix, option, plen);
1926}
1927
1928static inline int selinux_option(char *option, int len)
1929{
1930 return (match_prefix("context=", sizeof("context=")-1, option, len) ||
1931 match_prefix("fscontext=", sizeof("fscontext=")-1, option, len) ||
1885 match_prefix("defcontext=", sizeof("defcontext=")-1, option, len));
1932 match_prefix("defcontext=", sizeof("defcontext=")-1, option, len) ||
1933 match_prefix("rootcontext=", sizeof("rootcontext=")-1, option, len));
1886}
1887
1888static inline void take_option(char **to, char *from, int *first, int len)
1889{
1890 if (!*first) {
1891 **to = ',';
1892 *to += 1;
1893 }

--- 2869 unchanged lines hidden ---
1934}
1935
1936static inline void take_option(char **to, char *from, int *first, int len)
1937{
1938 if (!*first) {
1939 **to = ',';
1940 *to += 1;
1941 }

--- 2869 unchanged lines hidden ---