|
@@ -1420,16 +1420,13 @@ static int cred_has_capability(const struct cred *cred,
|
|
|
int cap, int audit)
|
|
|
{
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct av_decision avd;
|
|
|
u16 sclass;
|
|
|
u32 sid = cred_sid(cred);
|
|
|
u32 av = CAP_TO_MASK(cap);
|
|
|
int rc;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, CAP);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
- ad.tsk = current;
|
|
|
+ ad.type = LSM_AUDIT_DATA_CAP;
|
|
|
ad.u.cap = cap;
|
|
|
|
|
|
switch (CAP_TO_INDEX(cap)) {
|
|
@@ -1488,20 +1485,6 @@ static int inode_has_perm(const struct cred *cred,
|
|
|
return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
|
|
|
}
|
|
|
|
|
|
-static int inode_has_perm_noadp(const struct cred *cred,
|
|
|
- struct inode *inode,
|
|
|
- u32 perms,
|
|
|
- unsigned flags)
|
|
|
-{
|
|
|
- struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
-
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, INODE);
|
|
|
- ad.u.inode = inode;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
- return inode_has_perm(cred, inode, perms, &ad, flags);
|
|
|
-}
|
|
|
-
|
|
|
/* Same as inode_has_perm, but pass explicit audit data containing
|
|
|
the dentry to help the auditing code to more easily generate the
|
|
|
pathname if needed. */
|
|
@@ -1511,11 +1494,9 @@ static inline int dentry_has_perm(const struct cred *cred,
|
|
|
{
|
|
|
struct inode *inode = dentry->d_inode;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = dentry;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
return inode_has_perm(cred, inode, av, &ad, 0);
|
|
|
}
|
|
|
|
|
@@ -1528,11 +1509,9 @@ static inline int path_has_perm(const struct cred *cred,
|
|
|
{
|
|
|
struct inode *inode = path->dentry->d_inode;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
|
|
|
+ ad.type = LSM_AUDIT_DATA_PATH;
|
|
|
ad.u.path = *path;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
return inode_has_perm(cred, inode, av, &ad, 0);
|
|
|
}
|
|
|
|
|
@@ -1551,13 +1530,11 @@ static int file_has_perm(const struct cred *cred,
|
|
|
struct file_security_struct *fsec = file->f_security;
|
|
|
struct inode *inode = file->f_path.dentry->d_inode;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = cred_sid(cred);
|
|
|
int rc;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
|
|
|
+ ad.type = LSM_AUDIT_DATA_PATH;
|
|
|
ad.u.path = file->f_path;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
|
|
|
if (sid != fsec->sid) {
|
|
|
rc = avc_has_perm(sid, fsec->sid,
|
|
@@ -1587,7 +1564,6 @@ static int may_create(struct inode *dir,
|
|
|
struct superblock_security_struct *sbsec;
|
|
|
u32 sid, newsid;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
int rc;
|
|
|
|
|
|
dsec = dir->i_security;
|
|
@@ -1596,9 +1572,8 @@ static int may_create(struct inode *dir,
|
|
|
sid = tsec->sid;
|
|
|
newsid = tsec->create_sid;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = dentry;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
|
|
|
rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
|
|
|
DIR__ADD_NAME | DIR__SEARCH,
|
|
@@ -1643,7 +1618,6 @@ static int may_link(struct inode *dir,
|
|
|
{
|
|
|
struct inode_security_struct *dsec, *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
u32 av;
|
|
|
int rc;
|
|
@@ -1651,9 +1625,8 @@ static int may_link(struct inode *dir,
|
|
|
dsec = dir->i_security;
|
|
|
isec = dentry->d_inode->i_security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = dentry;
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
|
|
|
av = DIR__SEARCH;
|
|
|
av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
|
|
@@ -1688,7 +1661,6 @@ static inline int may_rename(struct inode *old_dir,
|
|
|
{
|
|
|
struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
u32 av;
|
|
|
int old_is_dir, new_is_dir;
|
|
@@ -1699,8 +1671,7 @@ 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, DENTRY);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
|
|
|
ad.u.dentry = old_dentry;
|
|
|
rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
|
|
@@ -1986,7 +1957,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
|
|
|
struct task_security_struct *new_tsec;
|
|
|
struct inode_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct inode *inode = bprm->file->f_path.dentry->d_inode;
|
|
|
int rc;
|
|
|
|
|
@@ -2016,6 +1986,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
|
|
|
new_tsec->sid = old_tsec->exec_sid;
|
|
|
/* Reset exec SID on execve. */
|
|
|
new_tsec->exec_sid = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Minimize confusion: if no_new_privs and a transition is
|
|
|
+ * explicitly requested, then fail the exec.
|
|
|
+ */
|
|
|
+ if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
|
|
|
+ return -EPERM;
|
|
|
} else {
|
|
|
/* Check for a default transition on this program. */
|
|
|
rc = security_transition_sid(old_tsec->sid, isec->sid,
|
|
@@ -2025,11 +2002,11 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, PATH);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_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) ||
|
|
|
+ (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS))
|
|
|
new_tsec->sid = old_tsec->sid;
|
|
|
|
|
|
if (new_tsec->sid == old_tsec->sid) {
|
|
@@ -2115,8 +2092,6 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
|
|
|
static inline void flush_unauthorized_files(const struct cred *cred,
|
|
|
struct files_struct *files)
|
|
|
{
|
|
|
- struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct file *file, *devnull = NULL;
|
|
|
struct tty_struct *tty;
|
|
|
struct fdtable *fdt;
|
|
@@ -2128,21 +2103,17 @@ static inline void flush_unauthorized_files(const struct cred *cred,
|
|
|
spin_lock(&tty_files_lock);
|
|
|
if (!list_empty(&tty->tty_files)) {
|
|
|
struct tty_file_private *file_priv;
|
|
|
- struct inode *inode;
|
|
|
|
|
|
/* Revalidate access to controlling tty.
|
|
|
- Use inode_has_perm on the tty inode directly rather
|
|
|
+ Use path_has_perm on the tty path directly rather
|
|
|
than using file_has_perm, as this particular open
|
|
|
file may belong to another process and we are only
|
|
|
interested in the inode-based check here. */
|
|
|
file_priv = list_first_entry(&tty->tty_files,
|
|
|
struct tty_file_private, list);
|
|
|
file = file_priv->file;
|
|
|
- inode = file->f_path.dentry->d_inode;
|
|
|
- if (inode_has_perm_noadp(cred, inode,
|
|
|
- FILE__READ | FILE__WRITE, 0)) {
|
|
|
+ if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE))
|
|
|
drop_tty = 1;
|
|
|
- }
|
|
|
}
|
|
|
spin_unlock(&tty_files_lock);
|
|
|
tty_kref_put(tty);
|
|
@@ -2152,10 +2123,6 @@ static inline void flush_unauthorized_files(const struct cred *cred,
|
|
|
no_tty();
|
|
|
|
|
|
/* Revalidate access to inherited open files. */
|
|
|
-
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, INODE);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
-
|
|
|
spin_lock(&files->file_lock);
|
|
|
for (;;) {
|
|
|
unsigned long set, i;
|
|
@@ -2492,7 +2459,6 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
|
|
|
{
|
|
|
const struct cred *cred = current_cred();
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
int rc;
|
|
|
|
|
|
rc = superblock_doinit(sb, data);
|
|
@@ -2503,8 +2469,7 @@ 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, DENTRY);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = sb->s_root;
|
|
|
return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
|
|
|
}
|
|
@@ -2513,10 +2478,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
|
|
|
{
|
|
|
const struct cred *cred = current_cred();
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = dentry->d_sb->s_root;
|
|
|
return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
|
|
|
}
|
|
@@ -2676,14 +2639,35 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
|
|
|
return dentry_has_perm(cred, dentry, FILE__READ);
|
|
|
}
|
|
|
|
|
|
+static noinline int audit_inode_permission(struct inode *inode,
|
|
|
+ u32 perms, u32 audited, u32 denied,
|
|
|
+ unsigned flags)
|
|
|
+{
|
|
|
+ struct common_audit_data ad;
|
|
|
+ struct inode_security_struct *isec = inode->i_security;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ ad.type = LSM_AUDIT_DATA_INODE;
|
|
|
+ ad.u.inode = inode;
|
|
|
+
|
|
|
+ rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
|
|
|
+ audited, denied, &ad, flags);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int selinux_inode_permission(struct inode *inode, int mask)
|
|
|
{
|
|
|
const struct cred *cred = current_cred();
|
|
|
- struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 perms;
|
|
|
bool from_access;
|
|
|
unsigned flags = mask & MAY_NOT_BLOCK;
|
|
|
+ struct inode_security_struct *isec;
|
|
|
+ u32 sid;
|
|
|
+ struct av_decision avd;
|
|
|
+ int rc, rc2;
|
|
|
+ u32 audited, denied;
|
|
|
|
|
|
from_access = mask & MAY_ACCESS;
|
|
|
mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
|
|
@@ -2692,22 +2676,34 @@ static int selinux_inode_permission(struct inode *inode, int mask)
|
|
|
if (!mask)
|
|
|
return 0;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, INODE);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
- ad.u.inode = inode;
|
|
|
+ validate_creds(cred);
|
|
|
|
|
|
- if (from_access)
|
|
|
- ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS;
|
|
|
+ if (unlikely(IS_PRIVATE(inode)))
|
|
|
+ return 0;
|
|
|
|
|
|
perms = file_mask_to_av(inode->i_mode, mask);
|
|
|
|
|
|
- return inode_has_perm(cred, inode, perms, &ad, flags);
|
|
|
+ sid = cred_sid(cred);
|
|
|
+ isec = inode->i_security;
|
|
|
+
|
|
|
+ rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
|
|
|
+ audited = avc_audit_required(perms, &avd, rc,
|
|
|
+ from_access ? FILE__AUDIT_ACCESS : 0,
|
|
|
+ &denied);
|
|
|
+ if (likely(!audited))
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
|
|
|
+ if (rc2)
|
|
|
+ return rc2;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
|
{
|
|
|
const struct cred *cred = current_cred();
|
|
|
unsigned int ia_valid = iattr->ia_valid;
|
|
|
+ __u32 av = FILE__WRITE;
|
|
|
|
|
|
/* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
|
|
|
if (ia_valid & ATTR_FORCE) {
|
|
@@ -2721,7 +2717,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
|
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
|
|
|
return dentry_has_perm(cred, dentry, FILE__SETATTR);
|
|
|
|
|
|
- return dentry_has_perm(cred, dentry, FILE__WRITE);
|
|
|
+ if (ia_valid & ATTR_SIZE)
|
|
|
+ av |= FILE__OPEN;
|
|
|
+
|
|
|
+ return dentry_has_perm(cred, dentry, av);
|
|
|
}
|
|
|
|
|
|
static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
|
|
@@ -2763,7 +2762,6 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|
|
struct inode_security_struct *isec = inode->i_security;
|
|
|
struct superblock_security_struct *sbsec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 newsid, sid = current_sid();
|
|
|
int rc = 0;
|
|
|
|
|
@@ -2777,8 +2775,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|
|
if (!inode_owner_or_capable(inode))
|
|
|
return -EPERM;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_DENTRY;
|
|
|
ad.u.dentry = dentry;
|
|
|
|
|
|
rc = avc_has_perm(sid, isec->sid, isec->sclass,
|
|
@@ -2788,8 +2785,25 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|
|
|
|
|
rc = security_context_to_sid(value, size, &newsid);
|
|
|
if (rc == -EINVAL) {
|
|
|
- if (!capable(CAP_MAC_ADMIN))
|
|
|
+ if (!capable(CAP_MAC_ADMIN)) {
|
|
|
+ struct audit_buffer *ab;
|
|
|
+ size_t audit_size;
|
|
|
+ const char *str;
|
|
|
+
|
|
|
+ /* We strip a nul only if it is at the end, otherwise the
|
|
|
+ * context contains a nul and we should audit that */
|
|
|
+ str = value;
|
|
|
+ if (str[size - 1] == '\0')
|
|
|
+ audit_size = size - 1;
|
|
|
+ else
|
|
|
+ audit_size = size;
|
|
|
+ ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
|
|
|
+ audit_log_format(ab, "op=setxattr invalid_context=");
|
|
|
+ audit_log_n_untrustedstring(ab, value, audit_size);
|
|
|
+ audit_log_end(ab);
|
|
|
+
|
|
|
return rc;
|
|
|
+ }
|
|
|
rc = security_context_to_sid_force(value, size, &newsid);
|
|
|
}
|
|
|
if (rc)
|
|
@@ -2969,7 +2983,7 @@ static int selinux_file_permission(struct file *file, int mask)
|
|
|
|
|
|
if (sid == fsec->sid && fsec->isid == isec->sid &&
|
|
|
fsec->pseqno == avc_policy_seqno())
|
|
|
- /* No change since dentry_open check. */
|
|
|
+ /* No change since file_open check. */
|
|
|
return 0;
|
|
|
|
|
|
return selinux_revalidate_file_permission(file, mask);
|
|
@@ -3228,15 +3242,13 @@ static int selinux_file_receive(struct file *file)
|
|
|
return file_has_perm(cred, file, file_to_av(file));
|
|
|
}
|
|
|
|
|
|
-static int selinux_dentry_open(struct file *file, const struct cred *cred)
|
|
|
+static int selinux_file_open(struct file *file, const struct cred *cred)
|
|
|
{
|
|
|
struct file_security_struct *fsec;
|
|
|
- struct inode *inode;
|
|
|
struct inode_security_struct *isec;
|
|
|
|
|
|
- inode = file->f_path.dentry->d_inode;
|
|
|
fsec = file->f_security;
|
|
|
- isec = inode->i_security;
|
|
|
+ isec = file->f_path.dentry->d_inode->i_security;
|
|
|
/*
|
|
|
* Save inode label and policy sequence number
|
|
|
* at open-time so that selinux_file_permission
|
|
@@ -3254,7 +3266,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
|
|
|
* new inode label or new policy.
|
|
|
* This check is not redundant - do not remove.
|
|
|
*/
|
|
|
- return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
|
|
|
+ return path_has_perm(cred, &file->f_path, open_file_to_av(file));
|
|
|
}
|
|
|
|
|
|
/* task security operations */
|
|
@@ -3373,12 +3385,10 @@ static int selinux_kernel_module_request(char *kmod_name)
|
|
|
{
|
|
|
u32 sid;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
|
|
|
sid = task_sid(current);
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, KMOD);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_KMOD;
|
|
|
ad.u.kmod_name = kmod_name;
|
|
|
|
|
|
return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
|
|
@@ -3751,15 +3761,13 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
|
|
|
{
|
|
|
struct sk_security_struct *sksec = sk->sk_security;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
u32 tsid = task_sid(task);
|
|
|
|
|
|
if (sksec->sid == SECINITSID_KERNEL)
|
|
|
return 0;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->sk = sk;
|
|
|
|
|
@@ -3839,7 +3847,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
|
|
|
char *addrp;
|
|
|
struct sk_security_struct *sksec = sk->sk_security;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
struct sockaddr_in *addr4 = NULL;
|
|
|
struct sockaddr_in6 *addr6 = NULL;
|
|
@@ -3866,8 +3873,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
|
|
|
snum, &sid);
|
|
|
if (err)
|
|
|
goto out;
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->sport = htons(snum);
|
|
|
ad.u.net->family = family;
|
|
@@ -3901,8 +3907,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->sport = htons(snum);
|
|
|
ad.u.net->family = family;
|
|
@@ -3937,7 +3942,6 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
|
|
|
if (sksec->sclass == SECCLASS_TCP_SOCKET ||
|
|
|
sksec->sclass == SECCLASS_DCCP_SOCKET) {
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
struct sockaddr_in *addr4 = NULL;
|
|
|
struct sockaddr_in6 *addr6 = NULL;
|
|
@@ -3963,8 +3967,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
|
|
|
perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
|
|
|
TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->dport = htons(snum);
|
|
|
ad.u.net->family = sk->sk_family;
|
|
@@ -4056,12 +4059,10 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
|
|
|
struct sk_security_struct *sksec_other = other->sk_security;
|
|
|
struct sk_security_struct *sksec_new = newsk->sk_security;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
int err;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->sk = other;
|
|
|
|
|
@@ -4090,11 +4091,9 @@ static int selinux_socket_unix_may_send(struct socket *sock,
|
|
|
struct sk_security_struct *ssec = sock->sk->sk_security;
|
|
|
struct sk_security_struct *osec = other->sk->sk_security;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->sk = other->sk;
|
|
|
|
|
@@ -4132,12 +4131,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
|
|
|
struct sk_security_struct *sksec = sk->sk_security;
|
|
|
u32 sk_sid = sksec->sid;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
char *addrp;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->netif = skb->skb_iif;
|
|
|
ad.u.net->family = family;
|
|
@@ -4167,7 +4164,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
u16 family = sk->sk_family;
|
|
|
u32 sk_sid = sksec->sid;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
char *addrp;
|
|
|
u8 secmark_active;
|
|
@@ -4192,8 +4188,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|
|
if (!secmark_active && !peerlbl_active)
|
|
|
return 0;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->netif = skb->skb_iif;
|
|
|
ad.u.net->family = family;
|
|
@@ -4531,7 +4526,6 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
|
|
|
char *addrp;
|
|
|
u32 peer_sid;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
u8 secmark_active;
|
|
|
u8 netlbl_active;
|
|
@@ -4549,8 +4543,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
|
|
|
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
|
|
|
return NF_DROP;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->netif = ifindex;
|
|
|
ad.u.net->family = family;
|
|
@@ -4640,7 +4633,6 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
|
|
struct sock *sk = skb->sk;
|
|
|
struct sk_security_struct *sksec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
char *addrp;
|
|
|
u8 proto;
|
|
@@ -4649,8 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
|
|
return NF_ACCEPT;
|
|
|
sksec = sk->sk_security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->netif = ifindex;
|
|
|
ad.u.net->family = family;
|
|
@@ -4675,7 +4666,6 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
|
|
|
u32 peer_sid;
|
|
|
struct sock *sk;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
struct lsm_network_audit net = {0,};
|
|
|
char *addrp;
|
|
|
u8 secmark_active;
|
|
@@ -4722,8 +4712,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
|
|
|
secmark_perm = PACKET__SEND;
|
|
|
}
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, NET);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_NET;
|
|
|
ad.u.net = &net;
|
|
|
ad.u.net->netif = ifindex;
|
|
|
ad.u.net->family = family;
|
|
@@ -4841,13 +4830,11 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
|
|
|
isec = ipc_perms->security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = ipc_perms->key;
|
|
|
|
|
|
return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
|
|
@@ -4868,7 +4855,6 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
int rc;
|
|
|
|
|
@@ -4878,8 +4864,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
|
|
|
|
|
|
isec = msq->q_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = msq->q_perm.key;
|
|
|
|
|
|
rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
|
|
@@ -4900,13 +4885,11 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
|
|
|
isec = msq->q_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = msq->q_perm.key;
|
|
|
|
|
|
return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
|
|
@@ -4946,7 +4929,6 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct msg_security_struct *msec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
int rc;
|
|
|
|
|
@@ -4967,8 +4949,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = msq->q_perm.key;
|
|
|
|
|
|
/* Can this process write to the queue? */
|
|
@@ -4993,15 +4974,13 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct msg_security_struct *msec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = task_sid(target);
|
|
|
int rc;
|
|
|
|
|
|
isec = msq->q_perm.security;
|
|
|
msec = msg->security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = msq->q_perm.key;
|
|
|
|
|
|
rc = avc_has_perm(sid, isec->sid,
|
|
@@ -5017,7 +4996,6 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
int rc;
|
|
|
|
|
@@ -5027,8 +5005,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
|
|
|
|
|
|
isec = shp->shm_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = shp->shm_perm.key;
|
|
|
|
|
|
rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
|
|
@@ -5049,13 +5026,11 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
|
|
|
isec = shp->shm_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = shp->shm_perm.key;
|
|
|
|
|
|
return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
|
|
@@ -5113,7 +5088,6 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
int rc;
|
|
|
|
|
@@ -5123,8 +5097,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
|
|
|
|
|
|
isec = sma->sem_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = sma->sem_perm.key;
|
|
|
|
|
|
rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
|
|
@@ -5145,13 +5118,11 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg)
|
|
|
{
|
|
|
struct ipc_security_struct *isec;
|
|
|
struct common_audit_data ad;
|
|
|
- struct selinux_audit_data sad = {0,};
|
|
|
u32 sid = current_sid();
|
|
|
|
|
|
isec = sma->sem_perm.security;
|
|
|
|
|
|
- COMMON_AUDIT_DATA_INIT(&ad, IPC);
|
|
|
- ad.selinux_audit_data = &sad;
|
|
|
+ ad.type = LSM_AUDIT_DATA_IPC;
|
|
|
ad.u.ipc_id = sma->sem_perm.key;
|
|
|
|
|
|
return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
|
|
@@ -5331,8 +5302,23 @@ static int selinux_setprocattr(struct task_struct *p,
|
|
|
}
|
|
|
error = security_context_to_sid(value, size, &sid);
|
|
|
if (error == -EINVAL && !strcmp(name, "fscreate")) {
|
|
|
- if (!capable(CAP_MAC_ADMIN))
|
|
|
+ if (!capable(CAP_MAC_ADMIN)) {
|
|
|
+ struct audit_buffer *ab;
|
|
|
+ size_t audit_size;
|
|
|
+
|
|
|
+ /* We strip a nul only if it is at the end, otherwise the
|
|
|
+ * context contains a nul and we should audit that */
|
|
|
+ if (str[size - 1] == '\0')
|
|
|
+ audit_size = size - 1;
|
|
|
+ else
|
|
|
+ audit_size = size;
|
|
|
+ ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
|
|
|
+ audit_log_format(ab, "op=fscreate invalid_context=");
|
|
|
+ audit_log_n_untrustedstring(ab, value, audit_size);
|
|
|
+ audit_log_end(ab);
|
|
|
+
|
|
|
return error;
|
|
|
+ }
|
|
|
error = security_context_to_sid_force(value, size,
|
|
|
&sid);
|
|
|
}
|
|
@@ -5592,7 +5578,7 @@ static struct security_operations selinux_ops = {
|
|
|
.file_send_sigiotask = selinux_file_send_sigiotask,
|
|
|
.file_receive = selinux_file_receive,
|
|
|
|
|
|
- .dentry_open = selinux_dentry_open,
|
|
|
+ .file_open = selinux_file_open,
|
|
|
|
|
|
.task_create = selinux_task_create,
|
|
|
.cred_alloc_blank = selinux_cred_alloc_blank,
|