diff options
author | Eric Paris <eparis@redhat.com> | 2011-04-25 13:10:27 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2011-04-25 18:14:07 -0400 |
commit | a269434d2fb48a4d66c1d7bf821b7874b59c5b41 (patch) | |
tree | 9c84b5f3e9f3adb3dd4a7e9da2b72dd7fe7eec49 | |
parent | f48b7399840b453e7282b523f535561fe9638a2d (diff) |
LSM: separate LSM_AUDIT_DATA_DENTRY from LSM_AUDIT_DATA_PATH
This patch separates and audit message that only contains a dentry from
one that contains a full path. This allows us to make it harder to
misuse the interfaces or for the interfaces to be implemented wrong.
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
-rw-r--r-- | include/linux/lsm_audit.h | 2 | ||||
-rw-r--r-- | security/lsm_audit.c | 25 | ||||
-rw-r--r-- | security/selinux/hooks.c | 26 | ||||
-rw-r--r-- | security/smack/smack.h | 7 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 34 |
5 files changed, 52 insertions, 42 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index bbaceab83a65..88e78dedc2e8 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h | |||
@@ -36,9 +36,11 @@ struct common_audit_data { | |||
36 | #define LSM_AUDIT_DATA_NONE 7 | 36 | #define LSM_AUDIT_DATA_NONE 7 |
37 | #define LSM_AUDIT_DATA_KMOD 8 | 37 | #define LSM_AUDIT_DATA_KMOD 8 |
38 | #define LSM_AUDIT_DATA_INODE 9 | 38 | #define LSM_AUDIT_DATA_INODE 9 |
39 | #define LSM_AUDIT_DATA_DENTRY 10 | ||
39 | struct task_struct *tsk; | 40 | struct task_struct *tsk; |
40 | union { | 41 | union { |
41 | struct path path; | 42 | struct path path; |
43 | struct dentry *dentry; | ||
42 | struct inode *inode; | 44 | struct inode *inode; |
43 | struct { | 45 | struct { |
44 | int netif; | 46 | int netif; |
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 2e846052cbf4..893af8a2fa1e 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
@@ -229,17 +229,24 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
229 | audit_log_format(ab, " capability=%d ", a->u.cap); | 229 | audit_log_format(ab, " capability=%d ", a->u.cap); |
230 | break; | 230 | break; |
231 | case LSM_AUDIT_DATA_PATH: { | 231 | case LSM_AUDIT_DATA_PATH: { |
232 | struct dentry *dentry = a->u.path.dentry; | ||
233 | struct inode *inode; | 232 | struct inode *inode; |
234 | 233 | ||
235 | if (a->u.path.mnt) { | 234 | audit_log_d_path(ab, "path=", &a->u.path); |
236 | audit_log_d_path(ab, "path=", &a->u.path); | 235 | |
237 | } else { | 236 | inode = a->u.path.dentry->d_inode; |
238 | audit_log_format(ab, " name="); | 237 | if (inode) |
239 | audit_log_untrustedstring(ab, | 238 | audit_log_format(ab, " dev=%s ino=%lu", |
240 | dentry->d_name.name); | 239 | inode->i_sb->s_id, |
241 | } | 240 | inode->i_ino); |
242 | inode = dentry->d_inode; | 241 | break; |
242 | } | ||
243 | case LSM_AUDIT_DATA_DENTRY: { | ||
244 | struct inode *inode; | ||
245 | |||
246 | audit_log_format(ab, " name="); | ||
247 | audit_log_untrustedstring(ab, a->u.dentry->d_name.name); | ||
248 | |||
249 | inode = a->u.dentry->d_inode; | ||
243 | if (inode) | 250 | if (inode) |
244 | audit_log_format(ab, " dev=%s ino=%lu", | 251 | audit_log_format(ab, " dev=%s ino=%lu", |
245 | inode->i_sb->s_id, | 252 | inode->i_sb->s_id, |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad664d3056eb..9e8078a42a94 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1569,8 +1569,8 @@ static int may_create(struct inode *dir, | |||
1569 | sid = tsec->sid; | 1569 | sid = tsec->sid; |
1570 | newsid = tsec->create_sid; | 1570 | newsid = tsec->create_sid; |
1571 | 1571 | ||
1572 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1572 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1573 | ad.u.path.dentry = dentry; | 1573 | ad.u.dentry = dentry; |
1574 | 1574 | ||
1575 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, | 1575 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
1576 | DIR__ADD_NAME | DIR__SEARCH, | 1576 | DIR__ADD_NAME | DIR__SEARCH, |
@@ -1621,8 +1621,8 @@ static int may_link(struct inode *dir, | |||
1621 | dsec = dir->i_security; | 1621 | dsec = dir->i_security; |
1622 | isec = dentry->d_inode->i_security; | 1622 | isec = dentry->d_inode->i_security; |
1623 | 1623 | ||
1624 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1624 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1625 | ad.u.path.dentry = dentry; | 1625 | ad.u.dentry = dentry; |
1626 | 1626 | ||
1627 | av = DIR__SEARCH; | 1627 | av = DIR__SEARCH; |
1628 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); | 1628 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); |
@@ -1667,9 +1667,9 @@ static inline int may_rename(struct inode *old_dir, | |||
1667 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); | 1667 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); |
1668 | new_dsec = new_dir->i_security; | 1668 | new_dsec = new_dir->i_security; |
1669 | 1669 | ||
1670 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 1670 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
1671 | 1671 | ||
1672 | ad.u.path.dentry = old_dentry; | 1672 | ad.u.dentry = old_dentry; |
1673 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, | 1673 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
1674 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); | 1674 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); |
1675 | if (rc) | 1675 | if (rc) |
@@ -1685,7 +1685,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1685 | return rc; | 1685 | return rc; |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | ad.u.path.dentry = new_dentry; | 1688 | ad.u.dentry = new_dentry; |
1689 | av = DIR__ADD_NAME | DIR__SEARCH; | 1689 | av = DIR__ADD_NAME | DIR__SEARCH; |
1690 | if (new_dentry->d_inode) | 1690 | if (new_dentry->d_inode) |
1691 | av |= DIR__REMOVE_NAME; | 1691 | av |= DIR__REMOVE_NAME; |
@@ -2468,8 +2468,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2468 | if (flags & MS_KERNMOUNT) | 2468 | if (flags & MS_KERNMOUNT) |
2469 | return 0; | 2469 | return 0; |
2470 | 2470 | ||
2471 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 2471 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2472 | ad.u.path.dentry = sb->s_root; | 2472 | ad.u.dentry = sb->s_root; |
2473 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); | 2473 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); |
2474 | } | 2474 | } |
2475 | 2475 | ||
@@ -2478,8 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry) | |||
2478 | const struct cred *cred = current_cred(); | 2478 | const struct cred *cred = current_cred(); |
2479 | struct common_audit_data ad; | 2479 | struct common_audit_data ad; |
2480 | 2480 | ||
2481 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 2481 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2482 | ad.u.path.dentry = dentry->d_sb->s_root; | 2482 | ad.u.dentry = dentry->d_sb->s_root; |
2483 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2483 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
2484 | } | 2484 | } |
2485 | 2485 | ||
@@ -2732,8 +2732,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2732 | if (!is_owner_or_cap(inode)) | 2732 | if (!is_owner_or_cap(inode)) |
2733 | return -EPERM; | 2733 | return -EPERM; |
2734 | 2734 | ||
2735 | COMMON_AUDIT_DATA_INIT(&ad, PATH); | 2735 | COMMON_AUDIT_DATA_INIT(&ad, DENTRY); |
2736 | ad.u.path.dentry = dentry; | 2736 | ad.u.dentry = dentry; |
2737 | 2737 | ||
2738 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 2738 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
2739 | FILE__RELABELFROM, &ad); | 2739 | FILE__RELABELFROM, &ad); |
diff --git a/security/smack/smack.h b/security/smack/smack.h index a16925c0e91a..2b6c6a516123 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -316,12 +316,7 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | |||
316 | static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, | 316 | static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, |
317 | struct dentry *d) | 317 | struct dentry *d) |
318 | { | 318 | { |
319 | a->a.u.path.dentry = d; | 319 | a->a.u.dentry = d; |
320 | } | ||
321 | static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, | ||
322 | struct vfsmount *m) | ||
323 | { | ||
324 | a->a.u.path.mnt = m; | ||
325 | } | 320 | } |
326 | static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, | 321 | static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, |
327 | struct inode *i) | 322 | struct inode *i) |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index eeb393fbf925..a3bdd1383928 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry) | |||
383 | int rc; | 383 | int rc; |
384 | struct smk_audit_info ad; | 384 | struct smk_audit_info ad; |
385 | 385 | ||
386 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 386 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
387 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 387 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
388 | 388 | ||
389 | rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); | 389 | rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); |
@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) | |||
425 | { | 425 | { |
426 | struct superblock_smack *sbp; | 426 | struct superblock_smack *sbp; |
427 | struct smk_audit_info ad; | 427 | struct smk_audit_info ad; |
428 | struct path path; | ||
429 | |||
430 | path.dentry = mnt->mnt_root; | ||
431 | path.mnt = mnt; | ||
428 | 432 | ||
429 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 433 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
430 | smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); | 434 | smk_ad_setfield_u_fs_path(&ad, path); |
431 | smk_ad_setfield_u_fs_path_mnt(&ad, mnt); | ||
432 | 435 | ||
433 | sbp = mnt->mnt_sb->s_security; | 436 | sbp = mnt->mnt_sb->s_security; |
434 | return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); | 437 | return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); |
@@ -563,7 +566,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, | |||
563 | struct smk_audit_info ad; | 566 | struct smk_audit_info ad; |
564 | int rc; | 567 | int rc; |
565 | 568 | ||
566 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 569 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
567 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | 570 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); |
568 | 571 | ||
569 | isp = smk_of_inode(old_dentry->d_inode); | 572 | isp = smk_of_inode(old_dentry->d_inode); |
@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) | |||
592 | struct smk_audit_info ad; | 595 | struct smk_audit_info ad; |
593 | int rc; | 596 | int rc; |
594 | 597 | ||
595 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 598 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
596 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 599 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
597 | 600 | ||
598 | /* | 601 | /* |
@@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) | |||
623 | struct smk_audit_info ad; | 626 | struct smk_audit_info ad; |
624 | int rc; | 627 | int rc; |
625 | 628 | ||
626 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 629 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
627 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 630 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
628 | 631 | ||
629 | /* | 632 | /* |
@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode, | |||
663 | char *isp; | 666 | char *isp; |
664 | struct smk_audit_info ad; | 667 | struct smk_audit_info ad; |
665 | 668 | ||
666 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 669 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
667 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); | 670 | smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); |
668 | 671 | ||
669 | isp = smk_of_inode(old_dentry->d_inode); | 672 | isp = smk_of_inode(old_dentry->d_inode); |
@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
720 | */ | 723 | */ |
721 | if (iattr->ia_valid & ATTR_FORCE) | 724 | if (iattr->ia_valid & ATTR_FORCE) |
722 | return 0; | 725 | return 0; |
723 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 726 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
724 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 727 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
725 | 728 | ||
726 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 729 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
@@ -736,10 +739,13 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
736 | static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | 739 | static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) |
737 | { | 740 | { |
738 | struct smk_audit_info ad; | 741 | struct smk_audit_info ad; |
742 | struct path path; | ||
743 | |||
744 | path.dentry = dentry; | ||
745 | path.mnt = mnt; | ||
739 | 746 | ||
740 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 747 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
741 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 748 | smk_ad_setfield_u_fs_path(&ad, path); |
742 | smk_ad_setfield_u_fs_path_mnt(&ad, mnt); | ||
743 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | 749 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); |
744 | } | 750 | } |
745 | 751 | ||
@@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, | |||
784 | } else | 790 | } else |
785 | rc = cap_inode_setxattr(dentry, name, value, size, flags); | 791 | rc = cap_inode_setxattr(dentry, name, value, size, flags); |
786 | 792 | ||
787 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 793 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
788 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 794 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
789 | 795 | ||
790 | if (rc == 0) | 796 | if (rc == 0) |
@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) | |||
845 | { | 851 | { |
846 | struct smk_audit_info ad; | 852 | struct smk_audit_info ad; |
847 | 853 | ||
848 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 854 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
849 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 855 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
850 | 856 | ||
851 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); | 857 | return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); |
@@ -877,7 +883,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
877 | } else | 883 | } else |
878 | rc = cap_inode_removexattr(dentry, name); | 884 | rc = cap_inode_removexattr(dentry, name); |
879 | 885 | ||
880 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 886 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
881 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); | 887 | smk_ad_setfield_u_fs_path_dentry(&ad, dentry); |
882 | if (rc == 0) | 888 | if (rc == 0) |
883 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); | 889 | rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); |
@@ -1070,7 +1076,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd) | |||
1070 | { | 1076 | { |
1071 | struct smk_audit_info ad; | 1077 | struct smk_audit_info ad; |
1072 | 1078 | ||
1073 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1079 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); |
1074 | smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); | 1080 | smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); |
1075 | return smk_curacc(file->f_security, MAY_WRITE, &ad); | 1081 | return smk_curacc(file->f_security, MAY_WRITE, &ad); |
1076 | } | 1082 | } |