diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/Kconfig | 2 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 40 | ||||
-rw-r--r-- | security/apparmor/path.c | 9 | ||||
-rw-r--r-- | security/capability.c | 3 | ||||
-rw-r--r-- | security/commoncap.c | 2 | ||||
-rw-r--r-- | security/keys/internal.h | 5 | ||||
-rw-r--r-- | security/keys/request_key.c | 2 | ||||
-rw-r--r-- | security/security.c | 21 | ||||
-rw-r--r-- | security/selinux/Makefile | 2 | ||||
-rw-r--r-- | security/selinux/hooks.c | 21 |
10 files changed, 66 insertions, 41 deletions
diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig index 72555b9ca7d..9b9013b2e32 100644 --- a/security/apparmor/Kconfig +++ b/security/apparmor/Kconfig @@ -1,6 +1,6 @@ config SECURITY_APPARMOR bool "AppArmor support" - depends on SECURITY + depends on SECURITY && NET select AUDIT select SECURITY_PATH select SECURITYFS diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8db33a8b50c..f73e2c20421 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -607,8 +607,8 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, return error; } -static int apparmor_task_setrlimit(unsigned int resource, - struct rlimit *new_rlim) +static int apparmor_task_setrlimit(struct task_struct *task, + unsigned int resource, struct rlimit *new_rlim) { struct aa_profile *profile = aa_current_profile(); int error = 0; @@ -667,17 +667,29 @@ static struct security_operations apparmor_ops = { * AppArmor sysfs module parameters */ -static int param_set_aabool(const char *val, struct kernel_param *kp); -static int param_get_aabool(char *buffer, struct kernel_param *kp); +static int param_set_aabool(const char *val, const struct kernel_param *kp); +static int param_get_aabool(char *buffer, const struct kernel_param *kp); #define param_check_aabool(name, p) __param_check(name, p, int) +static struct kernel_param_ops param_ops_aabool = { + .set = param_set_aabool, + .get = param_get_aabool +}; -static int param_set_aauint(const char *val, struct kernel_param *kp); -static int param_get_aauint(char *buffer, struct kernel_param *kp); +static int param_set_aauint(const char *val, const struct kernel_param *kp); +static int param_get_aauint(char *buffer, const struct kernel_param *kp); #define param_check_aauint(name, p) __param_check(name, p, int) +static struct kernel_param_ops param_ops_aauint = { + .set = param_set_aauint, + .get = param_get_aauint +}; -static int param_set_aalockpolicy(const char *val, struct kernel_param *kp); -static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp); +static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp); +static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp); #define param_check_aalockpolicy(name, p) __param_check(name, p, int) +static struct kernel_param_ops param_ops_aalockpolicy = { + .set = param_set_aalockpolicy, + .get = param_get_aalockpolicy +}; static int param_set_audit(const char *val, struct kernel_param *kp); static int param_get_audit(char *buffer, struct kernel_param *kp); @@ -751,7 +763,7 @@ static int __init apparmor_enabled_setup(char *str) __setup("apparmor=", apparmor_enabled_setup); /* set global flag turning off the ability to load policy */ -static int param_set_aalockpolicy(const char *val, struct kernel_param *kp) +static int param_set_aalockpolicy(const char *val, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; @@ -760,35 +772,35 @@ static int param_set_aalockpolicy(const char *val, struct kernel_param *kp) return param_set_bool(val, kp); } -static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp) +static int param_get_aalockpolicy(char *buffer, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; return param_get_bool(buffer, kp); } -static int param_set_aabool(const char *val, struct kernel_param *kp) +static int param_set_aabool(const char *val, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; return param_set_bool(val, kp); } -static int param_get_aabool(char *buffer, struct kernel_param *kp) +static int param_get_aabool(char *buffer, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; return param_get_bool(buffer, kp); } -static int param_set_aauint(const char *val, struct kernel_param *kp) +static int param_set_aauint(const char *val, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; return param_set_uint(val, kp); } -static int param_get_aauint(char *buffer, struct kernel_param *kp) +static int param_get_aauint(char *buffer, const struct kernel_param *kp) { if (!capable(CAP_MAC_ADMIN)) return -EPERM; diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 96bab9469d4..19358dc1460 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -62,19 +62,14 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, int deleted, connected; int error = 0; - /* Get the root we want to resolve too */ + /* Get the root we want to resolve too, released below */ if (flags & PATH_CHROOT_REL) { /* resolve paths relative to chroot */ - read_lock(¤t->fs->lock); - root = current->fs->root; - /* released below */ - path_get(&root); - read_unlock(¤t->fs->lock); + get_fs_root(current->fs, &root); } else { /* resolve paths relative to namespace */ root.mnt = current->nsproxy->mnt_ns->root; root.dentry = root.mnt->mnt_root; - /* released below */ path_get(&root); } diff --git a/security/capability.c b/security/capability.c index a0bbf30fb6d..95a6599a37b 100644 --- a/security/capability.c +++ b/security/capability.c @@ -411,7 +411,8 @@ static int cap_task_getioprio(struct task_struct *p) return 0; } -static int cap_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +static int cap_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { return 0; } diff --git a/security/commoncap.c b/security/commoncap.c index 4e015996dd4..9d172e6e330 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -40,7 +40,7 @@ * * Warn if that happens, once per boot. */ -static void warn_setuid_and_fcaps_mixed(char *fname) +static void warn_setuid_and_fcaps_mixed(const char *fname) { static int warned; if (!warned) { diff --git a/security/keys/internal.h b/security/keys/internal.h index addb67b169f..56a133d8f37 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -15,11 +15,6 @@ #include <linux/sched.h> #include <linux/key-type.h> -static inline __attribute__((format(printf, 1, 2))) -void no_printk(const char *fmt, ...) -{ -} - #ifdef __KDEBUG #define kenter(FMT, ...) \ printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__) diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 0d26f689bd7..0088dd8bf68 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -537,6 +537,8 @@ int wait_for_key_construction(struct key *key, bool intr) intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); if (ret < 0) return ret; + if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + return -ENOKEY; return key_validate(key); } EXPORT_SYMBOL(wait_for_key_construction); diff --git a/security/security.c b/security/security.c index e8c87b8601b..c53949f17d9 100644 --- a/security/security.c +++ b/security/security.c @@ -619,7 +619,13 @@ void security_inode_getsecid(const struct inode *inode, u32 *secid) int security_file_permission(struct file *file, int mask) { - return security_ops->file_permission(file, mask); + int ret; + + ret = security_ops->file_permission(file, mask); + if (ret) + return ret; + + return fsnotify_perm(file, mask); } int security_file_alloc(struct file *file) @@ -683,7 +689,13 @@ int security_file_receive(struct file *file) int security_dentry_open(struct file *file, const struct cred *cred) { - return security_ops->dentry_open(file, cred); + int ret; + + ret = security_ops->dentry_open(file, cred); + if (ret) + return ret; + + return fsnotify_perm(file, MAY_OPEN); } int security_task_create(unsigned long clone_flags) @@ -768,9 +780,10 @@ int security_task_getioprio(struct task_struct *p) return security_ops->task_getioprio(p); } -int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +int security_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { - return security_ops->task_setrlimit(resource, new_rlim); + return security_ops->task_setrlimit(p, resource, new_rlim); } int security_task_setscheduler(struct task_struct *p, diff --git a/security/selinux/Makefile b/security/selinux/Makefile index f013982df41..58d80f3bd6f 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -25,6 +25,6 @@ $(obj)/avc.o: $(obj)/flask.h quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h -targets += flask.h +targets += flask.h av_permissions.h $(obj)/flask.h: $(src)/include/classmap.h FORCE $(call if_changed,flask) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9b40f4c0ac7..4796ddd4e72 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2170,8 +2170,9 @@ static inline void flush_unauthorized_files(const struct cred *cred, tty = get_current_tty(); if (tty) { - file_list_lock(); + 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. @@ -2179,14 +2180,16 @@ static inline void flush_unauthorized_files(const struct cred *cred, 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 = list_first_entry(&tty->tty_files, struct file, f_u.fu_list); + 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(cred, inode, FILE__READ | FILE__WRITE, NULL)) { drop_tty = 1; } } - file_list_unlock(); + spin_unlock(&tty_files_lock); tty_kref_put(tty); } /* Reset controlling tty. */ @@ -2284,12 +2287,15 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS, PROCESS__RLIMITINH, NULL); if (rc) { + /* protect against do_prlimit() */ + task_lock(current); for (i = 0; i < RLIM_NLIMITS; i++) { rlim = current->signal->rlim + i; initrlim = init_task.signal->rlim + i; rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); } - update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur); + task_unlock(current); + update_rlimit_cpu(current, rlimit(RLIMIT_CPU)); } } @@ -3333,16 +3339,17 @@ static int selinux_task_getioprio(struct task_struct *p) return current_has_perm(p, PROCESS__GETSCHED); } -static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) +static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource, + struct rlimit *new_rlim) { - struct rlimit *old_rlim = current->signal->rlim + resource; + struct rlimit *old_rlim = p->signal->rlim + resource; /* Control the ability to change the hard limit (whether lowering or raising it), so that the hard limit can later be used as a safe reset point for the soft limit upon context transitions. See selinux_bprm_committing_creds. */ if (old_rlim->rlim_max != new_rlim->rlim_max) - return current_has_perm(current, PROCESS__SETRLIMIT); + return current_has_perm(p, PROCESS__SETRLIMIT); return 0; } |