Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

landlock: Identify domain execution crossing

Extend struct landlock_cred_security with a domain_exec bitmask to
identify which Landlock domain were created by the current task's bprm.
The whole bitmask is reset on each execve(2) call.

Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20250320190717.2287696-9-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>

+59 -6
+23 -5
security/landlock/cred.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Landlock LSM - Credential hooks 3 + * Landlock - Credential hooks 4 4 * 5 5 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> 6 6 * Copyright © 2018-2020 ANSSI 7 + * Copyright © 2024-2025 Microsoft Corporation 7 8 */ 8 9 10 + #include <linux/binfmts.h> 9 11 #include <linux/cred.h> 10 12 #include <linux/lsm_hooks.h> 11 13 ··· 19 17 static void hook_cred_transfer(struct cred *const new, 20 18 const struct cred *const old) 21 19 { 22 - struct landlock_ruleset *const old_dom = landlock_cred(old)->domain; 20 + const struct landlock_cred_security *const old_llcred = 21 + landlock_cred(old); 23 22 24 - if (old_dom) { 25 - landlock_get_ruleset(old_dom); 26 - landlock_cred(new)->domain = old_dom; 23 + if (old_llcred->domain) { 24 + landlock_get_ruleset(old_llcred->domain); 25 + *landlock_cred(new) = *old_llcred; 27 26 } 28 27 } 29 28 ··· 43 40 landlock_put_ruleset_deferred(dom); 44 41 } 45 42 43 + #ifdef CONFIG_AUDIT 44 + 45 + static int hook_bprm_creds_for_exec(struct linux_binprm *const bprm) 46 + { 47 + /* Resets for each execution. */ 48 + landlock_cred(bprm->cred)->domain_exec = 0; 49 + return 0; 50 + } 51 + 52 + #endif /* CONFIG_AUDIT */ 53 + 46 54 static struct security_hook_list landlock_hooks[] __ro_after_init = { 47 55 LSM_HOOK_INIT(cred_prepare, hook_cred_prepare), 48 56 LSM_HOOK_INIT(cred_transfer, hook_cred_transfer), 49 57 LSM_HOOK_INIT(cred_free, hook_cred_free), 58 + 59 + #ifdef CONFIG_AUDIT 60 + LSM_HOOK_INIT(bprm_creds_for_exec, hook_bprm_creds_for_exec), 61 + #endif /* CONFIG_AUDIT */ 50 62 }; 51 63 52 64 __init void landlock_add_cred_hooks(void)
+31 -1
security/landlock/cred.h
··· 10 10 #ifndef _SECURITY_LANDLOCK_CRED_H 11 11 #define _SECURITY_LANDLOCK_CRED_H 12 12 13 + #include <linux/container_of.h> 13 14 #include <linux/cred.h> 14 15 #include <linux/init.h> 15 16 #include <linux/rcupdate.h> 16 17 17 18 #include "access.h" 19 + #include "limits.h" 18 20 #include "ruleset.h" 19 21 #include "setup.h" 20 22 23 + /** 24 + * struct landlock_cred_security - Credential security blob 25 + * 26 + * This structure is packed to minimize the size of struct 27 + * landlock_file_security. However, it is always aligned in the LSM cred blob, 28 + * see lsm_set_blob_size(). 29 + */ 21 30 struct landlock_cred_security { 31 + /** 32 + * @domain: Immutable ruleset enforced on a task. 33 + */ 22 34 struct landlock_ruleset *domain; 23 - }; 35 + 36 + #ifdef CONFIG_AUDIT 37 + /** 38 + * @domain_exec: Bitmask identifying the domain layers that were enforced by 39 + * the current task's executed file (i.e. no new execve(2) since 40 + * landlock_restrict_self(2)). 41 + */ 42 + u16 domain_exec; 43 + #endif /* CONFIG_AUDIT */ 44 + } __packed; 45 + 46 + #ifdef CONFIG_AUDIT 47 + 48 + /* Makes sure all layer executions can be stored. */ 49 + static_assert(BITS_PER_TYPE(typeof_member(struct landlock_cred_security, 50 + domain_exec)) >= 51 + LANDLOCK_MAX_NUM_LAYERS); 52 + 53 + #endif /* CONFIG_AUDIT */ 24 54 25 55 static inline struct landlock_cred_security * 26 56 landlock_cred(const struct cred *cred)
+5
security/landlock/syscalls.c
··· 510 510 /* Replaces the old (prepared) domain. */ 511 511 landlock_put_ruleset(new_llcred->domain); 512 512 new_llcred->domain = new_dom; 513 + 514 + #ifdef CONFIG_AUDIT 515 + new_llcred->domain_exec |= 1 << (new_dom->num_layers - 1); 516 + #endif /* CONFIG_AUDIT */ 517 + 513 518 return commit_creds(new_cred); 514 519 }