summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig1
-rw-r--r--security/apparmor/lsm.c5
-rw-r--r--security/landlock/fs.c2
-rw-r--r--security/min_addr.c6
-rw-r--r--security/security.c114
-rw-r--r--security/selinux/avc.c13
-rw-r--r--security/selinux/hooks.c73
-rw-r--r--security/selinux/include/objsec.h20
-rw-r--r--security/selinux/include/policycap.h1
-rw-r--r--security/selinux/include/policycap_names.h1
-rw-r--r--security/selinux/include/security.h4
-rw-r--r--security/selinux/selinuxfs.c18
-rw-r--r--security/smack/smack_lsm.c5
-rw-r--r--security/tomoyo/tomoyo.c2
14 files changed, 172 insertions, 93 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 4816fc74f81e..285f284dfcac 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -269,6 +269,7 @@ endchoice
config LSM
string "Ordered list of enabled LSMs"
+ depends on SECURITY
default "landlock,lockdown,yama,loadpin,safesetid,smack,selinux,tomoyo,apparmor,ipe,bpf" if DEFAULT_SECURITY_SMACK
default "landlock,lockdown,yama,loadpin,safesetid,apparmor,selinux,smack,tomoyo,ipe,bpf" if DEFAULT_SECURITY_APPARMOR
default "landlock,lockdown,yama,loadpin,safesetid,tomoyo,ipe,bpf" if DEFAULT_SECURITY_TOMOYO
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8e1cc229b41b..b3f7a3258a2c 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -112,7 +112,7 @@ static void apparmor_task_free(struct task_struct *task)
}
static int apparmor_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
struct aa_task_ctx *new = task_ctx(task);
@@ -2530,6 +2530,9 @@ static int __init apparmor_init(void)
security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),
&apparmor_lsmid);
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&apparmor_lsmid, AUDIT_CFG_LSM_SECCTX_SUBJECT);
+
/* Report that AppArmor successfully initialized */
apparmor_initialized = 1;
if (aa_g_profile_mode == APPARMOR_COMPLAIN)
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index c04f8879ad03..0bade2c5aa1d 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -1281,7 +1281,7 @@ static void hook_sb_delete(struct super_block *const sb)
struct landlock_object *object;
/* Only handles referenced inodes. */
- if (!atomic_read(&inode->i_count))
+ if (!icount_read(inode))
continue;
/*
diff --git a/security/min_addr.c b/security/min_addr.c
index df1bc643d886..c55bb84b8632 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <linux/security.h>
#include <linux/sysctl.h>
+#include <linux/minmax.h>
/* amount of vm to protect from userspace access by both DAC and the LSM*/
unsigned long mmap_min_addr;
@@ -16,10 +17,7 @@ unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
static void update_mmap_min_addr(void)
{
#ifdef CONFIG_LSM_MMAP_MIN_ADDR
- if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
- mmap_min_addr = dac_mmap_min_addr;
- else
- mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
+ mmap_min_addr = umax(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR);
#else
mmap_min_addr = dac_mmap_min_addr;
#endif
diff --git a/security/security.c b/security/security.c
index ad163f06bf7a..301104d63fde 100644
--- a/security/security.c
+++ b/security/security.c
@@ -283,6 +283,9 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
lsm_set_blob_size(&needed->lbs_xattr_count,
&blob_sizes.lbs_xattr_count);
lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
+ lsm_set_blob_size(&needed->lbs_bpf_map, &blob_sizes.lbs_bpf_map);
+ lsm_set_blob_size(&needed->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog);
+ lsm_set_blob_size(&needed->lbs_bpf_token, &blob_sizes.lbs_bpf_token);
}
/* Prepare LSM for initialization. */
@@ -480,6 +483,9 @@ static void __init ordered_lsm_init(void)
init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
+ init_debug("bpf map blob size = %d\n", blob_sizes.lbs_bpf_map);
+ init_debug("bpf prog blob size = %d\n", blob_sizes.lbs_bpf_prog);
+ init_debug("bpf token blob size = %d\n", blob_sizes.lbs_bpf_token);
/*
* Create any kmem_caches needed for blobs
@@ -823,17 +829,50 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp)
*/
static int lsm_bdev_alloc(struct block_device *bdev)
{
- if (blob_sizes.lbs_bdev == 0) {
- bdev->bd_security = NULL;
- return 0;
- }
+ return lsm_blob_alloc(&bdev->bd_security, blob_sizes.lbs_bdev,
+ GFP_KERNEL);
+}
- bdev->bd_security = kzalloc(blob_sizes.lbs_bdev, GFP_KERNEL);
- if (!bdev->bd_security)
- return -ENOMEM;
+#ifdef CONFIG_BPF_SYSCALL
+/**
+ * lsm_bpf_map_alloc - allocate a composite bpf_map blob
+ * @map: the bpf_map that needs a blob
+ *
+ * Allocate the bpf_map blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_map_alloc(struct bpf_map *map)
+{
+ return lsm_blob_alloc(&map->security, blob_sizes.lbs_bpf_map, GFP_KERNEL);
+}
- return 0;
+/**
+ * lsm_bpf_prog_alloc - allocate a composite bpf_prog blob
+ * @prog: the bpf_prog that needs a blob
+ *
+ * Allocate the bpf_prog blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_prog_alloc(struct bpf_prog *prog)
+{
+ return lsm_blob_alloc(&prog->aux->security, blob_sizes.lbs_bpf_prog, GFP_KERNEL);
+}
+
+/**
+ * lsm_bpf_token_alloc - allocate a composite bpf_token blob
+ * @token: the bpf_token that needs a blob
+ *
+ * Allocate the bpf_token blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_bpf_token_alloc(struct bpf_token *token)
+{
+ return lsm_blob_alloc(&token->security, blob_sizes.lbs_bpf_token, GFP_KERNEL);
}
+#endif /* CONFIG_BPF_SYSCALL */
/**
* lsm_early_task - during initialization allocate a composite task blob
@@ -3185,7 +3224,7 @@ int security_file_truncate(struct file *file)
*
* Return: Returns a zero on success, negative values on failure.
*/
-int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
+int security_task_alloc(struct task_struct *task, u64 clone_flags)
{
int rc = lsm_task_alloc(task);
@@ -4342,17 +4381,31 @@ EXPORT_SYMBOL(security_secid_to_secctx);
* security_lsmprop_to_secctx() - Convert a lsm_prop to a secctx
* @prop: lsm specific information
* @cp: the LSM context
+ * @lsmid: which security module to report
*
* Convert a @prop entry to security context. If @cp is NULL the
* length of the result will be returned. This does mean that the
* length could change between calls to check the length and the
* next call which actually allocates and returns the @cp.
*
+ * @lsmid identifies which LSM should supply the context.
+ * A value of LSM_ID_UNDEF indicates that the first LSM suppling
+ * the hook should be used. This is used in cases where the
+ * ID of the supplying LSM is unambiguous.
+ *
* Return: Return length of data on success, error on failure.
*/
-int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp)
+int security_lsmprop_to_secctx(struct lsm_prop *prop, struct lsm_context *cp,
+ int lsmid)
{
- return call_int_hook(lsmprop_to_secctx, prop, cp);
+ struct lsm_static_call *scall;
+
+ lsm_for_each_hook(scall, lsmprop_to_secctx) {
+ if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
+ continue;
+ return scall->hl->hook.lsmprop_to_secctx(prop, cp);
+ }
+ return LSM_RET_DEFAULT(lsmprop_to_secctx);
}
EXPORT_SYMBOL(security_lsmprop_to_secctx);
@@ -5714,7 +5767,16 @@ int security_bpf_prog(struct bpf_prog *prog)
int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
- return call_int_hook(bpf_map_create, map, attr, token, kernel);
+ int rc;
+
+ rc = lsm_bpf_map_alloc(map);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_map_create, map, attr, token, kernel);
+ if (unlikely(rc))
+ security_bpf_map_free(map);
+ return rc;
}
/**
@@ -5733,7 +5795,16 @@ int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
- return call_int_hook(bpf_prog_load, prog, attr, token, kernel);
+ int rc;
+
+ rc = lsm_bpf_prog_alloc(prog);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_prog_load, prog, attr, token, kernel);
+ if (unlikely(rc))
+ security_bpf_prog_free(prog);
+ return rc;
}
/**
@@ -5750,7 +5821,16 @@ int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
const struct path *path)
{
- return call_int_hook(bpf_token_create, token, attr, path);
+ int rc;
+
+ rc = lsm_bpf_token_alloc(token);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(bpf_token_create, token, attr, path);
+ if (unlikely(rc))
+ security_bpf_token_free(token);
+ return rc;
}
/**
@@ -5794,6 +5874,8 @@ int security_bpf_token_capable(const struct bpf_token *token, int cap)
void security_bpf_map_free(struct bpf_map *map)
{
call_void_hook(bpf_map_free, map);
+ kfree(map->security);
+ map->security = NULL;
}
/**
@@ -5805,6 +5887,8 @@ void security_bpf_map_free(struct bpf_map *map)
void security_bpf_prog_free(struct bpf_prog *prog)
{
call_void_hook(bpf_prog_free, prog);
+ kfree(prog->aux->security);
+ prog->aux->security = NULL;
}
/**
@@ -5816,6 +5900,8 @@ void security_bpf_prog_free(struct bpf_prog *prog)
void security_bpf_token_free(struct bpf_token *token)
{
call_void_hook(bpf_token_free, token);
+ kfree(token->security);
+ token->security = NULL;
}
#endif /* CONFIG_BPF_SYSCALL */
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 4b4837a20225..430b0e23ee00 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -292,27 +292,26 @@ static struct avc_xperms_decision_node
struct avc_xperms_decision_node *xpd_node;
struct extended_perms_decision *xpd;
- xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT);
if (!xpd_node)
return NULL;
xpd = &xpd_node->xpd;
if (which & XPERMS_ALLOWED) {
xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->allowed)
goto error;
}
if (which & XPERMS_AUDITALLOW) {
xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->auditallow)
goto error;
}
if (which & XPERMS_DONTAUDIT) {
xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep,
- GFP_NOWAIT | __GFP_NOWARN);
+ GFP_NOWAIT);
if (!xpd->dontaudit)
goto error;
}
@@ -340,7 +339,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void)
{
struct avc_xperms_node *xp_node;
- xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT);
if (!xp_node)
return xp_node;
INIT_LIST_HEAD(&xp_node->xpd_head);
@@ -495,7 +494,7 @@ static struct avc_node *avc_alloc_node(void)
{
struct avc_node *node;
- node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN);
+ node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT);
if (!node)
goto out;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c95a5874bf7d..76b66845a1c3 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -476,7 +476,9 @@ static int selinux_is_genfs_special_handling(struct super_block *sb)
!strcmp(sb->s_type->name, "rootfs") ||
(selinux_policycap_cgroupseclabel() &&
(!strcmp(sb->s_type->name, "cgroup") ||
- !strcmp(sb->s_type->name, "cgroup2")));
+ !strcmp(sb->s_type->name, "cgroup2"))) ||
+ (selinux_policycap_functionfs_seclabel() &&
+ !strcmp(sb->s_type->name, "functionfs"));
}
static int selinux_is_sblabel_mnt(struct super_block *sb)
@@ -741,7 +743,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
!strcmp(sb->s_type->name, "binder") ||
!strcmp(sb->s_type->name, "bpf") ||
!strcmp(sb->s_type->name, "pstore") ||
- !strcmp(sb->s_type->name, "securityfs"))
+ !strcmp(sb->s_type->name, "securityfs") ||
+ (selinux_policycap_functionfs_seclabel() &&
+ !strcmp(sb->s_type->name, "functionfs")))
sbsec->flags |= SE_SBGENFS;
if (!strcmp(sb->s_type->name, "sysfs") ||
@@ -4144,7 +4148,7 @@ static int selinux_file_open(struct file *file)
/* task security operations */
static int selinux_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
u32 sid = current_sid();
@@ -5885,7 +5889,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
* because we want to make sure we apply the necessary labeling
* before IPsec is applied so we can leverage AH protection */
- sk = sk_to_full_sk(skb->sk);
+ sk = skb_to_full_sk(skb);
if (sk) {
struct sk_security_struct *sksec;
@@ -7062,14 +7066,14 @@ static int bpf_fd_pass(const struct file *file, u32 sid)
if (file->f_op == &bpf_map_fops) {
map = file->private_data;
- bpfsec = map->security;
+ bpfsec = selinux_bpf_map_security(map);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(file->f_mode), NULL);
if (ret)
return ret;
} else if (file->f_op == &bpf_prog_fops) {
prog = file->private_data;
- bpfsec = prog->aux->security;
+ bpfsec = selinux_bpf_prog_security(prog);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
if (ret)
@@ -7083,7 +7087,7 @@ static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
- bpfsec = map->security;
+ bpfsec = selinux_bpf_map_security(map);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(fmode), NULL);
}
@@ -7093,7 +7097,7 @@ static int selinux_bpf_prog(struct bpf_prog *prog)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
- bpfsec = prog->aux->security;
+ bpfsec = selinux_bpf_prog_security(prog);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
}
@@ -7103,69 +7107,33 @@ static int selinux_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_map_security(map);
bpfsec->sid = current_sid();
- map->security = bpfsec;
return 0;
}
-static void selinux_bpf_map_free(struct bpf_map *map)
-{
- struct bpf_security_struct *bpfsec = map->security;
-
- map->security = NULL;
- kfree(bpfsec);
-}
-
static int selinux_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_prog_security(prog);
bpfsec->sid = current_sid();
- prog->aux->security = bpfsec;
return 0;
}
-static void selinux_bpf_prog_free(struct bpf_prog *prog)
-{
- struct bpf_security_struct *bpfsec = prog->aux->security;
-
- prog->aux->security = NULL;
- kfree(bpfsec);
-}
-
static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
const struct path *path)
{
struct bpf_security_struct *bpfsec;
- bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
- if (!bpfsec)
- return -ENOMEM;
-
+ bpfsec = selinux_bpf_token_security(token);
bpfsec->sid = current_sid();
- token->security = bpfsec;
return 0;
}
-
-static void selinux_bpf_token_free(struct bpf_token *token)
-{
- struct bpf_security_struct *bpfsec = token->security;
-
- token->security = NULL;
- kfree(bpfsec);
-}
#endif
struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
@@ -7183,6 +7151,9 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
.lbs_tun_dev = sizeof(struct tun_security_struct),
.lbs_ib = sizeof(struct ib_security_struct),
+ .lbs_bpf_map = sizeof(struct bpf_security_struct),
+ .lbs_bpf_prog = sizeof(struct bpf_security_struct),
+ .lbs_bpf_token = sizeof(struct bpf_security_struct),
};
#ifdef CONFIG_PERF_EVENTS
@@ -7536,9 +7507,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bpf, selinux_bpf),
LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
- LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free),
- LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free),
- LSM_HOOK_INIT(bpf_token_free, selinux_bpf_token_free),
#endif
#ifdef CONFIG_PERF_EVENTS
@@ -7618,6 +7586,11 @@ static __init int selinux_init(void)
/* Set the security state for the initial task. */
cred_init_security();
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&selinux_lsmid,
+ AUDIT_CFG_LSM_SECCTX_SUBJECT |
+ AUDIT_CFG_LSM_SECCTX_OBJECT);
+
default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
if (!default_noexec)
pr_notice("SELinux: virtual memory is executable by default\n");
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 1d7ac59015a1..2d5139c6d45b 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -26,6 +26,7 @@
#include <linux/lsm_hooks.h>
#include <linux/msg.h>
#include <net/net_namespace.h>
+#include <linux/bpf.h>
#include "flask.h"
#include "avc.h"
@@ -245,4 +246,23 @@ selinux_perf_event(void *perf_event)
return perf_event + selinux_blob_sizes.lbs_perf_event;
}
+#ifdef CONFIG_BPF_SYSCALL
+static inline struct bpf_security_struct *
+selinux_bpf_map_security(struct bpf_map *map)
+{
+ return map->security + selinux_blob_sizes.lbs_bpf_map;
+}
+
+static inline struct bpf_security_struct *
+selinux_bpf_prog_security(struct bpf_prog *prog)
+{
+ return prog->aux->security + selinux_blob_sizes.lbs_bpf_prog;
+}
+
+static inline struct bpf_security_struct *
+selinux_bpf_token_security(struct bpf_token *token)
+{
+ return token->security + selinux_blob_sizes.lbs_bpf_token;
+}
+#endif /* CONFIG_BPF_SYSCALL */
#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h
index 7405154e6c42..135a969f873c 100644
--- a/security/selinux/include/policycap.h
+++ b/security/selinux/include/policycap.h
@@ -17,6 +17,7 @@ enum {
POLICYDB_CAP_NETLINK_XPERM,
POLICYDB_CAP_NETIF_WILDCARD,
POLICYDB_CAP_GENFS_SECLABEL_WILDCARD,
+ POLICYDB_CAP_FUNCTIONFS_SECLABEL,
__POLICYDB_CAP_MAX
};
#define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h
index d8962fcf2ff9..ff8882887651 100644
--- a/security/selinux/include/policycap_names.h
+++ b/security/selinux/include/policycap_names.h
@@ -20,6 +20,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"netlink_xperm",
"netif_wildcard",
"genfs_seclabel_wildcard",
+ "functionfs_seclabel",
};
/* clang-format on */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8201e6a3ac0f..0f954a40d3fc 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -203,10 +203,10 @@ static inline bool selinux_policycap_netlink_xperm(void)
selinux_state.policycap[POLICYDB_CAP_NETLINK_XPERM]);
}
-static inline bool selinux_policycap_netif_wildcard(void)
+static inline bool selinux_policycap_functionfs_seclabel(void)
{
return READ_ONCE(
- selinux_state.policycap[POLICYDB_CAP_NETIF_WILDCARD]);
+ selinux_state.policycap[POLICYDB_CAP_FUNCTIONFS_SECLABEL]);
}
struct selinux_policy_convert_data;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 9aa1d03ab612..232e087bce3e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1203,7 +1203,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
size_t count, loff_t *ppos)
{
struct selinux_fs_info *fsi = file_inode(filep)->i_sb->s_fs_info;
- char *page = NULL;
+ char buffer[4];
ssize_t length;
ssize_t ret;
int cur_enforcing;
@@ -1217,27 +1217,19 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
fsi->bool_pending_names[index]))
goto out_unlock;
- ret = -ENOMEM;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
- goto out_unlock;
-
cur_enforcing = security_get_bool_value(index);
if (cur_enforcing < 0) {
ret = cur_enforcing;
goto out_unlock;
}
- length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
- fsi->bool_pending_values[index]);
+ length = scnprintf(buffer, sizeof(buffer), "%d %d", !!cur_enforcing,
+ !!fsi->bool_pending_values[index]);
mutex_unlock(&selinux_state.policy_mutex);
- ret = simple_read_from_buffer(buf, count, ppos, page, length);
-out_free:
- free_page((unsigned long)page);
- return ret;
+ return simple_read_from_buffer(buf, count, ppos, buffer, length);
out_unlock:
mutex_unlock(&selinux_state.policy_mutex);
- goto out_free;
+ return ret;
}
static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index fc340a6f0dde..fdf2f193a291 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -5267,6 +5267,11 @@ static __init int smack_init(void)
/* initialize the smack_known_list */
init_smack_known_list();
+ /* Inform the audit system that secctx is used */
+ audit_cfg_lsm(&smack_lsmid,
+ AUDIT_CFG_LSM_SECCTX_SUBJECT |
+ AUDIT_CFG_LSM_SECCTX_OBJECT);
+
return 0;
}
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index d6ebcd9db80a..48fc59d38ab2 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -514,7 +514,7 @@ struct lsm_blob_sizes tomoyo_blob_sizes __ro_after_init = {
* Returns 0.
*/
static int tomoyo_task_alloc(struct task_struct *task,
- unsigned long clone_flags)
+ u64 clone_flags)
{
struct tomoyo_task *old = tomoyo_task(current);
struct tomoyo_task *new = tomoyo_task(task);