Skip to content

Commit

Permalink
LSM: split LSM_AUDIT_DATA_FS into _PATH and _INODE
Browse files Browse the repository at this point in the history
The lsm common audit code has wacky contortions making sure which pieces
of information are set based on if it was given a path, dentry, or
inode.  Split this into path and inode to get rid of some of the code
complexity.

Signed-off-by: Eric Paris <[email protected]>
Acked-by: Casey Schaufler <[email protected]>
  • Loading branch information
eparis committed Apr 25, 2011
1 parent 0dc1ba2 commit f48b739
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 73 deletions.
9 changes: 4 additions & 5 deletions include/linux/lsm_audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,19 @@
/* Auxiliary data to use in generating the audit record. */
struct common_audit_data {
char type;
#define LSM_AUDIT_DATA_FS 1
#define LSM_AUDIT_DATA_PATH 1
#define LSM_AUDIT_DATA_NET 2
#define LSM_AUDIT_DATA_CAP 3
#define LSM_AUDIT_DATA_IPC 4
#define LSM_AUDIT_DATA_TASK 5
#define LSM_AUDIT_DATA_KEY 6
#define LSM_AUDIT_DATA_NONE 7
#define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9
struct task_struct *tsk;
union {
struct {
struct path path;
struct inode *inode;
} fs;
struct path path;
struct inode *inode;
struct {
int netif;
struct sock *sk;
Expand Down
50 changes: 28 additions & 22 deletions security/lsm_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
static void dump_common_audit_data(struct audit_buffer *ab,
struct common_audit_data *a)
{
struct inode *inode = NULL;
struct task_struct *tsk = current;

if (a->tsk)
Expand All @@ -229,33 +228,40 @@ static void dump_common_audit_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_CAP:
audit_log_format(ab, " capability=%d ", a->u.cap);
break;
case LSM_AUDIT_DATA_FS:
if (a->u.fs.path.dentry) {
struct dentry *dentry = a->u.fs.path.dentry;
if (a->u.fs.path.mnt) {
audit_log_d_path(ab, "path=", &a->u.fs.path);
} else {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab,
dentry->d_name.name);
}
inode = dentry->d_inode;
} else if (a->u.fs.inode) {
struct dentry *dentry;
inode = a->u.fs.inode;
dentry = d_find_alias(inode);
if (dentry) {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab,
dentry->d_name.name);
dput(dentry);
}
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;
if (inode)
audit_log_format(ab, " dev=%s ino=%lu",
inode->i_sb->s_id,
inode->i_ino);
break;
}
case LSM_AUDIT_DATA_INODE: {
struct dentry *dentry;
struct inode *inode;

inode = a->u.inode;
dentry = d_find_alias(inode);
if (dentry) {
audit_log_format(ab, " name=");
audit_log_untrustedstring(ab,
dentry->d_name.name);
dput(dentry);
}
audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id,
inode->i_ino);
break;
}
case LSM_AUDIT_DATA_TASK:
tsk = a->u.tsk;
if (tsk && tsk->pid) {
Expand Down
2 changes: 1 addition & 1 deletion security/selinux/avc.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ int avc_audit(u32 ssid, u32 tsid,
* during retry. However this is logically just as if the operation
* happened a little later.
*/
if ((a->type == LSM_AUDIT_DATA_FS) &&
if ((a->type == LSM_AUDIT_DATA_INODE) &&
(flags & IPERM_FLAG_RCU))
return -ECHILD;

Expand Down
50 changes: 25 additions & 25 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1488,8 +1488,8 @@ static int inode_has_perm(const struct cred *cred,

if (!adp) {
adp = &ad;
COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.inode = inode;
COMMON_AUDIT_DATA_INIT(&ad, INODE);
ad.u.inode = inode;
}

return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
Expand All @@ -1506,9 +1506,9 @@ static inline int dentry_has_perm(const struct cred *cred,
struct inode *inode = dentry->d_inode;
struct common_audit_data ad;

COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path.mnt = mnt;
ad.u.fs.path.dentry = dentry;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.mnt = mnt;
ad.u.path.dentry = dentry;
return inode_has_perm(cred, inode, av, &ad, 0);
}

Expand All @@ -1530,8 +1530,8 @@ static int file_has_perm(const struct cred *cred,
u32 sid = cred_sid(cred);
int rc;

COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path = file->f_path;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path = file->f_path;

if (sid != fsec->sid) {
rc = avc_has_perm(sid, fsec->sid,
Expand Down Expand Up @@ -1569,8 +1569,8 @@ static int may_create(struct inode *dir,
sid = tsec->sid;
newsid = tsec->create_sid;

COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path.dentry = dentry;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.dentry = dentry;

rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
DIR__ADD_NAME | DIR__SEARCH,
Expand Down Expand Up @@ -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, FS);
ad.u.fs.path.dentry = dentry;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.dentry = dentry;

av = DIR__SEARCH;
av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Expand Down Expand Up @@ -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, FS);
COMMON_AUDIT_DATA_INIT(&ad, PATH);

ad.u.fs.path.dentry = old_dentry;
ad.u.path.dentry = old_dentry;
rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
DIR__REMOVE_NAME | DIR__SEARCH, &ad);
if (rc)
Expand All @@ -1685,7 +1685,7 @@ static inline int may_rename(struct inode *old_dir,
return rc;
}

ad.u.fs.path.dentry = new_dentry;
ad.u.path.dentry = new_dentry;
av = DIR__ADD_NAME | DIR__SEARCH;
if (new_dentry->d_inode)
av |= DIR__REMOVE_NAME;
Expand Down Expand Up @@ -1991,8 +1991,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
return rc;
}

COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.path = bprm->file->f_path;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path = bprm->file->f_path;

if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
new_tsec->sid = old_tsec->sid;
Expand Down Expand Up @@ -2120,7 +2120,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,

/* Revalidate access to inherited open files. */

COMMON_AUDIT_DATA_INIT(&ad, FS);
COMMON_AUDIT_DATA_INIT(&ad, INODE);

spin_lock(&files->file_lock);
for (;;) {
Expand Down Expand Up @@ -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, FS);
ad.u.fs.path.dentry = sb->s_root;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.dentry = sb->s_root;
return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
}

Expand All @@ -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, FS);
ad.u.fs.path.dentry = dentry->d_sb->s_root;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.dentry = dentry->d_sb->s_root;
return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
}

Expand Down Expand Up @@ -2653,8 +2653,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
if (!mask)
return 0;

COMMON_AUDIT_DATA_INIT(&ad, FS);
ad.u.fs.inode = inode;
COMMON_AUDIT_DATA_INIT(&ad, INODE);
ad.u.inode = inode;

if (from_access)
ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
Expand Down Expand Up @@ -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, FS);
ad.u.fs.path.dentry = dentry;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path.dentry = dentry;

rc = avc_has_perm(sid, isec->sid, isec->sclass,
FILE__RELABELFROM, &ad);
Expand Down
8 changes: 4 additions & 4 deletions security/smack/smack.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,22 +316,22 @@ 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.fs.path.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.fs.path.mnt = m;
a->a.u.path.mnt = m;
}
static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
struct inode *i)
{
a->a.u.fs.inode = i;
a->a.u.inode = i;
}
static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
struct path p)
{
a->a.u.fs.path = p;
a->a.u.path = p;
}
static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
struct sock *sk)
Expand Down
Loading

0 comments on commit f48b739

Please sign in to comment.