summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig35
-rw-r--r--security/apparmor/domain.c2
-rw-r--r--security/apparmor/policy.c2
-rw-r--r--security/commoncap.c5
-rw-r--r--security/integrity/evm/evm_main.c2
-rw-r--r--security/keys/dh.c2
-rw-r--r--security/keys/encrypted-keys/encrypted.c4
-rw-r--r--security/keys/internal.h1
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--security/keys/persistent.c2
-rw-r--r--security/keys/process_keys.c1
-rw-r--r--security/keys/request_key.c7
-rw-r--r--security/keys/trusted.c4
-rw-r--r--security/keys/user_defined.c6
-rw-r--r--security/selinux/hooks.c20
-rw-r--r--security/selinux/include/classmap.h4
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/selinuxfs.c8
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c4
-rw-r--r--security/smack/smack_lsm.c2
-rw-r--r--security/tomoyo/domain.c2
-rw-r--r--security/tomoyo/group.c2
-rw-r--r--security/tomoyo/util.c2
25 files changed, 95 insertions, 30 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 118f4549404e..d900f47eaa68 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -158,6 +158,41 @@ config HARDENED_USERCOPY_PAGESPAN
been removed. This config is intended to be used only while
trying to find such users.
+config STATIC_USERMODEHELPER
+ bool "Force all usermode helper calls through a single binary"
+ help
+ By default, the kernel can call many different userspace
+ binary programs through the "usermode helper" kernel
+ interface. Some of these binaries are statically defined
+ either in the kernel code itself, or as a kernel configuration
+ option. However, some of these are dynamically created at
+ runtime, or can be modified after the kernel has started up.
+ To provide an additional layer of security, route all of these
+ calls through a single executable that can not have its name
+ changed.
+
+ Note, it is up to this single binary to then call the relevant
+ "real" usermode helper binary, based on the first argument
+ passed to it. If desired, this program can filter and pick
+ and choose what real programs are called.
+
+ If you wish for all usermode helper programs are to be
+ disabled, choose this option and then set
+ STATIC_USERMODEHELPER_PATH to an empty string.
+
+config STATIC_USERMODEHELPER_PATH
+ string "Path to the static usermode helper binary"
+ depends on STATIC_USERMODEHELPER
+ default "/sbin/usermode-helper"
+ help
+ The binary called by the kernel when any usermode helper
+ program is wish to be run. The "real" application's name will
+ be in the first argument passed to this program on the command
+ line.
+
+ If you wish for all usermode helper programs to be disabled,
+ specify an empty string here (i.e. "").
+
source security/selinux/Kconfig
source security/smack/Kconfig
source security/tomoyo/Kconfig
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index ef4beef06e9d..001e133a3c8c 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -471,7 +471,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
;
}
- if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
+ if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
error = may_change_ptraced_domain(new_profile);
if (error)
goto audit;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index f44312a19522..def1fbd6bdfd 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -76,6 +76,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
+#include <linux/cred.h>
+#include <linux/rculist.h>
#include <linux/user_namespace.h>
#include "include/apparmor.h"
diff --git a/security/commoncap.c b/security/commoncap.c
index 6d4d586b9356..78b37838a2d3 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -548,9 +548,10 @@ skip:
if ((is_setid ||
!cap_issubset(new->cap_permitted, old->cap_permitted)) &&
- bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
+ ((bprm->unsafe & ~LSM_UNSAFE_PTRACE) ||
+ !ptracer_capable(current, new->user_ns))) {
/* downgrade; they get no more than they had, and maybe less */
- if (!capable(CAP_SETUID) ||
+ if (!ns_capable(new->user_ns, CAP_SETUID) ||
(bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
new->euid = new->uid;
new->egid = new->gid;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index e2ed498c0f5f..063d38aef64e 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -22,6 +22,8 @@
#include <linux/xattr.h>
#include <linux/integrity.h>
#include <linux/evm.h>
+#include <linux/magic.h>
+
#include <crypto/hash.h>
#include <crypto/algapi.h>
#include "evm.h"
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 531ed2ec132f..893af4c45038 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -55,7 +55,7 @@ static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi)
if (status == 0) {
const struct user_key_payload *payload;
- payload = user_key_payload(key);
+ payload = user_key_payload_locked(key);
if (maxlen == 0) {
*mpi = NULL;
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 4fb315cddf5b..0010955d7876 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -314,7 +314,7 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
goto error;
down_read(&ukey->sem);
- upayload = user_key_payload(ukey);
+ upayload = user_key_payload_locked(ukey);
*master_key = upayload->data;
*master_keylen = upayload->datalen;
error:
@@ -926,7 +926,7 @@ static long encrypted_read(const struct key *key, char __user *buffer,
size_t asciiblob_len;
int ret;
- epayload = rcu_dereference_key(key);
+ epayload = dereference_key_locked(key);
/* returns the hex encoded iv, encrypted-data, and hmac as ascii */
asciiblob_len = epayload->datablob_len + ivsize + 1
diff --git a/security/keys/internal.h b/security/keys/internal.h
index a705a7d92ad7..a2f4c0abb8d8 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -13,6 +13,7 @@
#define _INTERNAL_H
#include <linux/sched.h>
+#include <linux/cred.h>
#include <linux/key-type.h>
#include <linux/task_work.h>
#include <linux/keyctl.h>
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 04a764f71ec8..52c34532c785 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -12,12 +12,14 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/sched/task.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/key.h>
#include <linux/keyctl.h>
#include <linux/fs.h>
#include <linux/capability.h>
+#include <linux/cred.h>
#include <linux/string.h>
#include <linux/err.h>
#include <linux/vmalloc.h>
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index 1edc1f0a0ce2..d0cb5b32eff7 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -10,6 +10,8 @@
*/
#include <linux/user_namespace.h>
+#include <linux/cred.h>
+
#include "internal.h"
unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 918cddcd4516..b6fdd22205b1 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/sched/user.h>
#include <linux/keyctl.h>
#include <linux/fs.h>
#include <linux/err.h>
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 43affcf10b22..9822e500d50d 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -72,7 +72,7 @@ static void umh_keys_cleanup(struct subprocess_info *info)
/*
* Call a usermode helper with a specific session keyring.
*/
-static int call_usermodehelper_keys(char *path, char **argv, char **envp,
+static int call_usermodehelper_keys(const char *path, char **argv, char **envp,
struct key *session_keyring, int wait)
{
struct subprocess_info *info;
@@ -95,6 +95,7 @@ static int call_sbin_request_key(struct key_construction *cons,
const char *op,
void *aux)
{
+ static char const request_key[] = "/sbin/request-key";
const struct cred *cred = current_cred();
key_serial_t prkey, sskey;
struct key *key = cons->key, *authkey = cons->authkey, *keyring,
@@ -161,7 +162,7 @@ static int call_sbin_request_key(struct key_construction *cons,
/* set up the argument list */
i = 0;
- argv[i++] = "/sbin/request-key";
+ argv[i++] = (char *)request_key;
argv[i++] = (char *) op;
argv[i++] = key_str;
argv[i++] = uid_str;
@@ -172,7 +173,7 @@ static int call_sbin_request_key(struct key_construction *cons,
argv[i] = NULL;
/* do it */
- ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
+ ret = call_usermodehelper_keys(request_key, argv, envp, keyring,
UMH_WAIT_PROC);
kdebug("usermode -> 0x%x", ret);
if (ret >= 0) {
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index 90d61751ff12..2ae31c5a87de 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -1140,12 +1140,12 @@ out:
static long trusted_read(const struct key *key, char __user *buffer,
size_t buflen)
{
- struct trusted_key_payload *p;
+ const struct trusted_key_payload *p;
char *ascii_buf;
char *bufp;
int i;
- p = rcu_dereference_key(key);
+ p = dereference_key_locked(key);
if (!p)
return -EINVAL;
if (!buffer || buflen <= 0)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index e187c8909d9d..26605134f17a 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -107,7 +107,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
/* attach the new data, displacing the old */
key->expiry = prep->expiry;
if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
- zap = rcu_dereference_key(key);
+ zap = dereference_key_locked(key);
rcu_assign_keypointer(key, prep->payload.data[0]);
prep->payload.data[0] = NULL;
@@ -123,7 +123,7 @@ EXPORT_SYMBOL_GPL(user_update);
*/
void user_revoke(struct key *key)
{
- struct user_key_payload *upayload = key->payload.data[0];
+ struct user_key_payload *upayload = user_key_payload_locked(key);
/* clear the quota */
key_payload_reserve(key, 0);
@@ -169,7 +169,7 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
const struct user_key_payload *upayload;
long ret;
- upayload = user_key_payload(key);
+ upayload = user_key_payload_locked(key);
ret = upayload->datalen;
/* we can return the data as is */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9bc12bcddc2c..0c2ac318aa7f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -28,7 +28,8 @@
#include <linux/kernel.h>
#include <linux/tracehook.h>
#include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/sched/signal.h>
+#include <linux/sched/task.h>
#include <linux/lsm_hooks.h>
#include <linux/xattr.h>
#include <linux/capability.h>
@@ -480,12 +481,13 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
sbsec->behavior == SECURITY_FS_USE_NATIVE ||
/* Special handling. Genfs but also in-core setxattr handler */
!strcmp(sb->s_type->name, "sysfs") ||
- !strcmp(sb->s_type->name, "cgroup") ||
- !strcmp(sb->s_type->name, "cgroup2") ||
!strcmp(sb->s_type->name, "pstore") ||
!strcmp(sb->s_type->name, "debugfs") ||
!strcmp(sb->s_type->name, "tracefs") ||
- !strcmp(sb->s_type->name, "rootfs");
+ !strcmp(sb->s_type->name, "rootfs") ||
+ (selinux_policycap_cgroupseclabel &&
+ (!strcmp(sb->s_type->name, "cgroup") ||
+ !strcmp(sb->s_type->name, "cgroup2")));
}
static int sb_finish_set_opts(struct super_block *sb)
@@ -1401,7 +1403,9 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
return SECCLASS_KCM_SOCKET;
case PF_QIPCRTR:
return SECCLASS_QIPCRTR_SOCKET;
-#if PF_MAX > 43
+ case PF_SMC:
+ return SECCLASS_SMC_SOCKET;
+#if PF_MAX > 44
#error New address family defined, please update this function.
#endif
}
@@ -2397,8 +2401,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
/* Make sure that anyone attempting to ptrace over a task that
* changes its SID has the appropriate permit */
- if (bprm->unsafe &
- (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
+ if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
u32 ptsid = ptrace_parent_sid();
if (ptsid != 0) {
rc = avc_has_perm(ptsid, new_tsec->sid,
@@ -4363,7 +4366,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
inet_get_local_port_range(sock_net(sk), &low, &high);
- if (snum < max(PROT_SOCK, low) || snum > high) {
+ if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
+ snum > high) {
err = sel_netport_sid(sk->sk_protocol,
snum, &sid);
if (err)
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 7898ffa6d3e6..d429c4a1c551 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -229,9 +229,11 @@ struct security_class_mapping secclass_map[] = {
{ COMMON_SOCK_PERMS, NULL } },
{ "qipcrtr_socket",
{ COMMON_SOCK_PERMS, NULL } },
+ { "smc_socket",
+ { COMMON_SOCK_PERMS, NULL } },
{ NULL }
};
-#if PF_MAX > 43
+#if PF_MAX > 44
#error New address family defined, please update secclass_map.
#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index beaa14b8b6cf..f979c35e037e 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -71,6 +71,7 @@ enum {
POLICYDB_CAPABILITY_OPENPERM,
POLICYDB_CAPABILITY_EXTSOCKCLASS,
POLICYDB_CAPABILITY_ALWAYSNETWORK,
+ POLICYDB_CAPABILITY_CGROUPSECLABEL,
__POLICYDB_CAPABILITY_MAX
};
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
@@ -79,6 +80,7 @@ extern int selinux_policycap_netpeer;
extern int selinux_policycap_openperm;
extern int selinux_policycap_extsockclass;
extern int selinux_policycap_alwaysnetwork;
+extern int selinux_policycap_cgroupseclabel;
/*
* type_datum properties
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index c354807381c1..cb3fd98fb05a 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -46,7 +46,8 @@ static char *policycap_names[] = {
"network_peer_controls",
"open_perms",
"extended_socket_class",
- "always_check_network"
+ "always_check_network",
+ "cgroup_seclabel"
};
unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
@@ -424,10 +425,9 @@ out:
return ret;
}
-static int sel_mmap_policy_fault(struct vm_area_struct *vma,
- struct vm_fault *vmf)
+static int sel_mmap_policy_fault(struct vm_fault *vmf)
{
- struct policy_load_memory *plm = vma->vm_file->private_data;
+ struct policy_load_memory *plm = vmf->vma->vm_file->private_data;
unsigned long offset;
struct page *page;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 7d10e5d418bb..9db4709a6877 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -360,7 +360,7 @@ int ebitmap_read(struct ebitmap *e, void *fp)
if (mapunit != BITS_PER_U64) {
printk(KERN_ERR "SELinux: ebitmap: map size %u does not "
- "match my size %Zd (high bit was %d)\n",
+ "match my size %zd (high bit was %d)\n",
mapunit, BITS_PER_U64, e->highbit);
goto bad;
}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index d719db4219cd..9c92f29a38ea 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -2266,7 +2266,7 @@ int policydb_read(struct policydb *p, void *fp)
len = le32_to_cpu(buf[1]);
if (len != strlen(POLICYDB_STRING)) {
printk(KERN_ERR "SELinux: policydb string length %d does not "
- "match expected length %Zu\n",
+ "match expected length %zu\n",
len, strlen(POLICYDB_STRING));
goto bad;
}
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index a70fcee9824b..b4aa491a0a23 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -74,6 +74,7 @@ int selinux_policycap_netpeer;
int selinux_policycap_openperm;
int selinux_policycap_extsockclass;
int selinux_policycap_alwaysnetwork;
+int selinux_policycap_cgroupseclabel;
static DEFINE_RWLOCK(policy_rwlock);
@@ -1993,6 +1994,9 @@ static void security_load_policycaps(void)
POLICYDB_CAPABILITY_EXTSOCKCLASS);
selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
POLICYDB_CAPABILITY_ALWAYSNETWORK);
+ selinux_policycap_cgroupseclabel =
+ ebitmap_get_bit(&policydb.policycaps,
+ POLICYDB_CAPABILITY_CGROUPSECLABEL);
}
static int security_preserve_bools(struct policydb *p);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 60b4217b9b68..fc8fb31fc24f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -931,7 +931,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
isp->smk_task != sbsp->smk_root)
return 0;
- if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
+ if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
struct task_struct *tracer;
rc = 0;
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 838ffa78cfda..00d223e9fb37 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -5,8 +5,10 @@
*/
#include "common.h"
+
#include <linux/binfmts.h>
#include <linux/slab.h>
+#include <linux/rculist.h>
/* Variables definitions.*/
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c
index 50092534ec54..944ad77d8fba 100644
--- a/security/tomoyo/group.c
+++ b/security/tomoyo/group.c
@@ -5,6 +5,8 @@
*/
#include <linux/slab.h>
+#include <linux/rculist.h>
+
#include "common.h"
/**
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 5fe3679137ae..848317fea704 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -5,6 +5,8 @@
*/
#include <linux/slab.h>
+#include <linux/rculist.h>
+
#include "common.h"
/* Lock for protecting policy. */