Message ID | 061dd6fe81dc97a4375e52ec0da20a54cf582cb5.1657624639.git.bcodding@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Keyagents: another call_usermodehelper approach for namespaces | expand |
Hi Benjamin, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on jmorris-security/next-testing] [also build test WARNING on dhowells-fs/fscache-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 base: https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next-testing config: hexagon-randconfig-r005-20220714 (https://download.01.org/0day-ci/archive/20220715/202207150537.QnoEUasf-lkp@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 5e61b9c556267086ef9b743a0b57df302eef831b) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/4d4f4ae463335d3e611bdb71330ab37af115cde9 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 git checkout 4d4f4ae463335d3e611bdb71330ab37af115cde9 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash security/keys/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> security/keys/request_key.c:254:1: warning: unused label 'done' [-Wunused-label] done: ^~~~~ 1 warning generated. vim +/done +254 security/keys/request_key.c 217 218 /* 219 * Call out to userspace for key construction. 220 * 221 * Program failure is ignored in favour of key status. 222 */ 223 static int construct_key(struct key *key, const void *callout_info, 224 size_t callout_len, void *aux, 225 struct key *dest_keyring) 226 { 227 request_key_actor_t actor; 228 struct key *authkey; 229 int ret; 230 231 kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); 232 233 /* allocate an authorisation key */ 234 authkey = request_key_auth_new(key, "create", callout_info, callout_len, 235 dest_keyring); 236 if (IS_ERR(authkey)) 237 return PTR_ERR(authkey); 238 239 /* Make the call */ 240 actor = call_sbin_request_key; 241 if (key->type->request_key) 242 actor = key->type->request_key; 243 #ifdef CONFIG_KEYAGENT 244 else { 245 ret = keyagent_request_key(authkey, aux); 246 247 /* ENOKEY: no keyagents match on calling process' keyrings */ 248 if (ret != -ENOKEY) 249 goto done; 250 } 251 #endif 252 ret = actor(authkey, aux); 253 > 254 done: 255 /* check that the actor called complete_request_key() prior to 256 * returning an error */ 257 WARN_ON(ret < 0 && 258 !test_bit(KEY_FLAG_INVALIDATED, &authkey->flags)); 259 260 key_put(authkey); 261 kleave(" = %d", ret); 262 return ret; 263 } 264
Hi Benjamin, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on jmorris-security/next-testing] [also build test WARNING on dhowells-fs/fscache-next arnd-asm-generic/master linus/master v5.19-rc6 next-20220714] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 base: https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next-testing config: i386-defconfig (https://download.01.org/0day-ci/archive/20220715/202207152343.9SGLm8sP-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4d4f4ae463335d3e611bdb71330ab37af115cde9 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 git checkout 4d4f4ae463335d3e611bdb71330ab37af115cde9 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash security/keys/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): security/keys/request_key.c: In function 'construct_key': >> security/keys/request_key.c:254:1: warning: label 'done' defined but not used [-Wunused-label] 254 | done: | ^~~~ vim +/done +254 security/keys/request_key.c 217 218 /* 219 * Call out to userspace for key construction. 220 * 221 * Program failure is ignored in favour of key status. 222 */ 223 static int construct_key(struct key *key, const void *callout_info, 224 size_t callout_len, void *aux, 225 struct key *dest_keyring) 226 { 227 request_key_actor_t actor; 228 struct key *authkey; 229 int ret; 230 231 kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux); 232 233 /* allocate an authorisation key */ 234 authkey = request_key_auth_new(key, "create", callout_info, callout_len, 235 dest_keyring); 236 if (IS_ERR(authkey)) 237 return PTR_ERR(authkey); 238 239 /* Make the call */ 240 actor = call_sbin_request_key; 241 if (key->type->request_key) 242 actor = key->type->request_key; 243 #ifdef CONFIG_KEYAGENT 244 else { 245 ret = keyagent_request_key(authkey, aux); 246 247 /* ENOKEY: no keyagents match on calling process' keyrings */ 248 if (ret != -ENOKEY) 249 goto done; 250 } 251 #endif 252 ret = actor(authkey, aux); 253 > 254 done: 255 /* check that the actor called complete_request_key() prior to 256 * returning an error */ 257 WARN_ON(ret < 0 && 258 !test_bit(KEY_FLAG_INVALIDATED, &authkey->flags)); 259 260 key_put(authkey); 261 kleave(" = %d", ret); 262 return ret; 263 } 264
Hi Benjamin, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on jmorris-security/next-testing] [also build test WARNING on dhowells-fs/fscache-next arnd-asm-generic/master linus/master v5.19-rc6 next-20220714] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 base: https://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next-testing config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20220715/202207152310.dTPT29kb-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/4d4f4ae463335d3e611bdb71330ab37af115cde9 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Benjamin-Coddington/Keyagents-another-call_usermodehelper-approach-for-namespaces/20220712-203658 git checkout 4d4f4ae463335d3e611bdb71330ab37af115cde9 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash security/keys/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): >> security/keys/keyagent.c:78:5: warning: no previous prototype for 'keyagent_request_key' [-Wmissing-prototypes] 78 | int keyagent_request_key(struct key *authkey, void *aux) | ^~~~~~~~~~~~~~~~~~~~ vim +/keyagent_request_key +78 security/keys/keyagent.c 72 73 /* 74 * Search the calling process' keyrings for a keyagent that 75 * matches the requested key type. If found, signal the keyagent 76 * to construct and link the key, else return -ENOKEY. 77 */ > 78 int keyagent_request_key(struct key *authkey, void *aux) 79 { 80 struct key *ka_key, *target_key; 81 struct request_key_auth *rka; 82 key_ref_t ka_ref; 83 const struct cred *cred = current_cred(); 84 int ret; 85 86 /* We must be careful not to touch authkey and aux if 87 * returning -ENOKEY, since it will be reused. */ 88 rka = get_request_key_auth(authkey); 89 target_key = rka->target_key; 90 91 /* Does the calling process have a keyagent in its session keyring? */ 92 ka_ref = keyring_search( 93 make_key_ref(cred->session_keyring, 1), 94 &key_type_keyagent, 95 target_key->type->name, false); 96 97 if (IS_ERR(ka_ref)) 98 return -ENOKEY; 99 100 /* We found a keyagent, let's call out to it. */ 101 ka_key = key_ref_to_ptr(ka_ref); 102 ret = keyagent_signal(ka_key, target_key, authkey); 103 key_put(key_ref_to_ptr(ka_ref)); 104 105 return ret; 106 } 107
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index ffbe4cec9f32..542e297f4466 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -185,6 +185,7 @@ typedef struct siginfo { #define SI_SIGIO -5 /* sent by queued SIGIO */ #define SI_TKILL -6 /* sent by tkill system call */ #define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */ +#define SI_KEYAGENT -8 /* sent by request-key */ #define SI_ASYNCNL -60 /* sent by glibc async name lookup completion */ #define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) diff --git a/security/keys/internal.h b/security/keys/internal.h index 9b9cf3b6fcbb..a6db6eecfff5 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -372,5 +372,9 @@ static inline void key_check(const struct key *key) #define key_check(key) do {} while(0) +#endif + +#ifdef CONFIG_KEYAGENT +extern int keyagent_request_key(struct key *authkey, void *aux); #endif #endif /* _INTERNAL_H */ diff --git a/security/keys/keyagent.c b/security/keys/keyagent.c index 87ebfe00c710..cf70146925f0 100644 --- a/security/keys/keyagent.c +++ b/security/keys/keyagent.c @@ -9,8 +9,11 @@ #include <linux/slab.h> #include <linux/key.h> #include <linux/key-type.h> +#include <linux/sched/signal.h> +#include <linux/sched/task.h> #include <keys/user-type.h> +#include <keys/request_key_auth-type.h> /* * Keyagent key payload. @@ -20,6 +23,88 @@ struct keyagent { int sig; }; +struct key_type key_type_keyagent; + +/* + * Given a key representing a keyagent and a target_key to construct, link + * the the authkey into the keyagent's process_keyring and signal the + * keyagent to construct the target_key. + */ +static int keyagent_signal(struct key *ka_key, struct key *target_key, + struct key *authkey) +{ + struct keyagent *ka = ka_key->payload.data[0]; + struct task_struct *task; + const struct cred *cred; + kernel_siginfo_t info = { + .si_code = SI_KEYAGENT, + .si_signo = ka->sig, + .si_int = target_key->serial, + }; + int ret = -ENOKEY; + + task = get_pid_task(ka->pid, PIDTYPE_PID); + /* If the task is gone, should we revoke the keyagent key? */ + if (!task) { + key_revoke(ka_key); + goto out; + } + + /* We're expecting valid keyagents to have a process keyring, + * if not, should we warn? */ + cred = get_cred(task->cred); + if (!cred->process_keyring) + goto out_nolink; + + /* Link the autkey to the keyagent's process_keyring */ + ret = key_link(cred->process_keyring, authkey); + if (ret < 0) + goto out_nolink; + + ret = send_sig_info(ka->sig, &info, task); + +out_nolink: + put_cred(cred); + put_task_struct(task); +out: + return ret; +} + +/* + * Search the calling process' keyrings for a keyagent that + * matches the requested key type. If found, signal the keyagent + * to construct and link the key, else return -ENOKEY. + */ +int keyagent_request_key(struct key *authkey, void *aux) +{ + struct key *ka_key, *target_key; + struct request_key_auth *rka; + key_ref_t ka_ref; + const struct cred *cred = current_cred(); + int ret; + + /* We must be careful not to touch authkey and aux if + * returning -ENOKEY, since it will be reused. */ + rka = get_request_key_auth(authkey); + target_key = rka->target_key; + + /* Does the calling process have a keyagent in its session keyring? */ + ka_ref = keyring_search( + make_key_ref(cred->session_keyring, 1), + &key_type_keyagent, + target_key->type->name, false); + + if (IS_ERR(ka_ref)) + return -ENOKEY; + + /* We found a keyagent, let's call out to it. */ + ka_key = key_ref_to_ptr(ka_ref); + ret = keyagent_signal(ka_key, target_key, authkey); + key_put(key_ref_to_ptr(ka_ref)); + + return ret; +} + /* * Instantiate takes a reference to the current task's struct pid * and the requested realtime signal number. diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 2da4404276f0..4c1f5ef55856 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -240,9 +240,18 @@ static int construct_key(struct key *key, const void *callout_info, actor = call_sbin_request_key; if (key->type->request_key) actor = key->type->request_key; +#ifdef CONFIG_KEYAGENT + else { + ret = keyagent_request_key(authkey, aux); + /* ENOKEY: no keyagents match on calling process' keyrings */ + if (ret != -ENOKEY) + goto done; + } +#endif ret = actor(authkey, aux); +done: /* check that the actor called complete_request_key() prior to * returning an error */ WARN_ON(ret < 0 &&
During key construction, search the calling process' session keyring for a keyagent key with a description that matches the requested key_type. If found, link the authkey into the keyagent's process_keyring, and signal the keyagent task with a realtime signal containing the serial number of the key that needs to be constructed. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> --- include/uapi/asm-generic/siginfo.h | 1 + security/keys/internal.h | 4 ++ security/keys/keyagent.c | 85 ++++++++++++++++++++++++++++++ security/keys/request_key.c | 9 ++++ 4 files changed, 99 insertions(+)