summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/lib.c1
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/device_cgroup.c8
-rw-r--r--security/keys/request_key.c6
-rw-r--r--security/selinux/hooks.c25
-rw-r--r--security/selinux/selinuxfs.c37
-rw-r--r--security/selinux/ss/policydb.c3
-rw-r--r--security/tomoyo/mount.c2
8 files changed, 61 insertions, 23 deletions
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 506d2baf6147..b82e383beb77 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -12,6 +12,7 @@
* License.
*/
+#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index ec1bcecf2cda..3d2fd141dff7 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -612,7 +612,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
static int apparmor_task_setrlimit(struct task_struct *task,
unsigned int resource, struct rlimit *new_rlim)
{
- struct aa_profile *profile = aa_current_profile();
+ struct aa_profile *profile = __aa_current_profile();
int error = 0;
if (!unconfined(profile))
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index cd1f779fa51d..1be68269e1c2 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -474,17 +474,11 @@ struct cgroup_subsys devices_subsys = {
.subsys_id = devices_subsys_id,
};
-int devcgroup_inode_permission(struct inode *inode, int mask)
+int __devcgroup_inode_permission(struct inode *inode, int mask)
{
struct dev_cgroup *dev_cgroup;
struct dev_whitelist_item *wh;
- dev_t device = inode->i_rdev;
- if (!device)
- return 0;
- if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode))
- return 0;
-
rcu_read_lock();
dev_cgroup = task_devcgroup(current);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index d31862e0aa1c..82465328c39b 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -71,9 +71,8 @@ EXPORT_SYMBOL(complete_request_key);
* This is called in context of freshly forked kthread before kernel_execve(),
* so we can simply install the desired session_keyring at this point.
*/
-static int umh_keys_init(struct subprocess_info *info)
+static int umh_keys_init(struct subprocess_info *info, struct cred *cred)
{
- struct cred *cred = (struct cred*)current_cred();
struct key *keyring = info->data;
return install_session_keyring_to_cred(cred, keyring);
@@ -470,7 +469,7 @@ static struct key *construct_key_and_link(struct key_type *type,
} else if (ret == -EINPROGRESS) {
ret = 0;
} else {
- key = ERR_PTR(ret);
+ goto couldnt_alloc_key;
}
key_put(dest_keyring);
@@ -480,6 +479,7 @@ static struct key *construct_key_and_link(struct key_type *type,
construction_failed:
key_negate_and_link(key, key_negative_timeout, NULL, NULL);
key_put(key);
+couldnt_alloc_key:
key_put(dest_keyring);
kleave(" = %d", ret);
return ERR_PTR(ret);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fc07d18ed6fc..422515509f3d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1476,7 +1476,6 @@ static int inode_has_perm(const struct cred *cred,
unsigned flags)
{
struct inode_security_struct *isec;
- struct common_audit_data ad;
u32 sid;
validate_creds(cred);
@@ -1487,15 +1486,21 @@ static int inode_has_perm(const struct cred *cred,
sid = cred_sid(cred);
isec = inode->i_security;
- if (!adp) {
- adp = &ad;
- COMMON_AUDIT_DATA_INIT(&ad, INODE);
- ad.u.inode = inode;
- }
-
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;
+
+ COMMON_AUDIT_DATA_INIT(&ad, INODE);
+ ad.u.inode = inode;
+ 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. */
@@ -2122,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
struct tty_file_private, list);
file = file_priv->file;
inode = file->f_path.dentry->d_inode;
- if (inode_has_perm(cred, inode,
- FILE__READ | FILE__WRITE, NULL, 0)) {
+ if (inode_has_perm_noadp(cred, inode,
+ FILE__READ | FILE__WRITE, 0)) {
drop_tty = 1;
}
}
@@ -3228,7 +3233,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(cred, inode, open_file_to_av(file), NULL, 0);
+ return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
}
/* task security operations */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 77d44138864f..35459340019e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -29,6 +29,7 @@
#include <linux/audit.h>
#include <linux/uaccess.h>
#include <linux/kobject.h>
+#include <linux/ctype.h>
/* selinuxfs pseudo filesystem for exporting the security policy API.
Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -751,6 +752,14 @@ out:
return length;
}
+static inline int hexcode_to_int(int code) {
+ if (code == '\0' || !isxdigit(code))
+ return -1;
+ if (isdigit(code))
+ return code - '0';
+ return tolower(code) - 'a' + 10;
+}
+
static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{
char *scon = NULL, *tcon = NULL;
@@ -785,8 +794,34 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
if (nargs < 3 || nargs > 4)
goto out;
- if (nargs == 4)
+ if (nargs == 4) {
+ /*
+ * If and when the name of new object to be queried contains
+ * either whitespace or multibyte characters, they shall be
+ * encoded based on the percentage-encoding rule.
+ * If not encoded, the sscanf logic picks up only left-half
+ * of the supplied name; splitted by a whitespace unexpectedly.
+ */
+ char *r, *w;
+ int c1, c2;
+
+ r = w = namebuf;
+ do {
+ c1 = *r++;
+ if (c1 == '+')
+ c1 = ' ';
+ else if (c1 == '%') {
+ if ((c1 = hexcode_to_int(*r++)) < 0)
+ goto out;
+ if ((c2 = hexcode_to_int(*r++)) < 0)
+ goto out;
+ c1 = (c1 << 4) | c2;
+ }
+ *w++ = c1;
+ } while (c1 != '\0');
+
objname = namebuf;
+ }
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
if (length)
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 102e9ec1b77a..d246aca3f4fb 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3222,6 +3222,9 @@ static int filename_trans_write(struct policydb *p, void *fp)
__le32 buf[1];
int rc;
+ if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
+ return 0;
+
nel = 0;
rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
if (rc)
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 162a864dba24..9fc2e15841c9 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -138,7 +138,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
}
if (need_dev) {
/* Get mount point or device file. */
- if (kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
+ if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
error = -ENOENT;
goto out;
}