From 1b67772e4e3f16cd647b229cae95fc06d120be08 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jan 2024 18:21:06 -0800 Subject: bpf,lsm: Refactor bpf_prog_alloc/bpf_prog_free LSM hooks Based on upstream discussion ([0]), rework existing bpf_prog_alloc_security LSM hook. Rename it to bpf_prog_load and instead of passing bpf_prog_aux, pass proper bpf_prog pointer for a full BPF program struct. Also, we pass bpf_attr union with all the user-provided arguments for BPF_PROG_LOAD command. This will give LSMs as much information as we can basically provide. The hook is also BPF token-aware now, and optional bpf_token struct is passed as a third argument. bpf_prog_load LSM hook is called after a bunch of sanity checks were performed, bpf_prog and bpf_prog_aux were allocated and filled out, but right before performing full-fledged BPF verification step. bpf_prog_free LSM hook is now accepting struct bpf_prog argument, for consistency. SELinux code is adjusted to all new names, types, and signatures. Note, given that bpf_prog_load (previously bpf_prog_alloc) hook can be used by some LSMs to allocate extra security blob, but also by other LSMs to reject BPF program loading, we need to make sure that bpf_prog_free LSM hook is called after bpf_prog_load/bpf_prog_alloc one *even* if the hook itself returned error. If we don't do that, we run the risk of leaking memory. This seems to be possible today when combining SELinux and BPF LSM, as one example, depending on their relative ordering. Also, for BPF LSM setup, add bpf_prog_load and bpf_prog_free to sleepable LSM hooks list, as they are both executed in sleepable context. Also drop bpf_prog_load hook from untrusted, as there is no issue with refcount or anything else anymore, that originally forced us to add it to untrusted list in c0c852dd1876 ("bpf: Do not mark certain LSM hook arguments as trusted"). We now trigger this hook much later and it should not be an issue anymore. [0] https://lore.kernel.org/bpf/9fe88aef7deabbe87d3fc38c4aea3c69.paul@paul-moore.com/ Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Acked-by: Paul Moore Link: https://lore.kernel.org/bpf/20240124022127.2379740-10-andrii@kernel.org --- include/linux/security.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'include/linux/security.h') diff --git a/include/linux/security.h b/include/linux/security.h index d0eb20f90b26..cb2932fce448 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -2064,15 +2064,16 @@ static inline void securityfs_remove(struct dentry *dentry) union bpf_attr; struct bpf_map; struct bpf_prog; -struct bpf_prog_aux; +struct bpf_token; #ifdef CONFIG_SECURITY extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size); extern int security_bpf_map(struct bpf_map *map, fmode_t fmode); extern int security_bpf_prog(struct bpf_prog *prog); extern int security_bpf_map_alloc(struct bpf_map *map); extern void security_bpf_map_free(struct bpf_map *map); -extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux); -extern void security_bpf_prog_free(struct bpf_prog_aux *aux); +extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, + struct bpf_token *token); +extern void security_bpf_prog_free(struct bpf_prog *prog); #else static inline int security_bpf(int cmd, union bpf_attr *attr, unsigned int size) @@ -2098,12 +2099,13 @@ static inline int security_bpf_map_alloc(struct bpf_map *map) static inline void security_bpf_map_free(struct bpf_map *map) { } -static inline int security_bpf_prog_alloc(struct bpf_prog_aux *aux) +static inline int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, + struct bpf_token *token) { return 0; } -static inline void security_bpf_prog_free(struct bpf_prog_aux *aux) +static inline void security_bpf_prog_free(struct bpf_prog *prog) { } #endif /* CONFIG_SECURITY */ #endif /* CONFIG_BPF_SYSCALL */ -- cgit v1.2.3 From a2431c7eabcf9bd5a1e7a1f7ecded40fdda4a8c5 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jan 2024 18:21:07 -0800 Subject: bpf,lsm: Refactor bpf_map_alloc/bpf_map_free LSM hooks Similarly to bpf_prog_alloc LSM hook, rename and extend bpf_map_alloc hook into bpf_map_create, taking not just struct bpf_map, but also bpf_attr and bpf_token, to give a fuller context to LSMs. Unlike bpf_prog_alloc, there is no need to move the hook around, as it currently is firing right before allocating BPF map ID and FD, which seems to be a sweet spot. But like bpf_prog_alloc/bpf_prog_free combo, make sure that bpf_map_free LSM hook is called even if bpf_map_create hook returned error, as if few LSMs are combined together it could be that one LSM successfully allocated security blob for its needs, while subsequent LSM rejected BPF map creation. The former LSM would still need to free up LSM blob, so we need to ensure security_bpf_map_free() is called regardless of the outcome. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Acked-by: Paul Moore Link: https://lore.kernel.org/bpf/20240124022127.2379740-11-andrii@kernel.org --- include/linux/lsm_hook_defs.h | 5 +++-- include/linux/security.h | 6 ++++-- kernel/bpf/bpf_lsm.c | 6 +++--- kernel/bpf/syscall.c | 4 ++-- security/security.c | 16 ++++++++++------ security/selinux/hooks.c | 7 ++++--- 6 files changed, 26 insertions(+), 18 deletions(-) (limited to 'include/linux/security.h') diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 370181aa685b..1be4d3ca6efb 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -404,8 +404,9 @@ LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule) LSM_HOOK(int, 0, bpf, int cmd, union bpf_attr *attr, unsigned int size) LSM_HOOK(int, 0, bpf_map, struct bpf_map *map, fmode_t fmode) LSM_HOOK(int, 0, bpf_prog, struct bpf_prog *prog) -LSM_HOOK(int, 0, bpf_map_alloc_security, struct bpf_map *map) -LSM_HOOK(void, LSM_RET_VOID, bpf_map_free_security, struct bpf_map *map) +LSM_HOOK(int, 0, bpf_map_create, struct bpf_map *map, union bpf_attr *attr, + struct bpf_token *token) +LSM_HOOK(void, LSM_RET_VOID, bpf_map_free, struct bpf_map *map) LSM_HOOK(int, 0, bpf_prog_load, struct bpf_prog *prog, union bpf_attr *attr, struct bpf_token *token) LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog) diff --git a/include/linux/security.h b/include/linux/security.h index cb2932fce448..83fcdc974116 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -2069,7 +2069,8 @@ struct bpf_token; extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size); extern int security_bpf_map(struct bpf_map *map, fmode_t fmode); extern int security_bpf_prog(struct bpf_prog *prog); -extern int security_bpf_map_alloc(struct bpf_map *map); +extern int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, + struct bpf_token *token); extern void security_bpf_map_free(struct bpf_map *map); extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, struct bpf_token *token); @@ -2091,7 +2092,8 @@ static inline int security_bpf_prog(struct bpf_prog *prog) return 0; } -static inline int security_bpf_map_alloc(struct bpf_map *map) +static inline int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, + struct bpf_token *token) { return 0; } diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index 7ee0dd011de4..76976908b302 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -260,8 +260,8 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) BTF_SET_START(sleepable_lsm_hooks) BTF_ID(func, bpf_lsm_bpf) BTF_ID(func, bpf_lsm_bpf_map) -BTF_ID(func, bpf_lsm_bpf_map_alloc_security) -BTF_ID(func, bpf_lsm_bpf_map_free_security) +BTF_ID(func, bpf_lsm_bpf_map_create) +BTF_ID(func, bpf_lsm_bpf_map_free) BTF_ID(func, bpf_lsm_bpf_prog) BTF_ID(func, bpf_lsm_bpf_prog_load) BTF_ID(func, bpf_lsm_bpf_prog_free) @@ -359,7 +359,7 @@ BTF_ID(func, bpf_lsm_userns_create) BTF_SET_END(sleepable_lsm_hooks) BTF_SET_START(untrusted_lsm_hooks) -BTF_ID(func, bpf_lsm_bpf_map_free_security) +BTF_ID(func, bpf_lsm_bpf_map_free) BTF_ID(func, bpf_lsm_bpf_prog_free) BTF_ID(func, bpf_lsm_file_alloc_security) BTF_ID(func, bpf_lsm_file_free_security) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 3857a2a9ae7f..b2750b79ac80 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1318,9 +1318,9 @@ static int map_create(union bpf_attr *attr) attr->btf_vmlinux_value_type_id; } - err = security_bpf_map_alloc(map); + err = security_bpf_map_create(map, attr, token); if (err) - goto free_map; + goto free_map_sec; err = bpf_map_alloc_id(map); if (err) diff --git a/security/security.c b/security/security.c index eb159da4b146..26fcab35b6cd 100644 --- a/security/security.c +++ b/security/security.c @@ -5410,16 +5410,20 @@ int security_bpf_prog(struct bpf_prog *prog) } /** - * security_bpf_map_alloc() - Allocate a bpf map LSM blob - * @map: bpf map + * security_bpf_map_create() - Check if BPF map creation is allowed + * @map: BPF map object + * @attr: BPF syscall attributes used to create BPF map + * @token: BPF token used to grant user access * - * Initialize the security field inside bpf map. + * Do a check when the kernel creates a new BPF map. This is also the + * point where LSM blob is allocated for LSMs that need them. * * Return: Returns 0 on success, error on failure. */ -int security_bpf_map_alloc(struct bpf_map *map) +int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, + struct bpf_token *token) { - return call_int_hook(bpf_map_alloc_security, 0, map); + return call_int_hook(bpf_map_create, 0, map, attr, token); } /** @@ -5448,7 +5452,7 @@ int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, */ void security_bpf_map_free(struct bpf_map *map) { - call_void_hook(bpf_map_free_security, map); + call_void_hook(bpf_map_free, map); } /** diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6d64fb189b1b..3d336a7952f7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6920,7 +6920,8 @@ static int selinux_bpf_prog(struct bpf_prog *prog) BPF__PROG_RUN, NULL); } -static int selinux_bpf_map_alloc(struct bpf_map *map) +static int selinux_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, + struct bpf_token *token) { struct bpf_security_struct *bpfsec; @@ -7325,7 +7326,7 @@ 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_security, selinux_bpf_map_free), + LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free), LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free), #endif @@ -7383,7 +7384,7 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = { LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init), #endif #ifdef CONFIG_BPF_SYSCALL - LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc), + LSM_HOOK_INIT(bpf_map_create, selinux_bpf_map_create), LSM_HOOK_INIT(bpf_prog_load, selinux_bpf_prog_load), #endif #ifdef CONFIG_PERF_EVENTS -- cgit v1.2.3 From f568a3d49af9aed813a184353592efe29b0e3d16 Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 23 Jan 2024 18:21:08 -0800 Subject: bpf,lsm: Add BPF token LSM hooks Wire up bpf_token_create and bpf_token_free LSM hooks, which allow to allocate LSM security blob (we add `void *security` field to struct bpf_token for that), but also control who can instantiate BPF token. This follows existing pattern for BPF map and BPF prog. Also add security_bpf_token_allow_cmd() and security_bpf_token_capable() LSM hooks that allow LSM implementation to control and negate (if necessary) BPF token's delegation of a specific bpf_cmd and capability, respectively. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Acked-by: Paul Moore Link: https://lore.kernel.org/bpf/20240124022127.2379740-12-andrii@kernel.org --- include/linux/bpf.h | 3 +++ include/linux/lsm_hook_defs.h | 5 ++++ include/linux/security.h | 25 ++++++++++++++++++ kernel/bpf/bpf_lsm.c | 4 +++ kernel/bpf/token.c | 12 ++++++++- security/security.c | 60 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 108 insertions(+), 1 deletion(-) (limited to 'include/linux/security.h') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 4e146e9708be..b86bd15a051d 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1634,6 +1634,9 @@ struct bpf_token { u64 allowed_maps; u64 allowed_progs; u64 allowed_attachs; +#ifdef CONFIG_SECURITY + void *security; +#endif }; struct bpf_struct_ops_value; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 1be4d3ca6efb..cd6fbc7af3f8 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -410,6 +410,11 @@ LSM_HOOK(void, LSM_RET_VOID, bpf_map_free, struct bpf_map *map) LSM_HOOK(int, 0, bpf_prog_load, struct bpf_prog *prog, union bpf_attr *attr, struct bpf_token *token) LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog) +LSM_HOOK(int, 0, bpf_token_create, struct bpf_token *token, union bpf_attr *attr, + struct path *path) +LSM_HOOK(void, LSM_RET_VOID, bpf_token_free, struct bpf_token *token) +LSM_HOOK(int, 0, bpf_token_cmd, const struct bpf_token *token, enum bpf_cmd cmd) +LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap) #endif /* CONFIG_BPF_SYSCALL */ LSM_HOOK(int, 0, locked_down, enum lockdown_reason what) diff --git a/include/linux/security.h b/include/linux/security.h index 83fcdc974116..15804af54f37 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -32,6 +32,7 @@ #include #include #include +#include #include struct linux_binprm; @@ -2075,6 +2076,11 @@ extern void security_bpf_map_free(struct bpf_map *map); extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, struct bpf_token *token); extern void security_bpf_prog_free(struct bpf_prog *prog); +extern int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, + struct path *path); +extern void security_bpf_token_free(struct bpf_token *token); +extern int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd); +extern int security_bpf_token_capable(const struct bpf_token *token, int cap); #else static inline int security_bpf(int cmd, union bpf_attr *attr, unsigned int size) @@ -2109,6 +2115,25 @@ static inline int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr * static inline void security_bpf_prog_free(struct bpf_prog *prog) { } + +static inline int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, + struct path *path) +{ + return 0; +} + +static inline void security_bpf_token_free(struct bpf_token *token) +{ } + +static inline int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd) +{ + return 0; +} + +static inline int security_bpf_token_capable(const struct bpf_token *token, int cap) +{ + return 0; +} #endif /* CONFIG_SECURITY */ #endif /* CONFIG_BPF_SYSCALL */ diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index 76976908b302..63b4dc495125 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -265,6 +265,10 @@ BTF_ID(func, bpf_lsm_bpf_map_free) BTF_ID(func, bpf_lsm_bpf_prog) BTF_ID(func, bpf_lsm_bpf_prog_load) BTF_ID(func, bpf_lsm_bpf_prog_free) +BTF_ID(func, bpf_lsm_bpf_token_create) +BTF_ID(func, bpf_lsm_bpf_token_free) +BTF_ID(func, bpf_lsm_bpf_token_cmd) +BTF_ID(func, bpf_lsm_bpf_token_capable) BTF_ID(func, bpf_lsm_bprm_check_security) BTF_ID(func, bpf_lsm_bprm_committed_creds) BTF_ID(func, bpf_lsm_bprm_committing_creds) diff --git a/kernel/bpf/token.c b/kernel/bpf/token.c index c13c73788d8c..64c568f47f69 100644 --- a/kernel/bpf/token.c +++ b/kernel/bpf/token.c @@ -7,6 +7,7 @@ #include #include #include +#include static bool bpf_ns_capable(struct user_namespace *ns, int cap) { @@ -21,6 +22,8 @@ bool bpf_token_capable(const struct bpf_token *token, int cap) userns = token ? token->userns : &init_user_ns; if (!bpf_ns_capable(userns, cap)) return false; + if (token && security_bpf_token_capable(token, cap) < 0) + return false; return true; } @@ -31,6 +34,7 @@ void bpf_token_inc(struct bpf_token *token) static void bpf_token_free(struct bpf_token *token) { + security_bpf_token_free(token); put_user_ns(token->userns); kfree(token); } @@ -193,6 +197,10 @@ int bpf_token_create(union bpf_attr *attr) token->allowed_progs = mnt_opts->delegate_progs; token->allowed_attachs = mnt_opts->delegate_attachs; + err = security_bpf_token_create(token, attr, &path); + if (err) + goto out_token; + fd = get_unused_fd_flags(O_CLOEXEC); if (fd < 0) { err = fd; @@ -237,7 +245,9 @@ bool bpf_token_allow_cmd(const struct bpf_token *token, enum bpf_cmd cmd) { if (!token) return false; - return token->allowed_cmds & (1ULL << cmd); + if (!(token->allowed_cmds & (1ULL << cmd))) + return false; + return security_bpf_token_cmd(token, cmd) == 0; } bool bpf_token_allow_map_type(const struct bpf_token *token, enum bpf_map_type type) diff --git a/security/security.c b/security/security.c index 26fcab35b6cd..73e009e3d937 100644 --- a/security/security.c +++ b/security/security.c @@ -5444,6 +5444,55 @@ int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, return call_int_hook(bpf_prog_load, 0, prog, attr, token); } +/** + * security_bpf_token_create() - Check if creating of BPF token is allowed + * @token: BPF token object + * @attr: BPF syscall attributes used to create BPF token + * @path: path pointing to BPF FS mount point from which BPF token is created + * + * Do a check when the kernel instantiates a new BPF token object from BPF FS + * instance. This is also the point where LSM blob can be allocated for LSMs. + * + * Return: Returns 0 on success, error on failure. + */ +int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, + struct path *path) +{ + return call_int_hook(bpf_token_create, 0, token, attr, path); +} + +/** + * security_bpf_token_cmd() - Check if BPF token is allowed to delegate + * requested BPF syscall command + * @token: BPF token object + * @cmd: BPF syscall command requested to be delegated by BPF token + * + * Do a check when the kernel decides whether provided BPF token should allow + * delegation of requested BPF syscall command. + * + * Return: Returns 0 on success, error on failure. + */ +int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd) +{ + return call_int_hook(bpf_token_cmd, 0, token, cmd); +} + +/** + * security_bpf_token_capable() - Check if BPF token is allowed to delegate + * requested BPF-related capability + * @token: BPF token object + * @cap: capabilities requested to be delegated by BPF token + * + * Do a check when the kernel decides whether provided BPF token should allow + * delegation of requested BPF-related capabilities. + * + * Return: Returns 0 on success, error on failure. + */ +int security_bpf_token_capable(const struct bpf_token *token, int cap) +{ + return call_int_hook(bpf_token_capable, 0, token, cap); +} + /** * security_bpf_map_free() - Free a bpf map's LSM blob * @map: bpf map @@ -5465,6 +5514,17 @@ void security_bpf_prog_free(struct bpf_prog *prog) { call_void_hook(bpf_prog_free, prog); } + +/** + * security_bpf_token_free() - Free a BPF token's LSM blob + * @token: BPF token struct + * + * Clean up the security information stored inside BPF token. + */ +void security_bpf_token_free(struct bpf_token *token) +{ + call_void_hook(bpf_token_free, token); +} #endif /* CONFIG_BPF_SYSCALL */ /** -- cgit v1.2.3 From 77fa6f314f0376176ef6bf3d84403e0d8b54ce28 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:30:58 +0100 Subject: security: Introduce inode_post_setattr hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_setattr hook. At inode_setattr hook, EVM verifies the file's existing HMAC value. At inode_post_setattr, EVM re-calculates the file's HMAC based on the modified file attributes and other file metadata. Other LSMs could similarly take some action after successful file attribute change. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Reviewed-by: Mimi Zohar Acked-by: Casey Schaufler Acked-by: Christian Brauner Signed-off-by: Paul Moore --- fs/attr.c | 1 + include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 7 +++++++ security/security.c | 16 ++++++++++++++++ 4 files changed, 26 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/attr.c b/fs/attr.c index adeba0ec40f1..990e1b3a3c91 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -502,6 +502,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry, if (!error) { fsnotify_change(dentry, ia_valid); + security_inode_post_setattr(idmap, dentry, ia_valid); ima_inode_post_setattr(idmap, dentry, ia_valid); evm_inode_post_setattr(idmap, dentry, ia_valid); } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index b00b16d58413..a0e9e48015a4 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -137,6 +137,8 @@ LSM_HOOK(int, 0, inode_follow_link, struct dentry *dentry, struct inode *inode, LSM_HOOK(int, 0, inode_permission, struct inode *inode, int mask) LSM_HOOK(int, 0, inode_setattr, struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr) +LSM_HOOK(void, LSM_RET_VOID, inode_post_setattr, struct mnt_idmap *idmap, + struct dentry *dentry, int ia_valid) LSM_HOOK(int, 0, inode_getattr, const struct path *path) LSM_HOOK(int, 0, inode_setxattr, struct mnt_idmap *idmap, struct dentry *dentry, const char *name, const void *value, diff --git a/include/linux/security.h b/include/linux/security.h index d0eb20f90b26..56c841aa3994 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -361,6 +361,8 @@ int security_inode_follow_link(struct dentry *dentry, struct inode *inode, int security_inode_permission(struct inode *inode, int mask); int security_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr); +void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + int ia_valid); int security_inode_getattr(const struct path *path); int security_inode_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, @@ -879,6 +881,11 @@ static inline int security_inode_setattr(struct mnt_idmap *idmap, return 0; } +static inline void +security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + int ia_valid) +{ } + static inline int security_inode_getattr(const struct path *path) { return 0; diff --git a/security/security.c b/security/security.c index 9dc601d45960..56527d5415e2 100644 --- a/security/security.c +++ b/security/security.c @@ -2222,6 +2222,22 @@ int security_inode_setattr(struct mnt_idmap *idmap, } EXPORT_SYMBOL_GPL(security_inode_setattr); +/** + * security_inode_post_setattr() - Update the inode after a setattr operation + * @idmap: idmap of the mount + * @dentry: file + * @ia_valid: file attributes set + * + * Update inode security field after successful setting file attributes. + */ +void security_inode_post_setattr(struct mnt_idmap *idmap, struct dentry *dentry, + int ia_valid) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(inode_post_setattr, idmap, dentry, ia_valid); +} + /** * security_inode_getattr() - Check if getting file attributes is allowed * @path: file -- cgit v1.2.3 From dae52cbf5887ac51c3574648124cfe475a9b3246 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:30:59 +0100 Subject: security: Introduce inode_post_removexattr hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_removexattr hook. At inode_removexattr hook, EVM verifies the file's existing HMAC value. At inode_post_removexattr, EVM re-calculates the file's HMAC with the passed xattr removed and other file metadata. Other LSMs could similarly take some action after successful xattr removal. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Reviewed-by: Mimi Zohar Reviewed-by: Casey Schaufler Acked-by: Christian Brauner Signed-off-by: Paul Moore --- fs/xattr.c | 9 +++++---- include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 5 +++++ security/security.c | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) (limited to 'include/linux/security.h') diff --git a/fs/xattr.c b/fs/xattr.c index 09d927603433..f891c260a971 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -552,11 +552,12 @@ __vfs_removexattr_locked(struct mnt_idmap *idmap, goto out; error = __vfs_removexattr(idmap, dentry, name); + if (error) + return error; - if (!error) { - fsnotify_xattr(dentry); - evm_inode_post_removexattr(dentry, name); - } + fsnotify_xattr(dentry); + security_inode_post_removexattr(dentry, name); + evm_inode_post_removexattr(dentry, name); out: return error; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index a0e9e48015a4..f849f7d5bb53 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -149,6 +149,8 @@ LSM_HOOK(int, 0, inode_getxattr, struct dentry *dentry, const char *name) LSM_HOOK(int, 0, inode_listxattr, struct dentry *dentry) LSM_HOOK(int, 0, inode_removexattr, struct mnt_idmap *idmap, struct dentry *dentry, const char *name) +LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, + const char *name) LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, diff --git a/include/linux/security.h b/include/linux/security.h index 56c841aa3994..84ae03690340 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -380,6 +380,7 @@ int security_inode_getxattr(struct dentry *dentry, const char *name); int security_inode_listxattr(struct dentry *dentry); int security_inode_removexattr(struct mnt_idmap *idmap, struct dentry *dentry, const char *name); +void security_inode_post_removexattr(struct dentry *dentry, const char *name); int security_inode_need_killpriv(struct dentry *dentry); int security_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry); int security_inode_getsecurity(struct mnt_idmap *idmap, @@ -942,6 +943,10 @@ static inline int security_inode_removexattr(struct mnt_idmap *idmap, return cap_inode_removexattr(idmap, dentry, name); } +static inline void security_inode_post_removexattr(struct dentry *dentry, + const char *name) +{ } + static inline int security_inode_need_killpriv(struct dentry *dentry) { return cap_inode_need_killpriv(dentry); diff --git a/security/security.c b/security/security.c index 56527d5415e2..d77fdd3ca1bc 100644 --- a/security/security.c +++ b/security/security.c @@ -2452,6 +2452,20 @@ int security_inode_removexattr(struct mnt_idmap *idmap, return evm_inode_removexattr(idmap, dentry, name); } +/** + * security_inode_post_removexattr() - Update the inode after a removexattr op + * @dentry: file + * @name: xattr name + * + * Update the inode after a successful removexattr operation. + */ +void security_inode_post_removexattr(struct dentry *dentry, const char *name) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(inode_post_removexattr, dentry, name); +} + /** * security_inode_need_killpriv() - Check if security_inode_killpriv() required * @dentry: associated dentry -- cgit v1.2.3 From 8f46ff5767b0b18329140d80d6bcabd818f42c4c Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:00 +0100 Subject: security: Introduce file_post_open hook In preparation to move IMA and EVM to the LSM infrastructure, introduce the file_post_open hook. Also, export security_file_post_open() for NFS. Based on policy, IMA calculates the digest of the file content and extends the TPM with the digest, verifies the file's integrity based on the digest, and/or includes the file digest in the audit log. LSMs could similarly take action depending on the file content and the access mask requested with open(). The new hook returns a value and can cause the open to be aborted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Acked-by: Christian Brauner Signed-off-by: Paul Moore --- fs/namei.c | 2 ++ fs/nfsd/vfs.c | 6 ++++++ include/linux/lsm_hook_defs.h | 1 + include/linux/security.h | 6 ++++++ security/security.c | 17 +++++++++++++++++ 5 files changed, 32 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/namei.c b/fs/namei.c index 4e0de939fea1..ef867f1d6704 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3639,6 +3639,8 @@ static int do_open(struct nameidata *nd, error = may_open(idmap, &nd->path, acc_mode, open_flag); if (!error && !(file->f_mode & FMODE_OPENED)) error = vfs_open(&nd->path, file); + if (!error) + error = security_file_post_open(file, op->acc_mode); if (!error) error = ima_file_check(file, op->acc_mode); if (!error && do_truncate) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index b7c7a9273ea0..e44d8239545b 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -877,6 +877,12 @@ __nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, goto out; } + host_err = security_file_post_open(file, may_flags); + if (host_err) { + fput(file); + goto out; + } + host_err = ima_file_check(file, may_flags); if (host_err) { fput(file); diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index f849f7d5bb53..3c84942d2818 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -191,6 +191,7 @@ LSM_HOOK(int, 0, file_send_sigiotask, struct task_struct *tsk, struct fown_struct *fown, int sig) LSM_HOOK(int, 0, file_receive, struct file *file) LSM_HOOK(int, 0, file_open, struct file *file) +LSM_HOOK(int, 0, file_post_open, struct file *file, int mask) LSM_HOOK(int, 0, file_truncate, struct file *file) LSM_HOOK(int, 0, task_alloc, struct task_struct *task, unsigned long clone_flags) diff --git a/include/linux/security.h b/include/linux/security.h index 84ae03690340..97f2212c13b6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -411,6 +411,7 @@ int security_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int sig); int security_file_receive(struct file *file); int security_file_open(struct file *file); +int security_file_post_open(struct file *file, int mask); int security_file_truncate(struct file *file); int security_task_alloc(struct task_struct *task, unsigned long clone_flags); void security_task_free(struct task_struct *task); @@ -1074,6 +1075,11 @@ static inline int security_file_open(struct file *file) return 0; } +static inline int security_file_post_open(struct file *file, int mask) +{ + return 0; +} + static inline int security_file_truncate(struct file *file) { return 0; diff --git a/security/security.c b/security/security.c index d77fdd3ca1bc..207405a84902 100644 --- a/security/security.c +++ b/security/security.c @@ -2966,6 +2966,23 @@ int security_file_open(struct file *file) return fsnotify_open_perm(file); } +/** + * security_file_post_open() - Evaluate a file after it has been opened + * @file: the file + * @mask: access mask + * + * Evaluate an opened file and the access mask requested with open(). The hook + * is useful for LSMs that require the file content to be available in order to + * make decisions. + * + * Return: Returns 0 if permission is granted. + */ +int security_file_post_open(struct file *file, int mask) +{ + return call_int_hook(file_post_open, 0, file, mask); +} +EXPORT_SYMBOL_GPL(security_file_post_open); + /** * security_file_truncate() - Check if truncating a file is allowed * @file: file -- cgit v1.2.3 From f09068b5a114ed28d2df2e82a7d30dde0145dc69 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:01 +0100 Subject: security: Introduce file_release hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the file_release hook. IMA calculates at file close the new digest of the file content and writes it to security.ima, so that appraisal at next file access succeeds. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Acked-by: Christian Brauner Reviewed-by: Stefan Berger Reviewed-by: Mimi Zohar Signed-off-by: Paul Moore --- fs/file_table.c | 1 + include/linux/lsm_hook_defs.h | 1 + include/linux/security.h | 4 ++++ security/security.c | 11 +++++++++++ 4 files changed, 17 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/file_table.c b/fs/file_table.c index b991f90571b4..725407f374fa 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -367,6 +367,7 @@ static void __fput(struct file *file) eventpoll_release(file); locks_remove_file(file); + security_file_release(file); ima_file_free(file); if (unlikely(file->f_flags & FASYNC)) { if (file->f_op->fasync) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 3c84942d2818..7f9e9240606e 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -173,6 +173,7 @@ LSM_HOOK(int, 0, kernfs_init_security, struct kernfs_node *kn_dir, struct kernfs_node *kn) LSM_HOOK(int, 0, file_permission, struct file *file, int mask) LSM_HOOK(int, 0, file_alloc_security, struct file *file) +LSM_HOOK(void, LSM_RET_VOID, file_release, struct file *file) LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file) LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, unsigned long arg) diff --git a/include/linux/security.h b/include/linux/security.h index 97f2212c13b6..2997348afcb7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -395,6 +395,7 @@ int security_kernfs_init_security(struct kernfs_node *kn_dir, struct kernfs_node *kn); int security_file_permission(struct file *file, int mask); int security_file_alloc(struct file *file); +void security_file_release(struct file *file); void security_file_free(struct file *file); int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int security_file_ioctl_compat(struct file *file, unsigned int cmd, @@ -1008,6 +1009,9 @@ static inline int security_file_alloc(struct file *file) return 0; } +static inline void security_file_release(struct file *file) +{ } + static inline void security_file_free(struct file *file) { } diff --git a/security/security.c b/security/security.c index 207405a84902..99004c44ce55 100644 --- a/security/security.c +++ b/security/security.c @@ -2718,6 +2718,17 @@ int security_file_alloc(struct file *file) return rc; } +/** + * security_file_release() - Perform actions before releasing the file ref + * @file: the file + * + * Perform actions before releasing the last reference to a file. + */ +void security_file_release(struct file *file) +{ + call_void_hook(file_release, file); +} + /** * security_file_free() - Free a file's LSM blob * @file: the file -- cgit v1.2.3 From 08abce60d63fb55f440c393f4508e99064f2fd91 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:02 +0100 Subject: security: Introduce path_post_mknod hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the path_post_mknod hook. IMA-appraisal requires all existing files in policy to have a file hash/signature stored in security.ima. An exception is made for empty files created by mknod, by tagging them as new files. LSMs could also take some action after files are created. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Acked-by: Christian Brauner Reviewed-by: Stefan Berger Signed-off-by: Paul Moore --- fs/namei.c | 5 +++++ include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 5 +++++ security/security.c | 14 ++++++++++++++ 4 files changed, 26 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/namei.c b/fs/namei.c index ef867f1d6704..9280aa5d60a7 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4063,6 +4063,11 @@ retry: dentry, mode, 0); break; } + + if (error) + goto out2; + + security_path_post_mknod(idmap, dentry); out2: done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 7f9e9240606e..dba5d8204dc5 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -94,6 +94,8 @@ LSM_HOOK(int, 0, path_mkdir, const struct path *dir, struct dentry *dentry, LSM_HOOK(int, 0, path_rmdir, const struct path *dir, struct dentry *dentry) LSM_HOOK(int, 0, path_mknod, const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) +LSM_HOOK(void, LSM_RET_VOID, path_post_mknod, struct mnt_idmap *idmap, + struct dentry *dentry) LSM_HOOK(int, 0, path_truncate, const struct path *path) LSM_HOOK(int, 0, path_symlink, const struct path *dir, struct dentry *dentry, const char *old_name) diff --git a/include/linux/security.h b/include/linux/security.h index 2997348afcb7..977dd9f7f51a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1893,6 +1893,7 @@ int security_path_mkdir(const struct path *dir, struct dentry *dentry, umode_t m int security_path_rmdir(const struct path *dir, struct dentry *dentry); int security_path_mknod(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev); +void security_path_post_mknod(struct mnt_idmap *idmap, struct dentry *dentry); int security_path_truncate(const struct path *path); int security_path_symlink(const struct path *dir, struct dentry *dentry, const char *old_name); @@ -1927,6 +1928,10 @@ static inline int security_path_mknod(const struct path *dir, struct dentry *den return 0; } +static inline void security_path_post_mknod(struct mnt_idmap *idmap, + struct dentry *dentry) +{ } + static inline int security_path_truncate(const struct path *path) { return 0; diff --git a/security/security.c b/security/security.c index 99004c44ce55..ee4582e1d4d0 100644 --- a/security/security.c +++ b/security/security.c @@ -1800,6 +1800,20 @@ int security_path_mknod(const struct path *dir, struct dentry *dentry, } EXPORT_SYMBOL(security_path_mknod); +/** + * security_path_post_mknod() - Update inode security field after file creation + * @idmap: idmap of the mount + * @dentry: new file + * + * Update inode security field after a file has been created. + */ +void security_path_post_mknod(struct mnt_idmap *idmap, struct dentry *dentry) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(path_post_mknod, idmap, dentry); +} + /** * security_path_mkdir() - Check if creating a new directory is allowed * @dir: parent directory -- cgit v1.2.3 From a7811e34d100acf24870eb949c5ae3e49dde18b9 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:03 +0100 Subject: security: Introduce inode_post_create_tmpfile hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_create_tmpfile hook. As temp files can be made persistent, treat new temp files like other new files, so that the file hash is calculated and stored in the security xattr. LSMs could also take some action after temp files have been created. The new hook cannot return an error and cannot cause the operation to be canceled. Signed-off-by: Roberto Sassu Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Acked-by: Christian Brauner Reviewed-by: Stefan Berger Signed-off-by: Paul Moore --- fs/namei.c | 1 + include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 6 ++++++ security/security.c | 15 +++++++++++++++ 4 files changed, 24 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/namei.c b/fs/namei.c index 9280aa5d60a7..c7ac7fdf0f25 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -3705,6 +3705,7 @@ static int vfs_tmpfile(struct mnt_idmap *idmap, inode->i_state |= I_LINKABLE; spin_unlock(&inode->i_lock); } + security_inode_post_create_tmpfile(idmap, inode); ima_post_create_tmpfile(idmap, inode); return 0; } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index dba5d8204dc5..87f60b47dfca 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -121,6 +121,8 @@ LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode, const struct qstr *name, const struct inode *context_inode) LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry, umode_t mode) +LSM_HOOK(void, LSM_RET_VOID, inode_post_create_tmpfile, struct mnt_idmap *idmap, + struct inode *inode) LSM_HOOK(int, 0, inode_link, struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) LSM_HOOK(int, 0, inode_unlink, struct inode *dir, struct dentry *dentry) diff --git a/include/linux/security.h b/include/linux/security.h index 977dd9f7f51a..1cb604282617 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -344,6 +344,8 @@ int security_inode_init_security_anon(struct inode *inode, const struct qstr *name, const struct inode *context_inode); int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode); +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap, + struct inode *inode); int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); int security_inode_unlink(struct inode *dir, struct dentry *dentry); @@ -811,6 +813,10 @@ static inline int security_inode_create(struct inode *dir, return 0; } +static inline void +security_inode_post_create_tmpfile(struct mnt_idmap *idmap, struct inode *inode) +{ } + static inline int security_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) diff --git a/security/security.c b/security/security.c index ee4582e1d4d0..710db090aa8b 100644 --- a/security/security.c +++ b/security/security.c @@ -2013,6 +2013,21 @@ int security_inode_create(struct inode *dir, struct dentry *dentry, } EXPORT_SYMBOL_GPL(security_inode_create); +/** + * security_inode_post_create_tmpfile() - Update inode security of new tmpfile + * @idmap: idmap of the mount + * @inode: inode of the new tmpfile + * + * Update inode security data after a tmpfile has been created. + */ +void security_inode_post_create_tmpfile(struct mnt_idmap *idmap, + struct inode *inode) +{ + if (unlikely(IS_PRIVATE(inode))) + return; + call_void_hook(inode_post_create_tmpfile, idmap, inode); +} + /** * security_inode_link() - Check if creating a hard link is allowed * @old_dentry: existing file -- cgit v1.2.3 From 8b9d0b825c6573d654c8b8039ea79920926305c2 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:04 +0100 Subject: security: Introduce inode_post_set_acl hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_set_acl hook. At inode_set_acl hook, EVM verifies the file's existing HMAC value. At inode_post_set_acl, EVM re-calculates the file's HMAC based on the modified POSIX ACL and other file metadata. Other LSMs could similarly take some action after successful POSIX ACL change. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Acked-by: Christian Brauner Signed-off-by: Paul Moore --- fs/posix_acl.c | 1 + include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 7 +++++++ security/security.c | 17 +++++++++++++++++ 4 files changed, 27 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/posix_acl.c b/fs/posix_acl.c index e1af20893ebe..7556ee9f8a51 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1137,6 +1137,7 @@ retry_deleg: error = -EIO; if (!error) { fsnotify_xattr(dentry); + security_inode_post_set_acl(dentry, acl_name, kacl); evm_inode_post_set_acl(dentry, acl_name, kacl); } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 87f60b47dfca..b0125c99f80a 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -157,6 +157,8 @@ LSM_HOOK(void, LSM_RET_VOID, inode_post_removexattr, struct dentry *dentry, const char *name) LSM_HOOK(int, 0, inode_set_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl) +LSM_HOOK(void, LSM_RET_VOID, inode_post_set_acl, struct dentry *dentry, + const char *acl_name, struct posix_acl *kacl) LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap, diff --git a/include/linux/security.h b/include/linux/security.h index 1cb604282617..c372797e1617 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -372,6 +372,8 @@ int security_inode_setxattr(struct mnt_idmap *idmap, int security_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl); +void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name, + struct posix_acl *kacl); int security_inode_get_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name); int security_inode_remove_acl(struct mnt_idmap *idmap, @@ -915,6 +917,11 @@ static inline int security_inode_set_acl(struct mnt_idmap *idmap, return 0; } +static inline void security_inode_post_set_acl(struct dentry *dentry, + const char *acl_name, + struct posix_acl *kacl) +{ } + static inline int security_inode_get_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) diff --git a/security/security.c b/security/security.c index 710db090aa8b..52f62f785087 100644 --- a/security/security.c +++ b/security/security.c @@ -2350,6 +2350,23 @@ int security_inode_set_acl(struct mnt_idmap *idmap, return evm_inode_set_acl(idmap, dentry, acl_name, kacl); } +/** + * security_inode_post_set_acl() - Update inode security from posix acls set + * @dentry: file + * @acl_name: acl name + * @kacl: acl struct + * + * Update inode security data after successfully setting posix acls on @dentry. + * The posix acls in @kacl are identified by @acl_name. + */ +void security_inode_post_set_acl(struct dentry *dentry, const char *acl_name, + struct posix_acl *kacl) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(inode_post_set_acl, dentry, acl_name, kacl); +} + /** * security_inode_get_acl() - Check if reading posix acls is allowed * @idmap: idmap of the mount -- cgit v1.2.3 From 2d705d8024143c272a764320c880ccd3230bb699 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:05 +0100 Subject: security: Introduce inode_post_remove_acl hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the inode_post_remove_acl hook. At inode_remove_acl hook, EVM verifies the file's existing HMAC value. At inode_post_remove_acl, EVM re-calculates the file's HMAC with the passed POSIX ACL removed and other file metadata. Other LSMs could similarly take some action after successful POSIX ACL removal. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Acked-by: Christian Brauner Signed-off-by: Paul Moore --- fs/posix_acl.c | 1 + include/linux/lsm_hook_defs.h | 2 ++ include/linux/security.h | 8 ++++++++ security/security.c | 17 +++++++++++++++++ 4 files changed, 28 insertions(+) (limited to 'include/linux/security.h') diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 7556ee9f8a51..0d2371240c1b 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -1246,6 +1246,7 @@ retry_deleg: error = -EIO; if (!error) { fsnotify_xattr(dentry); + security_inode_post_remove_acl(idmap, dentry, acl_name); evm_inode_post_remove_acl(idmap, dentry, acl_name); } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index b0125c99f80a..7e414ba26333 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -163,6 +163,8 @@ LSM_HOOK(int, 0, inode_get_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) LSM_HOOK(int, 0, inode_remove_acl, struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) +LSM_HOOK(void, LSM_RET_VOID, inode_post_remove_acl, struct mnt_idmap *idmap, + struct dentry *dentry, const char *acl_name) LSM_HOOK(int, 0, inode_need_killpriv, struct dentry *dentry) LSM_HOOK(int, 0, inode_killpriv, struct mnt_idmap *idmap, struct dentry *dentry) diff --git a/include/linux/security.h b/include/linux/security.h index c372797e1617..4b03c76b91f1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -378,6 +378,9 @@ int security_inode_get_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name); int security_inode_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name); +void security_inode_post_remove_acl(struct mnt_idmap *idmap, + struct dentry *dentry, + const char *acl_name); void security_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); int security_inode_getxattr(struct dentry *dentry, const char *name); @@ -936,6 +939,11 @@ static inline int security_inode_remove_acl(struct mnt_idmap *idmap, return 0; } +static inline void security_inode_post_remove_acl(struct mnt_idmap *idmap, + struct dentry *dentry, + const char *acl_name) +{ } + static inline void security_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { } diff --git a/security/security.c b/security/security.c index 52f62f785087..3bed660fc950 100644 --- a/security/security.c +++ b/security/security.c @@ -2413,6 +2413,23 @@ int security_inode_remove_acl(struct mnt_idmap *idmap, return evm_inode_remove_acl(idmap, dentry, acl_name); } +/** + * security_inode_post_remove_acl() - Update inode security after rm posix acls + * @idmap: idmap of the mount + * @dentry: file + * @acl_name: acl name + * + * Update inode security data after successfully removing posix acls on + * @dentry in @idmap. The posix acls are identified by @acl_name. + */ +void security_inode_post_remove_acl(struct mnt_idmap *idmap, + struct dentry *dentry, const char *acl_name) +{ + if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) + return; + call_void_hook(inode_post_remove_acl, idmap, dentry, acl_name); +} + /** * security_inode_post_setxattr() - Update the inode after a setxattr operation * @dentry: file -- cgit v1.2.3 From b8d997032a46fcf47d5bda011c0d1e87b20c08ba Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Thu, 15 Feb 2024 11:31:06 +0100 Subject: security: Introduce key_post_create_or_update hook In preparation for moving IMA and EVM to the LSM infrastructure, introduce the key_post_create_or_update hook. Depending on policy, IMA measures the key content after creation or update, so that remote verifiers are aware of the operation. Other LSMs could similarly take some action after successful key creation or update. The new hook cannot return an error and cannot cause the operation to be reverted. Signed-off-by: Roberto Sassu Reviewed-by: Stefan Berger Acked-by: Casey Schaufler Reviewed-by: Mimi Zohar Signed-off-by: Paul Moore --- include/linux/lsm_hook_defs.h | 3 +++ include/linux/security.h | 11 +++++++++++ security/keys/key.c | 7 ++++++- security/security.c | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) (limited to 'include/linux/security.h') diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 7e414ba26333..7e4683035d34 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -405,6 +405,9 @@ LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key) LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm) LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer) +LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring, + struct key *key, const void *payload, size_t payload_len, + unsigned long flags, bool create) #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT diff --git a/include/linux/security.h b/include/linux/security.h index 4b03c76b91f1..8436f9abf43d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -2004,6 +2004,9 @@ void security_key_free(struct key *key); int security_key_permission(key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm); int security_key_getsecurity(struct key *key, char **_buffer); +void security_key_post_create_or_update(struct key *keyring, struct key *key, + const void *payload, size_t payload_len, + unsigned long flags, bool create); #else @@ -2031,6 +2034,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) return 0; } +static inline void security_key_post_create_or_update(struct key *keyring, + struct key *key, + const void *payload, + size_t payload_len, + unsigned long flags, + bool create) +{ } + #endif #endif /* CONFIG_KEYS */ diff --git a/security/keys/key.c b/security/keys/key.c index 5b10641debd5..31a8b9408b7c 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -930,6 +930,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, goto error_link_end; } + security_key_post_create_or_update(keyring, key, payload, plen, flags, + true); ima_post_key_create_or_update(keyring, key, payload, plen, flags, true); @@ -963,10 +965,13 @@ error: key_ref = __key_update(key_ref, &prep); - if (!IS_ERR(key_ref)) + if (!IS_ERR(key_ref)) { + security_key_post_create_or_update(keyring, key, payload, plen, + flags, false); ima_post_key_create_or_update(keyring, key, payload, plen, flags, false); + } goto error_free_prep; } diff --git a/security/security.c b/security/security.c index 3bed660fc950..6c23c620e3c1 100644 --- a/security/security.c +++ b/security/security.c @@ -5453,6 +5453,25 @@ int security_key_getsecurity(struct key *key, char **buffer) *buffer = NULL; return call_int_hook(key_getsecurity, 0, key, buffer); } + +/** + * security_key_post_create_or_update() - Notification of key create or update + * @keyring: keyring to which the key is linked to + * @key: created or updated key + * @payload: data used to instantiate or update the key + * @payload_len: length of payload + * @flags: key flags + * @create: flag indicating whether the key was created or updated + * + * Notify the caller of a key creation or update. + */ +void security_key_post_create_or_update(struct key *keyring, struct key *key, + const void *payload, size_t payload_len, + unsigned long flags, bool create) +{ + call_void_hook(key_post_create_or_update, keyring, key, payload, + payload_len, flags, create); +} #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT -- cgit v1.2.3 From a5a858f622a0aff5cdb5e271442cd01b2a01467f Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Thu, 14 Mar 2024 11:31:26 -0400 Subject: lsm: use 32-bit compatible data types in LSM syscalls Change the size parameters in lsm_list_modules(), lsm_set_self_attr() and lsm_get_self_attr() from size_t to u32. This avoids the need to have different interfaces for 32 and 64 bit systems. Cc: stable@vger.kernel.org Fixes: a04a1198088a ("LSM: syscalls for current process attributes") Fixes: ad4aff9ec25f ("LSM: Create lsm_list_modules system call") Signed-off-by: Casey Schaufler Reported-and-reviewed-by: Dmitry V. Levin [PM: subject and metadata tweaks, syscall.h fixes] Signed-off-by: Paul Moore --- include/linux/lsm_hook_defs.h | 4 ++-- include/linux/security.h | 8 ++++---- include/linux/syscalls.h | 6 +++--- security/apparmor/lsm.c | 4 ++-- security/lsm_syscalls.c | 10 +++++----- security/security.c | 12 ++++++------ security/selinux/hooks.c | 4 ++-- security/smack/smack_lsm.c | 4 ++-- tools/testing/selftests/lsm/common.h | 6 +++--- tools/testing/selftests/lsm/lsm_get_self_attr_test.c | 10 +++++----- tools/testing/selftests/lsm/lsm_list_modules_test.c | 8 ++++---- tools/testing/selftests/lsm/lsm_set_self_attr_test.c | 6 +++--- 12 files changed, 41 insertions(+), 41 deletions(-) (limited to 'include/linux/security.h') diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index a8057a3f8de6..334e00efbde4 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -280,9 +280,9 @@ LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb) LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry, struct inode *inode) LSM_HOOK(int, -EOPNOTSUPP, getselfattr, unsigned int attr, - struct lsm_ctx __user *ctx, size_t *size, u32 flags) + struct lsm_ctx __user *ctx, u32 *size, u32 flags) LSM_HOOK(int, -EOPNOTSUPP, setselfattr, unsigned int attr, - struct lsm_ctx *ctx, size_t size, u32 flags) + struct lsm_ctx *ctx, u32 size, u32 flags) LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, char **value) LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) diff --git a/include/linux/security.h b/include/linux/security.h index f249f5b9a9d7..41a8f667bdfa 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -491,9 +491,9 @@ int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter); void security_d_instantiate(struct dentry *dentry, struct inode *inode); int security_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, - size_t __user *size, u32 flags); + u32 __user *size, u32 flags); int security_setselfattr(unsigned int attr, struct lsm_ctx __user *ctx, - size_t size, u32 flags); + u32 size, u32 flags); int security_getprocattr(struct task_struct *p, int lsmid, const char *name, char **value); int security_setprocattr(int lsmid, const char *name, void *value, size_t size); @@ -507,7 +507,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); int security_locked_down(enum lockdown_reason what); -int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, +int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags); #else /* CONFIG_SECURITY */ @@ -1478,7 +1478,7 @@ static inline int security_locked_down(enum lockdown_reason what) return 0; } static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, - size_t *uctx_len, void *val, size_t val_len, + u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags) { return -EOPNOTSUPP; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 77eb9b0e7685..e619ac10cd23 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -960,10 +960,10 @@ asmlinkage long sys_cachestat(unsigned int fd, struct cachestat __user *cstat, unsigned int flags); asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags); asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, - size_t *size, __u32 flags); + u32 *size, u32 flags); asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, - size_t size, __u32 flags); -asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags); + u32 size, u32 flags); +asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags); /* * Architecture-specific system calls diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 9a3dcaafb5b1..cef8c466af80 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -779,7 +779,7 @@ static int apparmor_sb_pivotroot(const struct path *old_path, } static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx, - size_t *size, u32 flags) + u32 *size, u32 flags) { int error = -ENOENT; struct aa_task_ctx *ctx = task_ctx(current); @@ -924,7 +924,7 @@ fail: } static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx, - size_t size, u32 flags) + u32 size, u32 flags) { int rc; diff --git a/security/lsm_syscalls.c b/security/lsm_syscalls.c index 5d391b1f7e69..8440948a690c 100644 --- a/security/lsm_syscalls.c +++ b/security/lsm_syscalls.c @@ -53,7 +53,7 @@ u64 lsm_name_to_attr(const char *name) * value indicating the reason for the error is returned. */ SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, - ctx, size_t, size, u32, flags) + ctx, u32, size, u32, flags) { return security_setselfattr(attr, ctx, size, flags); } @@ -75,7 +75,7 @@ SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, * a negative value indicating the error is returned. */ SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *, - ctx, size_t __user *, size, u32, flags) + ctx, u32 __user *, size, u32, flags) { return security_getselfattr(attr, ctx, size, flags); } @@ -93,11 +93,11 @@ SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *, * required size. In all other cases a negative value indicating the * error is returned. */ -SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, size_t __user *, size, +SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, u32 __user *, size, u32, flags) { - size_t total_size = lsm_active_cnt * sizeof(*ids); - size_t usize; + u32 total_size = lsm_active_cnt * sizeof(*ids); + u32 usize; int i; if (flags) diff --git a/security/security.c b/security/security.c index a07f43c58d65..5b2e0a15377d 100644 --- a/security/security.c +++ b/security/security.c @@ -785,7 +785,7 @@ static int lsm_superblock_alloc(struct super_block *sb) * Returns 0 on success, -E2BIG if userspace buffer is not large enough, * -EFAULT on a copyout error, -ENOMEM if memory can't be allocated. */ -int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, +int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags) { @@ -3931,14 +3931,14 @@ EXPORT_SYMBOL(security_d_instantiate); * If @size is insufficient to contain the data -E2BIG is returned. */ int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx, - size_t __user *size, u32 flags) + u32 __user *size, u32 flags) { struct security_hook_list *hp; struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, }; u8 __user *base = (u8 __user *)uctx; - size_t total = 0; - size_t entrysize; - size_t left; + u32 entrysize; + u32 total = 0; + u32 left; bool toobig = false; bool single = false; int count = 0; @@ -4024,7 +4024,7 @@ int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx, * LSM specific failure. */ int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx, - size_t size, u32 flags) + u32 size, u32 flags) { struct security_hook_list *hp; struct lsm_ctx *lctx; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8db4875164ab..3448454c82d0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6559,7 +6559,7 @@ abort_change: * There will only ever be one attribute. */ static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, - size_t *size, u32 flags) + u32 *size, u32 flags) { int rc; char *val = NULL; @@ -6574,7 +6574,7 @@ static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, } static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx, - size_t size, u32 flags) + u32 size, u32 flags) { int rc; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 28be26712396..146667937811 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3653,7 +3653,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * There will only ever be one attribute. */ static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, - size_t *size, u32 flags) + u32 *size, u32 flags) { int rc; struct smack_known *skp; @@ -3774,7 +3774,7 @@ static int do_setattr(u64 attr, void *value, size_t size) * Returns 0 on success, an error code otherwise. */ static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, - size_t size, u32 flags) + u32 size, u32 flags) { int rc; diff --git a/tools/testing/selftests/lsm/common.h b/tools/testing/selftests/lsm/common.h index d404329e5eeb..06d12110d241 100644 --- a/tools/testing/selftests/lsm/common.h +++ b/tools/testing/selftests/lsm/common.h @@ -7,7 +7,7 @@ #ifndef lsm_get_self_attr static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, - size_t *size, __u32 flags) + __u32 *size, __u32 flags) { return syscall(__NR_lsm_get_self_attr, attr, ctx, size, flags); } @@ -15,14 +15,14 @@ static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, #ifndef lsm_set_self_attr static inline int lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, - size_t size, __u32 flags) + __u32 size, __u32 flags) { return syscall(__NR_lsm_set_self_attr, attr, ctx, size, flags); } #endif #ifndef lsm_list_modules -static inline int lsm_list_modules(__u64 *ids, size_t *size, __u32 flags) +static inline int lsm_list_modules(__u64 *ids, __u32 *size, __u32 flags) { return syscall(__NR_lsm_list_modules, ids, size, flags); } diff --git a/tools/testing/selftests/lsm/lsm_get_self_attr_test.c b/tools/testing/selftests/lsm/lsm_get_self_attr_test.c index e0e313d9047a..df215e4aa63f 100644 --- a/tools/testing/selftests/lsm/lsm_get_self_attr_test.c +++ b/tools/testing/selftests/lsm/lsm_get_self_attr_test.c @@ -40,7 +40,7 @@ TEST(size_null_lsm_get_self_attr) TEST(ctx_null_lsm_get_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); - size_t size = page_size; + __u32 size = page_size; int rc; rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0); @@ -57,7 +57,7 @@ TEST(size_too_small_lsm_get_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); struct lsm_ctx *ctx = calloc(page_size, 1); - size_t size = 1; + __u32 size = 1; ASSERT_NE(NULL, ctx); errno = 0; @@ -77,7 +77,7 @@ TEST(flags_zero_lsm_get_self_attr) const long page_size = sysconf(_SC_PAGESIZE); struct lsm_ctx *ctx = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1); - size_t size; + __u32 size; int lsmcount; int i; @@ -117,7 +117,7 @@ TEST(flags_overset_lsm_get_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); struct lsm_ctx *ctx = calloc(page_size, 1); - size_t size; + __u32 size; ASSERT_NE(NULL, ctx); @@ -140,7 +140,7 @@ TEST(flags_overset_lsm_get_self_attr) TEST(basic_lsm_get_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); - size_t size = page_size; + __u32 size = page_size; struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *tctx = NULL; __u64 *syscall_lsms = calloc(page_size, 1); diff --git a/tools/testing/selftests/lsm/lsm_list_modules_test.c b/tools/testing/selftests/lsm/lsm_list_modules_test.c index 4d5d4cee2586..06d24d4679a6 100644 --- a/tools/testing/selftests/lsm/lsm_list_modules_test.c +++ b/tools/testing/selftests/lsm/lsm_list_modules_test.c @@ -31,7 +31,7 @@ TEST(size_null_lsm_list_modules) TEST(ids_null_lsm_list_modules) { const long page_size = sysconf(_SC_PAGESIZE); - size_t size = page_size; + __u32 size = page_size; errno = 0; ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0)); @@ -43,7 +43,7 @@ TEST(size_too_small_lsm_list_modules) { const long page_size = sysconf(_SC_PAGESIZE); __u64 *syscall_lsms = calloc(page_size, 1); - size_t size = 1; + __u32 size = 1; ASSERT_NE(NULL, syscall_lsms); errno = 0; @@ -58,7 +58,7 @@ TEST(flags_set_lsm_list_modules) { const long page_size = sysconf(_SC_PAGESIZE); __u64 *syscall_lsms = calloc(page_size, 1); - size_t size = page_size; + __u32 size = page_size; ASSERT_NE(NULL, syscall_lsms); errno = 0; @@ -72,7 +72,7 @@ TEST(flags_set_lsm_list_modules) TEST(correct_lsm_list_modules) { const long page_size = sysconf(_SC_PAGESIZE); - size_t size = page_size; + __u32 size = page_size; __u64 *syscall_lsms = calloc(page_size, 1); char *sysfs_lsms = calloc(page_size, 1); char *name; diff --git a/tools/testing/selftests/lsm/lsm_set_self_attr_test.c b/tools/testing/selftests/lsm/lsm_set_self_attr_test.c index e9712c6cf596..66dec47e3ca3 100644 --- a/tools/testing/selftests/lsm/lsm_set_self_attr_test.c +++ b/tools/testing/selftests/lsm/lsm_set_self_attr_test.c @@ -25,7 +25,7 @@ TEST(size_too_small_lsm_set_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); struct lsm_ctx *ctx = calloc(page_size, 1); - size_t size = page_size; + __u32 size = page_size; ASSERT_NE(NULL, ctx); if (attr_lsm_count()) { @@ -41,7 +41,7 @@ TEST(flags_zero_lsm_set_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); struct lsm_ctx *ctx = calloc(page_size, 1); - size_t size = page_size; + __u32 size = page_size; ASSERT_NE(NULL, ctx); if (attr_lsm_count()) { @@ -57,7 +57,7 @@ TEST(flags_overset_lsm_set_self_attr) { const long page_size = sysconf(_SC_PAGESIZE); char *ctx = calloc(page_size, 1); - size_t size = page_size; + __u32 size = page_size; struct lsm_ctx *tctx = (struct lsm_ctx *)ctx; ASSERT_NE(NULL, ctx); -- cgit v1.2.3