aboutsummaryrefslogtreecommitdiff
path: root/drivers/base/firmware_loader/main.c
diff options
context:
space:
mode:
authorKees Cook <[email protected]>2022-10-26 16:31:11 -0700
committerKees Cook <[email protected]>2022-11-01 10:04:52 -0700
commit5a17f040fa332e71a45ca9ff02d6979d9176a423 (patch)
tree976a0250731074e8689c74665873f3b77f0b60c6 /drivers/base/firmware_loader/main.c
parente9a40e1585d792751d3a122392695e5a53032809 (diff)
cred: Do not default to init_cred in prepare_kernel_cred()
A common exploit pattern for ROP attacks is to abuse prepare_kernel_cred() in order to construct escalated privileges[1]. Instead of providing a short-hand argument (NULL) to the "daemon" argument to indicate using init_cred as the base cred, require that "daemon" is always set to an actual task. Replace all existing callers that were passing NULL with &init_task. Future attacks will need to have sufficiently powerful read/write primitives to have found an appropriately privileged task and written it to the ROP stack as an argument to succeed, which is similarly difficult to the prior effort needed to escalate privileges before struct cred existed: locate the current cred and overwrite the uid member. This has the added benefit of meaning that prepare_kernel_cred() can no longer exceed the privileges of the init task, which may have changed from the original init_cred (e.g. dropping capabilities from the bounding set). [1] https://google.com/search?q=commit_creds(prepare_kernel_cred(0)) Cc: "Eric W. Biederman" <[email protected]> Cc: David Howells <[email protected]> Cc: "Rafael J. Wysocki" <[email protected]> Cc: Steve French <[email protected]> Cc: Ronnie Sahlberg <[email protected]> Cc: Shyam Prasad N <[email protected]> Cc: Tom Talpey <[email protected]> Cc: Namjae Jeon <[email protected]> Cc: Trond Myklebust <[email protected]> Cc: Anna Schumaker <[email protected]> Cc: Chuck Lever <[email protected]> Cc: Jeff Layton <[email protected]> Cc: "David S. Miller" <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Jakub Kicinski <[email protected]> Cc: Paolo Abeni <[email protected]> Cc: "Michal Koutný" <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Kees Cook <[email protected]> Acked-by: Luis Chamberlain <[email protected]> Reviewed-by: Sergey Senozhatsky <[email protected]> Acked-by: Russ Weight <[email protected]> Acked-by: Greg Kroah-Hartman <[email protected]> Acked-by: Paulo Alcantara (SUSE) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/base/firmware_loader/main.c')
-rw-r--r--drivers/base/firmware_loader/main.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 7c3590fd97c2..017c4cdb219e 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -821,7 +821,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
* called by a driver when serving an unrelated request from userland, we use
* the kernel credentials to read the file.
*/
- kern_cred = prepare_kernel_cred(NULL);
+ kern_cred = prepare_kernel_cred(&init_task);
if (!kern_cred) {
ret = -ENOMEM;
goto out;