|
23 | 23 | * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
24 | 24 | * Copyright 2013, Joyent, Inc. All rights reserved. |
25 | 25 | * Copyright (C) 2016 Lawrence Livermore National Security, LLC. |
| 26 | + * Copyright (c) 2025, Rob Norris <[email protected]> |
26 | 27 | * |
27 | 28 | * For Linux the vast majority of this enforcement is already handled via |
28 | 29 | * the standard Linux VFS permission checks. However certain administrative |
|
34 | 35 | #include <linux/security.h> |
35 | 36 | #include <linux/vfs_compat.h> |
36 | 37 |
|
37 | | -/* |
38 | | - * The passed credentials cannot be directly verified because Linux only |
39 | | - * provides and interface to check the *current* process credentials. In |
40 | | - * order to handle this the capable() test is only run when the passed |
41 | | - * credentials match the current process credentials or the kcred. In |
42 | | - * all other cases this function must fail and return the passed err. |
43 | | - */ |
44 | 38 | static int |
45 | 39 | priv_policy_ns(const cred_t *cr, int capability, int err, |
46 | 40 | struct user_namespace *ns) |
47 | 41 | { |
48 | | - if (cr != CRED() && (cr != kcred)) |
49 | | - return (err); |
| 42 | + /* |
| 43 | + * The passed credentials cannot be directly verified because Linux |
| 44 | + * only provides an interface to check the *current* process |
| 45 | + * credentials. In order to handle this we check if the passed in |
| 46 | + * creds match the current process credentials or the kcred. If not, |
| 47 | + * we swap the passed credentials into the current task, perform the |
| 48 | + * check, and then revert it before returning. |
| 49 | + */ |
| 50 | + const cred_t *old = |
| 51 | + (cr != CRED() && cr != kcred) ? override_creds(cr) : NULL; |
50 | 52 |
|
51 | 53 | #if defined(CONFIG_USER_NS) |
52 | | - if (!(ns ? ns_capable(ns, capability) : capable(capability))) |
| 54 | + if (ns ? ns_capable(ns, capability) : capable(capability)) |
53 | 55 | #else |
54 | | - if (!capable(capability)) |
| 56 | + if (capable(capability)) |
55 | 57 | #endif |
56 | | - return (err); |
| 58 | + err = 0; |
57 | 59 |
|
58 | | - return (0); |
| 60 | + if (old) |
| 61 | + revert_creds(old); |
| 62 | + |
| 63 | + return (err); |
59 | 64 | } |
60 | 65 |
|
61 | 66 | static int |
@@ -248,19 +253,6 @@ secpolicy_zfs(const cred_t *cr) |
248 | 253 | return (priv_policy(cr, CAP_SYS_ADMIN, EACCES)); |
249 | 254 | } |
250 | 255 |
|
251 | | -/* |
252 | | - * Equivalent to secpolicy_zfs(), but works even if the cred_t is not that of |
253 | | - * the current process. Takes both cred_t and proc_t so that this can work |
254 | | - * easily on all platforms. |
255 | | - */ |
256 | | -int |
257 | | -secpolicy_zfs_proc(const cred_t *cr, proc_t *proc) |
258 | | -{ |
259 | | - if (!has_capability(proc, CAP_SYS_ADMIN)) |
260 | | - return (EACCES); |
261 | | - return (0); |
262 | | -} |
263 | | - |
264 | 256 | void |
265 | 257 | secpolicy_setid_clear(vattr_t *vap, cred_t *cr) |
266 | 258 | { |
|
0 commit comments