Skip to content

Commit 00c0e48

Browse files
thejhSasha Levin
authored and
Sasha Levin
committed
landlock: Don't lose track of restrictions on cred_transfer
commit 39705a6 upstream. When a process' cred struct is replaced, this _almost_ always invokes the cred_prepare LSM hook; but in one special case (when KEYCTL_SESSION_TO_PARENT updates the parent's credentials), the cred_transfer LSM hook is used instead. Landlock only implements the cred_prepare hook, not cred_transfer, so KEYCTL_SESSION_TO_PARENT causes all information on Landlock restrictions to be lost. This basically means that a process with the ability to use the fork() and keyctl() syscalls can get rid of all Landlock restrictions on itself. Fix it by adding a cred_transfer hook that does the same thing as the existing cred_prepare hook. (Implemented by having hook_cred_prepare() call hook_cred_transfer() so that the two functions are less likely to accidentally diverge in the future.) Cc: [email protected] Fixes: 385975d ("landlock: Set up the security framework and manage credentials") Signed-off-by: Jann Horn <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mickaël Salaün <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7936344 commit 00c0e48

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

security/landlock/cred.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,21 @@
1414
#include "ruleset.h"
1515
#include "setup.h"
1616

17-
static int hook_cred_prepare(struct cred *const new,
18-
const struct cred *const old, const gfp_t gfp)
17+
static void hook_cred_transfer(struct cred *const new,
18+
const struct cred *const old)
1919
{
2020
struct landlock_ruleset *const old_dom = landlock_cred(old)->domain;
2121

2222
if (old_dom) {
2323
landlock_get_ruleset(old_dom);
2424
landlock_cred(new)->domain = old_dom;
2525
}
26+
}
27+
28+
static int hook_cred_prepare(struct cred *const new,
29+
const struct cred *const old, const gfp_t gfp)
30+
{
31+
hook_cred_transfer(new, old);
2632
return 0;
2733
}
2834

@@ -36,6 +42,7 @@ static void hook_cred_free(struct cred *const cred)
3642

3743
static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
3844
LSM_HOOK_INIT(cred_prepare, hook_cred_prepare),
45+
LSM_HOOK_INIT(cred_transfer, hook_cred_transfer),
3946
LSM_HOOK_INIT(cred_free, hook_cred_free),
4047
};
4148

0 commit comments

Comments
 (0)