aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2011-04-25 13:10:27 -0400
committerEric Paris <eparis@redhat.com>2011-04-25 18:14:07 -0400
commita269434d2fb48a4d66c1d7bf821b7874b59c5b41 (patch)
tree9c84b5f3e9f3adb3dd4a7e9da2b72dd7fe7eec49
parentf48b7399840b453e7282b523f535561fe9638a2d (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.h2
-rw-r--r--security/lsm_audit.c25
-rw-r--r--security/selinux/hooks.c26
-rw-r--r--security/smack/smack.h7
-rw-r--r--security/smack/smack_lsm.c34
5 files changed, 52 insertions, 42 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index bbaceab83a6..88e78dedc2e 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -36,9 +36,11 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_NONE 7
#define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9
+#define LSM_AUDIT_DATA_DENTRY 10
struct task_struct *tsk;
union {
struct path path;
+ struct dentry *dentry;
struct inode *inode;
struct {
int netif;
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 2e846052cbf..893af8a2fa1 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,
audit_log_format(ab, " capability=%d ", a->u.cap);
break;
case LSM_AUDIT_DATA_PATH: {
- struct dentry *dentry = a->u.path.dentry;
struct inode *inode;
- if (a->u.path.mnt) {
- audit_log_d_path(ab, "path=", &a->u.path);
- } else {
- audit_log_format(ab, " name=");
- audit_log_untrustedstring(ab,
- dentry->d_name.name);
- }
- inode = dentry->d_inode;
+ audit_log_d_path(ab, "path=", &a->u.path);
+
+ inode = a->u.path.dentry->d_inode;
+ if (inode)
+ audit_log_format(ab, " dev=%s ino=%lu",
+ inode->i_sb->s_id,
+ inode->i_ino);
+ break;
+ }
+ case LSM_AUDIT_DATA_DENTRY: {
+ struct inode *inode;
+
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
+
+ inode = a->u.dentry->d_inode;
if (inode)
audit_log_format(ab, " dev=%s ino=%lu",
inode->i_sb->s_id,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ad664d3056e..9e8078a42a9 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1569,8 +1569,8 @@ static int may_create(struct inode *dir,
sid = tsec->sid;
newsid = tsec->create_sid;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
- ad.u.path.dentry = dentry;
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+ ad.u.dentry = dentry;
rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
DIR__ADD_NAME | DIR__SEARCH,
@@ -1621,8 +1621,8 @@ static int may_link(struct inode *dir,
dsec = dir->i_security;
isec = dentry->d_inode->i_security;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
- ad.u.path.dentry = dentry;
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+ ad.u.dentry = dentry;
av = DIR__SEARCH;
av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1667,9 +1667,9 @@ static inline int may_rename(struct inode *old_dir,
old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
new_dsec = new_dir->i_security;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
- ad.u.path.dentry = old_dentry;
+ ad.u.dentry = old_dentry;
rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
DIR__REMOVE_NAME | DIR__SEARCH, &ad);
if (rc)
@@ -1685,7 +1685,7 @@ static inline int may_rename(struct inode *old_dir,
return rc;
}
- ad.u.path.dentry = new_dentry;
+ ad.u.dentry = new_dentry;
av = DIR__ADD_NAME | DIR__SEARCH;
if (new_dentry->d_inode)
av |= DIR__REMOVE_NAME;
@@ -2468,8 +2468,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
if (flags & MS_KERNMOUNT)
return 0;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
- ad.u.path.dentry = sb->s_root;
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+ ad.u.dentry = sb->s_root;
return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
}
@@ -2478,8 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
const struct cred *cred = current_cred();
struct common_audit_data ad;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
- ad.u.path.dentry = dentry->d_sb->s_root;
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+ ad.u.dentry = dentry->d_sb->s_root;
return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
}
@@ -2732,8 +2732,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
if (!is_owner_or_cap(inode))
return -EPERM;
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
- ad.u.path.dentry = dentry;
+ COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+ ad.u.dentry = dentry;
rc = avc_has_perm(sid, isec->sid, isec->sclass,
FILE__RELABELFROM, &ad);
diff --git a/security/smack/smack.h b/security/smack/smack.h
index a16925c0e91..2b6c6a51612 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,
static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
struct dentry *d)
{
- a->a.u.path.dentry = d;
-}
-static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
- struct vfsmount *m)
-{
- a->a.u.path.mnt = m;
+ a->a.u.dentry = d;
}
static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
struct inode *i)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index eeb393fbf92..a3bdd138392 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)
int rc;
struct smk_audit_info ad;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
{
struct superblock_smack *sbp;
struct smk_audit_info ad;
+ struct path path;
+
+ path.dentry = mnt->mnt_root;
+ path.mnt = mnt;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
- smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root);
- smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
+ smk_ad_setfield_u_fs_path(&ad, path);
sbp = mnt->mnt_sb->s_security;
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,
struct smk_audit_info ad;
int rc;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode);
@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
struct smk_audit_info ad;
int rc;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
/*
@@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
struct smk_audit_info ad;
int rc;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
/*
@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode,
char *isp;
struct smk_audit_info ad;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode);
@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
*/
if (iattr->ia_valid & ATTR_FORCE)
return 0;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
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)
static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{
struct smk_audit_info ad;
+ struct path path;
+
+ path.dentry = dentry;
+ path.mnt = mnt;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
- smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
- smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
+ smk_ad_setfield_u_fs_path(&ad, path);
return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
}
@@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
} else
rc = cap_inode_setxattr(dentry, name, value, size, flags);
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
if (rc == 0)
@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
{
struct smk_audit_info ad;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
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)
} else
rc = cap_inode_removexattr(dentry, name);
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
if (rc == 0)
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)
{
struct smk_audit_info ad;
- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
+ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry);
return smk_curacc(file->f_security, MAY_WRITE, &ad);
}