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 --- |