Skip to content

Commit 7730d7a

Browse files
thejhsmb49
authored andcommitted
landlock: Don't lose track of restrictions on cred_transfer
BugLink: https://bugs.launchpad.net/bugs/2078428 commit 39705a6c29f8a2b93cf5b99528a55366c50014d1 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: stable@kernel.org Fixes: 385975d ("landlock: Set up the security framework and manage credentials") Signed-off-by: Jann Horn <jannh@google.com> Link: https://lore.kernel.org/r/20240724-landlock-houdini-fix-v1-1-df89a4560ca3@google.com Signed-off-by: Mickaël Salaün <mic@digikod.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent 2051d09 commit 7730d7a

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

security/landlock/cred.c

Lines changed: 9 additions & 2 deletions
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)