Commit b7b57551 authored by James Morris's avatar James Morris

Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus

Conflicts:
	lib/flex_array.c
	security/selinux/avc.c
	security/selinux/hooks.c
	security/selinux/ss/policydb.c
	security/smack/smack_lsm.c

Manually resolve conflicts.
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parents 434d42cf 7a627e3b
...@@ -5592,10 +5592,11 @@ M: James Morris <jmorris@namei.org> ...@@ -5592,10 +5592,11 @@ M: James Morris <jmorris@namei.org>
M: Eric Paris <eparis@parisplace.org> M: Eric Paris <eparis@parisplace.org>
L: selinux@tycho.nsa.gov (subscribers-only, general discussion) L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
W: http://selinuxproject.org W: http://selinuxproject.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git T: git git://git.infradead.org/users/eparis/selinux.git
S: Supported S: Supported
F: include/linux/selinux* F: include/linux/selinux*
F: security/selinux/ F: security/selinux/
F: scripts/selinux/
APPARMOR SECURITY MODULE APPARMOR SECURITY MODULE
M: John Johansen <john.johansen@canonical.com> M: John Johansen <john.johansen@canonical.com>
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
/* Auxiliary data to use in generating the audit record. */ /* Auxiliary data to use in generating the audit record. */
struct common_audit_data { struct common_audit_data {
char type; char type;
#define LSM_AUDIT_DATA_FS 1 #define LSM_AUDIT_DATA_PATH 1
#define LSM_AUDIT_DATA_NET 2 #define LSM_AUDIT_DATA_NET 2
#define LSM_AUDIT_DATA_CAP 3 #define LSM_AUDIT_DATA_CAP 3
#define LSM_AUDIT_DATA_IPC 4 #define LSM_AUDIT_DATA_IPC 4
...@@ -35,12 +35,13 @@ struct common_audit_data { ...@@ -35,12 +35,13 @@ struct common_audit_data {
#define LSM_AUDIT_DATA_KEY 6 #define LSM_AUDIT_DATA_KEY 6
#define LSM_AUDIT_DATA_NONE 7 #define LSM_AUDIT_DATA_NONE 7
#define LSM_AUDIT_DATA_KMOD 8 #define LSM_AUDIT_DATA_KMOD 8
#define LSM_AUDIT_DATA_INODE 9
#define LSM_AUDIT_DATA_DENTRY 10
struct task_struct *tsk; struct task_struct *tsk;
union { union {
struct { struct path path;
struct path path; struct dentry *dentry;
struct inode *inode; struct inode *inode;
} fs;
struct { struct {
int netif; int netif;
struct sock *sk; struct sock *sk;
......
...@@ -88,8 +88,11 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total, ...@@ -88,8 +88,11 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
gfp_t flags) gfp_t flags)
{ {
struct flex_array *ret; struct flex_array *ret;
int max_size = FLEX_ARRAY_NR_BASE_PTRS * int max_size = 0;
FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
if (element_size)
max_size = FLEX_ARRAY_NR_BASE_PTRS *
FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
/* max_size will end up 0 if element_size > PAGE_SIZE */ /* max_size will end up 0 if element_size > PAGE_SIZE */
if (total > max_size) if (total > max_size)
...@@ -183,15 +186,18 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags) ...@@ -183,15 +186,18 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
gfp_t flags) gfp_t flags)
{ {
int part_nr = fa_element_to_part_nr(fa, element_nr); int part_nr;
struct flex_array_part *part; struct flex_array_part *part;
void *dst; void *dst;
if (element_nr >= fa->total_nr_elements) if (element_nr >= fa->total_nr_elements)
return -ENOSPC; return -ENOSPC;
if (!fa->element_size)
return 0;
if (elements_fit_in_base(fa)) if (elements_fit_in_base(fa))
part = (struct flex_array_part *)&fa->parts[0]; part = (struct flex_array_part *)&fa->parts[0];
else { else {
part_nr = fa_element_to_part_nr(fa, element_nr);
part = __fa_get_part(fa, part_nr, flags); part = __fa_get_part(fa, part_nr, flags);
if (!part) if (!part)
return -ENOMEM; return -ENOMEM;
...@@ -211,15 +217,18 @@ EXPORT_SYMBOL(flex_array_put); ...@@ -211,15 +217,18 @@ EXPORT_SYMBOL(flex_array_put);
*/ */
int flex_array_clear(struct flex_array *fa, unsigned int element_nr) int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
{ {
int part_nr = fa_element_to_part_nr(fa, element_nr); int part_nr;
struct flex_array_part *part; struct flex_array_part *part;
void *dst; void *dst;
if (element_nr >= fa->total_nr_elements) if (element_nr >= fa->total_nr_elements)
return -ENOSPC; return -ENOSPC;
if (!fa->element_size)
return 0;
if (elements_fit_in_base(fa)) if (elements_fit_in_base(fa))
part = (struct flex_array_part *)&fa->parts[0]; part = (struct flex_array_part *)&fa->parts[0];
else { else {
part_nr = fa_element_to_part_nr(fa, element_nr);
part = fa->parts[part_nr]; part = fa->parts[part_nr];
if (!part) if (!part)
return -EINVAL; return -EINVAL;
...@@ -264,6 +273,8 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start, ...@@ -264,6 +273,8 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start,
if (end >= fa->total_nr_elements) if (end >= fa->total_nr_elements)
return -ENOSPC; return -ENOSPC;
if (!fa->element_size)
return 0;
if (elements_fit_in_base(fa)) if (elements_fit_in_base(fa))
return 0; return 0;
start_part = fa_element_to_part_nr(fa, start); start_part = fa_element_to_part_nr(fa, start);
...@@ -291,14 +302,17 @@ EXPORT_SYMBOL(flex_array_prealloc); ...@@ -291,14 +302,17 @@ EXPORT_SYMBOL(flex_array_prealloc);
*/ */
void *flex_array_get(struct flex_array *fa, unsigned int element_nr) void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
{ {
int part_nr = fa_element_to_part_nr(fa, element_nr); int part_nr;
struct flex_array_part *part; struct flex_array_part *part;
if (!fa->element_size)
return NULL;
if (element_nr >= fa->total_nr_elements) if (element_nr >= fa->total_nr_elements)
return NULL; return NULL;
if (elements_fit_in_base(fa)) if (elements_fit_in_base(fa))
part = (struct flex_array_part *)&fa->parts[0]; part = (struct flex_array_part *)&fa->parts[0];
else { else {
part_nr = fa_element_to_part_nr(fa, element_nr);
part = fa->parts[part_nr]; part = fa->parts[part_nr];
if (!part) if (!part)
return NULL; return NULL;
...@@ -353,7 +367,7 @@ int flex_array_shrink(struct flex_array *fa) ...@@ -353,7 +367,7 @@ int flex_array_shrink(struct flex_array *fa)
int part_nr; int part_nr;
int ret = 0; int ret = 0;
if (!fa->total_nr_elements) if (!fa->total_nr_elements || !fa->element_size)
return 0; return 0;
if (elements_fit_in_base(fa)) if (elements_fit_in_base(fa))
return ret; return ret;
......
...@@ -210,7 +210,6 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, ...@@ -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, static void dump_common_audit_data(struct audit_buffer *ab,
struct common_audit_data *a) struct common_audit_data *a)
{ {
struct inode *inode = NULL;
struct task_struct *tsk = current; struct task_struct *tsk = current;
if (a->tsk) if (a->tsk)
...@@ -229,33 +228,47 @@ static void dump_common_audit_data(struct audit_buffer *ab, ...@@ -229,33 +228,47 @@ static void dump_common_audit_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_CAP: case LSM_AUDIT_DATA_CAP:
audit_log_format(ab, " capability=%d ", a->u.cap); audit_log_format(ab, " capability=%d ", a->u.cap);
break; break;
case LSM_AUDIT_DATA_FS: case LSM_AUDIT_DATA_PATH: {
if (a->u.fs.path.dentry) { struct inode *inode;
struct dentry *dentry = a->u.fs.path.dentry;
if (a->u.fs.path.mnt) { audit_log_d_path(ab, "path=", &a->u.path);
audit_log_d_path(ab, "path=", &a->u.fs.path);
} else { inode = a->u.path.dentry->d_inode;
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);
}
}
if (inode) if (inode)
audit_log_format(ab, " dev=%s ino=%lu", audit_log_format(ab, " dev=%s ino=%lu",
inode->i_sb->s_id, inode->i_sb->s_id,
inode->i_ino); inode->i_ino);
break; 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,
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: case LSM_AUDIT_DATA_TASK:
tsk = a->u.tsk; tsk = a->u.tsk;
if (tsk && tsk->pid) { if (tsk && tsk->pid) {
......
...@@ -526,7 +526,7 @@ int avc_audit(u32 ssid, u32 tsid, ...@@ -526,7 +526,7 @@ int avc_audit(u32 ssid, u32 tsid,
* during retry. However this is logically just as if the operation * during retry. However this is logically just as if the operation
* happened a little later. * happened a little later.
*/ */
if ((a->type == LSM_AUDIT_DATA_FS) && if ((a->type == LSM_AUDIT_DATA_INODE) &&
(flags & IPERM_FLAG_RCU)) (flags & IPERM_FLAG_RCU))
return -ECHILD; return -ECHILD;
......
...@@ -990,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m, ...@@ -990,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m,
continue; continue;
default: default:
BUG(); BUG();
return;
}; };
/* we need a comma before each option */ /* we need a comma before each option */
seq_putc(m, ','); seq_putc(m, ',');
...@@ -1443,6 +1444,7 @@ static int task_has_capability(struct task_struct *tsk, ...@@ -1443,6 +1444,7 @@ static int task_has_capability(struct task_struct *tsk,
printk(KERN_ERR printk(KERN_ERR
"SELinux: out of range capability %d\n", cap); "SELinux: out of range capability %d\n", cap);
BUG(); BUG();
return -EINVAL;
} }
rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
...@@ -1487,8 +1489,8 @@ static int inode_has_perm(const struct cred *cred, ...@@ -1487,8 +1489,8 @@ static int inode_has_perm(const struct cred *cred,
if (!adp) { if (!adp) {
adp = &ad; adp = &ad;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, INODE);
ad.u.fs.inode = inode; ad.u.inode = inode;
} }
return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
...@@ -1498,16 +1500,29 @@ static int inode_has_perm(const struct cred *cred, ...@@ -1498,16 +1500,29 @@ static int inode_has_perm(const struct cred *cred,
the dentry to help the auditing code to more easily generate the the dentry to help the auditing code to more easily generate the
pathname if needed. */ pathname if needed. */
static inline int dentry_has_perm(const struct cred *cred, static inline int dentry_has_perm(const struct cred *cred,
struct vfsmount *mnt,
struct dentry *dentry, struct dentry *dentry,
u32 av) u32 av)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct common_audit_data ad; struct common_audit_data ad;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.mnt = mnt; ad.u.dentry = dentry;
ad.u.fs.path.dentry = dentry; return inode_has_perm(cred, inode, av, &ad, 0);
}
/* Same as inode_has_perm, but pass explicit audit data containing
the path to help the auditing code to more easily generate the
pathname if needed. */
static inline int path_has_perm(const struct cred *cred,
struct path *path,
u32 av)
{
struct inode *inode = path->dentry->d_inode;
struct common_audit_data ad;
COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.path = *path;
return inode_has_perm(cred, inode, av, &ad, 0); return inode_has_perm(cred, inode, av, &ad, 0);
} }
...@@ -1529,8 +1544,8 @@ static int file_has_perm(const struct cred *cred, ...@@ -1529,8 +1544,8 @@ static int file_has_perm(const struct cred *cred,
u32 sid = cred_sid(cred); u32 sid = cred_sid(cred);
int rc; int rc;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.fs.path = file->f_path; ad.u.path = file->f_path;
if (sid != fsec->sid) { if (sid != fsec->sid) {
rc = avc_has_perm(sid, fsec->sid, rc = avc_has_perm(sid, fsec->sid,
...@@ -1568,8 +1583,8 @@ static int may_create(struct inode *dir, ...@@ -1568,8 +1583,8 @@ static int may_create(struct inode *dir,
sid = tsec->sid; sid = tsec->sid;
newsid = tsec->create_sid; newsid = tsec->create_sid;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = dentry; ad.u.dentry = dentry;
rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
DIR__ADD_NAME | DIR__SEARCH, DIR__ADD_NAME | DIR__SEARCH,
...@@ -1621,8 +1636,8 @@ static int may_link(struct inode *dir, ...@@ -1621,8 +1636,8 @@ static int may_link(struct inode *dir,
dsec = dir->i_security; dsec = dir->i_security;
isec = dentry->d_inode->i_security; isec = dentry->d_inode->i_security;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = dentry; ad.u.dentry = dentry;
av = DIR__SEARCH; av = DIR__SEARCH;
av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
...@@ -1667,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir, ...@@ -1667,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,
old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
new_dsec = new_dir->i_security; new_dsec = new_dir->i_security;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = old_dentry; ad.u.dentry = old_dentry;
rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
DIR__REMOVE_NAME | DIR__SEARCH, &ad); DIR__REMOVE_NAME | DIR__SEARCH, &ad);
if (rc) if (rc)
...@@ -1685,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir, ...@@ -1685,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
return rc; return rc;
} }
ad.u.fs.path.dentry = new_dentry; ad.u.dentry = new_dentry;
av = DIR__ADD_NAME | DIR__SEARCH; av = DIR__ADD_NAME | DIR__SEARCH;
if (new_dentry->d_inode) if (new_dentry->d_inode)
av |= DIR__REMOVE_NAME; av |= DIR__REMOVE_NAME;
...@@ -1895,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry) ...@@ -1895,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); return dentry_has_perm(cred, dentry, FILE__QUOTAON);
} }
static int selinux_syslog(int type) static int selinux_syslog(int type)
...@@ -1992,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) ...@@ -1992,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
return rc; return rc;
} }
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, PATH);
ad.u.fs.path = bprm->file->f_path; ad.u.path = bprm->file->f_path;
if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
new_tsec->sid = old_tsec->sid; new_tsec->sid = old_tsec->sid;
...@@ -2121,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, ...@@ -2121,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
/* Revalidate access to inherited open files. */ /* Revalidate access to inherited open files. */
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, INODE);
spin_lock(&files->file_lock); spin_lock(&files->file_lock);
for (;;) { for (;;) {
...@@ -2469,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) ...@@ -2469,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
if (flags & MS_KERNMOUNT) if (flags & MS_KERNMOUNT)
return 0; return 0;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = sb->s_root; ad.u.dentry = sb->s_root;
return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
} }
...@@ -2479,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry) ...@@ -2479,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
struct common_audit_data ad; struct common_audit_data ad;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = dentry->d_sb->s_root; ad.u.dentry = dentry->d_sb->s_root;
return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
} }
...@@ -2496,8 +2511,7 @@ static int selinux_mount(char *dev_name, ...@@ -2496,8 +2511,7 @@ static int selinux_mount(char *dev_name,
return superblock_has_perm(cred, path->mnt->mnt_sb, return superblock_has_perm(cred, path->mnt->mnt_sb,
FILESYSTEM__REMOUNT, NULL); FILESYSTEM__REMOUNT, NULL);
else else
return dentry_has_perm(cred, path->mnt, path->dentry, return path_has_perm(cred, path, FILE__MOUNTON);
FILE__MOUNTON);
} }
static int selinux_umount(struct vfsmount *mnt, int flags) static int selinux_umount(struct vfsmount *mnt, int flags)
...@@ -2630,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry) ...@@ -2630,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
return dentry_has_perm(cred, NULL, dentry, FILE__READ); return dentry_has_perm(cred, dentry, FILE__READ);
} }
static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
return dentry_has_perm(cred, NULL, dentry, FILE__READ); return dentry_has_perm(cred, dentry, FILE__READ);
} }
static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
...@@ -2654,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag ...@@ -2654,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
if (!mask) if (!mask)
return 0; return 0;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, INODE);
ad.u.fs.inode = inode; ad.u.inode = inode;
if (from_access) if (from_access)
ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
...@@ -2680,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -2680,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); return dentry_has_perm(cred, dentry, FILE__SETATTR);
return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); return dentry_has_perm(cred, dentry, FILE__WRITE);
} }
static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
struct path path;
path.dentry = dentry;
path.mnt = mnt;
return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); return path_has_perm(cred, &path, FILE__GETATTR);
} }
static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
...@@ -2710,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) ...@@ -2710,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
/* Not an attribute we recognize, so just check the /* Not an attribute we recognize, so just check the
ordinary setattr permission. */ ordinary setattr permission. */
return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); return dentry_has_perm(cred, dentry, FILE__SETATTR);
} }
static int selinux_inode_setxattr(struct dentry *dentry, const char *name, static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
...@@ -2733,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, ...@@ -2733,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
if (!inode_owner_or_capable(inode)) if (!inode_owner_or_capable(inode))
return -EPERM; return -EPERM;
COMMON_AUDIT_DATA_INIT(&ad, FS); COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
ad.u.fs.path.dentry = dentry; ad.u.dentry = dentry;
rc = avc_has_perm(sid, isec->sid, isec->sclass, rc = avc_has_perm(sid, isec->sid, isec->sclass,
FILE__RELABELFROM, &ad); FILE__RELABELFROM, &ad);
...@@ -2797,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name) ...@@ -2797,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); return dentry_has_perm(cred, dentry, FILE__GETATTR);
} }
static int selinux_inode_listxattr(struct dentry *dentry) static int selinux_inode_listxattr(struct dentry *dentry)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); return dentry_has_perm(cred, dentry, FILE__GETATTR);
} }
static int selinux_inode_removexattr(struct dentry *dentry, const char *name) static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
......
...@@ -30,13 +30,14 @@ ...@@ -30,13 +30,14 @@
#define POLICYDB_VERSION_PERMISSIVE 23 #define POLICYDB_VERSION_PERMISSIVE 23
#define POLICYDB_VERSION_BOUNDARY 24 #define POLICYDB_VERSION_BOUNDARY 24
#define POLICYDB_VERSION_FILENAME_TRANS 25 #define POLICYDB_VERSION_FILENAME_TRANS 25
#define POLICYDB_VERSION_ROLETRANS 26
/* Range of policy versions we understand*/ /* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#else #else
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS #define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS
#endif #endif
/* Mask for just the mount related flags */ /* Mask for just the mount related flags */
...@@ -85,7 +86,7 @@ extern int selinux_policycap_openperm; ...@@ -85,7 +86,7 @@ extern int selinux_policycap_openperm;
int security_mls_enabled(void); int security_mls_enabled(void);
int security_load_policy(void *data, size_t len); int security_load_policy(void *data, size_t len);
int security_read_policy(void **data, ssize_t *len); int security_read_policy(void **data, size_t *len);
size_t security_policydb_len(void); size_t security_policydb_len(void);
int security_policycap_supported(unsigned int req_cap); int security_policycap_supported(unsigned int req_cap);
...@@ -111,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid, ...@@ -111,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid); const struct qstr *qstr, u32 *out_sid);
int security_transition_sid_user(u32 ssid, u32 tsid, int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
u16 tclass, u32 *out_sid); const char *objname, u32 *out_sid);
int security_member_sid(u32 ssid, u32 tsid, int security_member_sid(u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid); u16 tclass, u32 *out_sid);
......
...@@ -141,6 +141,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) ...@@ -141,6 +141,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
break; break;
default: default:
BUG(); BUG();
return NULL;
} }
list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kobject.h>
/* selinuxfs pseudo filesystem for exporting the security policy API. /* selinuxfs pseudo filesystem for exporting the security policy API.
Based on the proc code and the fs/nfsd/nfsctl.c code. */ Based on the proc code and the fs/nfsd/nfsctl.c code. */
...@@ -753,11 +754,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) ...@@ -753,11 +754,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
static ssize_t sel_write_create(struct file *file, char *buf, size_t size) static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{ {
char *scon = NULL, *tcon = NULL; char *scon = NULL, *tcon = NULL;
char *namebuf = NULL, *objname = NULL;
u32 ssid, tsid, newsid; u32 ssid, tsid, newsid;
u16 tclass; u16 tclass;
ssize_t length; ssize_t length;
char *newcon = NULL; char *newcon = NULL;
u32 len; u32 len;
int nargs;
length = task_has_security(current, SECURITY__COMPUTE_CREATE); length = task_has_security(current, SECURITY__COMPUTE_CREATE);
if (length) if (length)
...@@ -773,9 +776,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -773,9 +776,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if (!tcon) if (!tcon)
goto out; goto out;
length = -ENOMEM;
namebuf = kzalloc(size + 1, GFP_KERNEL);
if (!namebuf)
goto out;
length = -EINVAL; length = -EINVAL;
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
if (nargs < 3 || nargs > 4)
goto out; goto out;
if (nargs == 4)
objname = namebuf;
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
if (length) if (length)
...@@ -785,7 +796,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -785,7 +796,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if (length) if (length)
goto out; goto out;
length = security_transition_sid_user(ssid, tsid, tclass, &newsid); length = security_transition_sid_user(ssid, tsid, tclass,
objname, &newsid);
if (length) if (length)
goto out; goto out;
...@@ -804,6 +816,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -804,6 +816,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
length = len; length = len;
out: out:
kfree(newcon); kfree(newcon);
kfree(namebuf);
kfree(tcon); kfree(tcon);
kfree(scon); kfree(scon);
return length; return length;
...@@ -1901,6 +1914,7 @@ static struct file_system_type sel_fs_type = { ...@@ -1901,6 +1914,7 @@ static struct file_system_type sel_fs_type = {
}; };
struct vfsmount *selinuxfs_mount; struct vfsmount *selinuxfs_mount;
static struct kobject *selinuxfs_kobj;
static int __init init_sel_fs(void) static int __init init_sel_fs(void)
{ {
...@@ -1908,9 +1922,16 @@ static int __init init_sel_fs(void) ...@@ -1908,9 +1922,16 @@ static int __init init_sel_fs(void)
if (!selinux_enabled) if (!selinux_enabled)
return 0; return 0;
selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
if (!selinuxfs_kobj)
return -ENOMEM;
err = register_filesystem(&sel_fs_type); err = register_filesystem(&sel_fs_type);
if (err) if (err) {
kobject_put(selinuxfs_kobj);
return err; return err;
}
selinuxfs_mount = kern_mount(&sel_fs_type); selinuxfs_mount = kern_mount(&sel_fs_type);
if (IS_ERR(selinuxfs_mount)) { if (IS_ERR(selinuxfs_mount)) {
...@@ -1927,6 +1948,7 @@ __initcall(init_sel_fs); ...@@ -1927,6 +1948,7 @@ __initcall(init_sel_fs);
#ifdef CONFIG_SECURITY_SELINUX_DISABLE #ifdef CONFIG_SECURITY_SELINUX_DISABLE
void exit_sel_fs(void) void exit_sel_fs(void)
{ {
kobject_put(selinuxfs_kobj);
unregister_filesystem(&sel_fs_type); unregister_filesystem(&sel_fs_type);
} }
#endif #endif
This diff is collapsed.
...@@ -72,17 +72,20 @@ struct role_datum { ...@@ -72,17 +72,20 @@ struct role_datum {
struct role_trans { struct role_trans {
u32 role; /* current role */ u32 role; /* current role */
u32 type; /* program executable type */ u32 type; /* program executable type, or new object type */
u32 tclass; /* process class, or new object class */
u32 new_role; /* new role */ u32 new_role; /* new role */
struct role_trans *next; struct role_trans *next;
}; };
struct filename_trans { struct filename_trans {
struct filename_trans *next;
u32 stype; /* current process */ u32 stype; /* current process */
u32 ttype; /* parent dir context */ u32 ttype; /* parent dir context */
u16 tclass; /* class of new object */ u16 tclass; /* class of new object */
const char *name; /* last path component */ const char *name; /* last path component */
};
struct filename_trans_datum {
u32 otype; /* expected of new object */ u32 otype; /* expected of new object */
}; };
...@@ -227,7 +230,10 @@ struct policydb { ...@@ -227,7 +230,10 @@ struct policydb {
struct role_trans *role_tr; struct role_trans *role_tr;
/* file transitions with the last path component */ /* file transitions with the last path component */
struct filename_trans *filename_trans; /* quickly exclude lookups when parent ttype has no rules */
struct ebitmap filename_trans_ttypes;
/* actual set of filename_trans rules */
struct hashtab *filename_trans;
/* bools indexed by (value - 1) */ /* bools indexed by (value - 1) */
struct cond_bool_datum **bool_val_to_struct; struct cond_bool_datum **bool_val_to_struct;
......
...@@ -1359,26 +1359,35 @@ static int compute_sid_handle_invalid_context( ...@@ -1359,26 +1359,35 @@ static int compute_sid_handle_invalid_context(
} }
static void filename_compute_type(struct policydb *p, struct context *newcontext, static void filename_compute_type(struct policydb *p, struct context *newcontext,
u32 scon, u32 tcon, u16 tclass, u32 stype, u32 ttype, u16 tclass,
const struct qstr *qstr) const char *objname)
{ {
struct filename_trans *ft; struct filename_trans ft;
for (ft = p->filename_trans; ft; ft = ft->next) { struct filename_trans_datum *otype;
if (ft->stype == scon &&
ft->ttype == tcon && /*
ft->tclass == tclass && * Most filename trans rules are going to live in specific directories
!strcmp(ft->name, qstr->name)) { * like /dev or /var/run. This bitmap will quickly skip rule searches
newcontext->type = ft->otype; * if the ttype does not contain any rules.
return; */
} if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
} return;
ft.stype = stype;
ft.ttype = ttype;
ft.tclass = tclass;
ft.name = objname;
otype = hashtab_search(p->filename_trans, &ft);
if (otype)
newcontext->type = otype->otype;
} }
static int security_compute_sid(u32 ssid, static int security_compute_sid(u32 ssid,
u32 tsid, u32 tsid,
u16 orig_tclass, u16 orig_tclass,
u32 specified, u32 specified,
const struct qstr *qstr, const char *objname,
u32 *out_sid, u32 *out_sid,
bool kern) bool kern)
{ {
...@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid, ...@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid,
newcontext.type = avdatum->data; newcontext.type = avdatum->data;
} }
/* if we have a qstr this is a file trans check so check those rules */ /* if we have a objname this is a file trans check so check those rules */
if (qstr) if (objname)
filename_compute_type(&policydb, &newcontext, scontext->type, filename_compute_type(&policydb, &newcontext, scontext->type,
tcontext->type, tclass, qstr); tcontext->type, tclass, objname);
/* Check for class-specific changes. */ /* Check for class-specific changes. */
if (tclass == policydb.process_class) { if (specified & AVTAB_TRANSITION) {
if (specified & AVTAB_TRANSITION) { /* Look for a role transition rule. */
/* Look for a role transition rule. */ for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
for (roletr = policydb.role_tr; roletr; if ((roletr->role == scontext->role) &&
roletr = roletr->next) { (roletr->type == tcontext->type) &&
if (roletr->role == scontext->role && (roletr->tclass == tclass)) {
roletr->type == tcontext->type) { /* Use the role transition rule. */
/* Use the role transition rule. */ newcontext.role = roletr->new_role;
newcontext.role = roletr->new_role; break;
break;
}
} }
} }
} }
...@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, ...@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid) const struct qstr *qstr, u32 *out_sid)
{ {
return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
qstr, out_sid, true); qstr ? qstr->name : NULL, out_sid, true);
} }
int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
const char *objname, u32 *out_sid)
{ {
return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
NULL, out_sid, false); objname, out_sid, false);
} }
/** /**
...@@ -3190,7 +3198,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) ...@@ -3190,7 +3198,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
* @len: length of data in bytes * @len: length of data in bytes
* *
*/ */
int security_read_policy(void **data, ssize_t *len) int security_read_policy(void **data, size_t *len)
{ {
int rc; int rc;
struct policy_file fp; struct policy_file fp;
......
...@@ -316,22 +316,17 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, ...@@ -316,22 +316,17 @@ 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, static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
struct dentry *d) struct dentry *d)
{ {
a->a.u.fs.path.dentry = d; a->a.u.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;
} }
static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
struct inode *i) 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, static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
struct path p) 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, static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
struct sock *sk) struct sock *sk)
......
...@@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry) ...@@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry)
int rc; int rc;
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
...@@ -407,7 +407,7 @@ static int smack_sb_mount(char *dev_name, struct path *path, ...@@ -407,7 +407,7 @@ static int smack_sb_mount(char *dev_name, struct path *path,
struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, *path); smk_ad_setfield_u_fs_path(&ad, *path);
return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
...@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags) ...@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
{ {
struct superblock_smack *sbp; struct superblock_smack *sbp;
struct smk_audit_info ad; struct smk_audit_info ad;
struct path path;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); path.dentry = mnt->mnt_root;
smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); path.mnt = mnt;
smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, path);
sbp = mnt->mnt_sb->s_security; sbp = mnt->mnt_sb->s_security;
return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 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,7 +566,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
struct smk_audit_info ad; struct smk_audit_info ad;
int rc; int rc;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode); isp = smk_of_inode(old_dentry->d_inode);
...@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) ...@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
struct smk_audit_info ad; struct smk_audit_info ad;
int rc; int rc;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, 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) ...@@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
struct smk_audit_info ad; struct smk_audit_info ad;
int rc; int rc;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
/* /*
...@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode, ...@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode,
char *isp; char *isp;
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
isp = smk_of_inode(old_dentry->d_inode); isp = smk_of_inode(old_dentry->d_inode);
...@@ -700,7 +703,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags) ...@@ -700,7 +703,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags)
/* May be droppable after audit */ /* May be droppable after audit */
if (flags & IPERM_FLAG_RCU) if (flags & IPERM_FLAG_RCU)
return -ECHILD; return -ECHILD;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
smk_ad_setfield_u_fs_inode(&ad, inode); smk_ad_setfield_u_fs_inode(&ad, inode);
return smk_curacc(smk_of_inode(inode), mask, &ad); return smk_curacc(smk_of_inode(inode), mask, &ad);
} }
...@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
*/ */
if (iattr->ia_valid & ATTR_FORCE) if (iattr->ia_valid & ATTR_FORCE)
return 0; return 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 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,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) static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
{ {
struct smk_audit_info ad; struct smk_audit_info ad;
struct path path;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); path.dentry = dentry;
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); path.mnt = mnt;
smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, path);
return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 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, ...@@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
} else } else
rc = cap_inode_setxattr(dentry, name, value, size, flags); rc = cap_inode_setxattr(dentry, name, value, size, flags);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
if (rc == 0) if (rc == 0)
...@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) ...@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
{ {
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 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,7 +883,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
} else } else
rc = cap_inode_removexattr(dentry, name); rc = cap_inode_removexattr(dentry, name);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
smk_ad_setfield_u_fs_path_dentry(&ad, dentry); smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
if (rc == 0) if (rc == 0)
rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
...@@ -1047,7 +1053,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, ...@@ -1047,7 +1053,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
int rc = 0; int rc = 0;
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path);
if (_IOC_DIR(cmd) & _IOC_WRITE) if (_IOC_DIR(cmd) & _IOC_WRITE)
...@@ -1070,8 +1076,8 @@ static int smack_file_lock(struct file *file, unsigned int cmd) ...@@ -1070,8 +1076,8 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
{ {
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); smk_ad_setfield_u_fs_path(&ad, file->f_path);
return smk_curacc(file->f_security, MAY_WRITE, &ad); return smk_curacc(file->f_security, MAY_WRITE, &ad);
} }
...@@ -1089,7 +1095,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, ...@@ -1089,7 +1095,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
struct smk_audit_info ad; struct smk_audit_info ad;
int rc; int rc;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path);
switch (cmd) { switch (cmd) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment