From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754518Ab0CHRpA (ORCPT ); Mon, 8 Mar 2010 12:45:00 -0500 Received: from charlotte.tuxdriver.com ([70.61.120.58]:57895 "EHLO smtp.tuxdriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751642Ab0CHRoz (ORCPT ); Mon, 8 Mar 2010 12:44:55 -0500 Date: Mon, 8 Mar 2010 12:44:25 -0500 From: Neil Horman To: Oleg Nesterov Cc: Andrew Morton , Andi Kleen , linux-kernel@vger.kernel.org, David Howells Subject: Re: [PATCH,RESEND -mm 1/2] umh && creds: convert call_usermodehelper_keys() to use subprocess_info->init() Message-ID: <20100308174425.GA23634@hmsreliant.think-freely.org> References: <20100226200357.GB16092@redhat.com> <20100226182325.GA31674@redhat.com> <20100225181500.GA18008@redhat.com> <16951.1267207238@redhat.com> <17603.1267209668@redhat.com> <20100226200313.GA16092@redhat.com> <23363.1267216958@redhat.com> <29907.1267226649@redhat.com> <20100305225243.GA21790@redhat.com> <20100305230957.GA22614@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20100305230957.GA22614@redhat.com> User-Agent: Mutt/1.5.20 (2009-08-17) X-Spam-Score: -4.1 (----) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Mar 06, 2010 at 12:09:57AM +0100, Oleg Nesterov wrote: > (on top of kmod-replace-call_usermodehelper_pipe-with-use-of-umh-init-function-and-resolve-limit.patch) > > call_usermodehelper_keys() uses call_usermodehelper_setkeys() to change > subprocess_info->cred in advance. Now that we have info->init() we can > change this code to set tgcred->session_keyring in context of execing > kernel thread. > > Note: since currently call_usermodehelper_keys() is never called with > UMH_NO_WAIT, call_usermodehelper_keys()->key_get() and umh_keys_cleanup() > are not really needed, we could rely on install_session_keyring_to_cred() > which does key_get() on success. > > Signed-off-by: Oleg Nesterov > Acked-by: Neil Horman > --- > Acked-by: Neil Horman > include/linux/kmod.h | 17 ----------------- > kernel/kmod.c | 18 ------------------ > security/keys/internal.h | 1 + > security/keys/process_keys.c | 3 +-- > security/keys/request_key.c | 32 ++++++++++++++++++++++++++++++++ > 5 files changed, 34 insertions(+), 37 deletions(-) > > --- mm/include/linux/kmod.h~1_CONVERT_KEYS 2010-02-25 17:37:41.000000000 +0100 > +++ mm/include/linux/kmod.h 2010-02-26 21:45:28.000000000 +0100 > @@ -71,8 +71,6 @@ struct subprocess_info *call_usermodehel > char **envp, gfp_t gfp_mask); > > /* Set various pieces of state into the subprocess_info structure */ > -void call_usermodehelper_setkeys(struct subprocess_info *info, > - struct key *session_keyring); > void call_usermodehelper_setfns(struct subprocess_info *info, > int (*init)(struct subprocess_info *info), > void (*cleanup)(struct subprocess_info *info), > @@ -108,21 +106,6 @@ call_usermodehelper(char *path, char **a > wait, NULL, NULL, NULL); > } > > -static inline int > -call_usermodehelper_keys(char *path, char **argv, char **envp, > - struct key *session_keyring, enum umh_wait wait) > -{ > - struct subprocess_info *info; > - gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; > - > - info = call_usermodehelper_setup(path, argv, envp, gfp_mask); > - if (info == NULL) > - return -ENOMEM; > - > - call_usermodehelper_setkeys(info, session_keyring); > - return call_usermodehelper_exec(info, wait); > -} > - > extern void usermodehelper_init(void); > > extern int usermodehelper_disable(void); > --- mm/kernel/kmod.c~1_CONVERT_KEYS 2010-02-25 17:37:41.000000000 +0100 > +++ mm/kernel/kmod.c 2010-02-26 21:45:28.000000000 +0100 > @@ -386,24 +386,6 @@ struct subprocess_info *call_usermodehel > EXPORT_SYMBOL(call_usermodehelper_setup); > > /** > - * call_usermodehelper_setkeys - set the session keys for usermode helper > - * @info: a subprocess_info returned by call_usermodehelper_setup > - * @session_keyring: the session keyring for the process > - */ > -void call_usermodehelper_setkeys(struct subprocess_info *info, > - struct key *session_keyring) > -{ > -#ifdef CONFIG_KEYS > - struct thread_group_cred *tgcred = info->cred->tgcred; > - key_put(tgcred->session_keyring); > - tgcred->session_keyring = key_get(session_keyring); > -#else > - BUG(); > -#endif > -} > -EXPORT_SYMBOL(call_usermodehelper_setkeys); > - > -/** > * call_usermodehelper_setfns - set a cleanup/init function > * @info: a subprocess_info returned by call_usermodehelper_setup > * @cleanup: a cleanup function > --- mm/security/keys/internal.h~1_CONVERT_KEYS 2010-02-25 15:22:14.000000000 +0100 > +++ mm/security/keys/internal.h 2010-02-26 20:30:52.000000000 +0100 > @@ -115,6 +115,7 @@ extern struct key *find_keyring_by_name( > extern int install_user_keyrings(void); > extern int install_thread_keyring_to_cred(struct cred *); > extern int install_process_keyring_to_cred(struct cred *); > +extern int install_session_keyring_to_cred(struct cred *, struct key *); > > extern struct key *request_key_and_link(struct key_type *type, > const char *description, > --- mm/security/keys/process_keys.c~1_CONVERT_KEYS 2010-02-25 15:22:14.000000000 +0100 > +++ mm/security/keys/process_keys.c 2010-02-26 20:22:14.000000000 +0100 > @@ -217,8 +217,7 @@ static int install_process_keyring(void) > /* > * install a session keyring directly to a credentials struct > */ > -static int install_session_keyring_to_cred(struct cred *cred, > - struct key *keyring) > +int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) > { > unsigned long flags; > struct key *old; > --- mm/security/keys/request_key.c~1_CONVERT_KEYS 2010-02-25 17:37:41.000000000 +0100 > +++ mm/security/keys/request_key.c 2010-02-26 21:46:23.000000000 +0100 > @@ -58,6 +58,38 @@ void complete_request_key(struct key_con > } > EXPORT_SYMBOL(complete_request_key); > > +static int umh_keys_init(struct subprocess_info *info) > +{ > + struct cred *cred = (struct cred*)current_cred(); > + struct key *keyring = info->data; > + /* > + * This is called in context of freshly forked kthread before > + * kernel_execve(), we can just change our ->session_keyring. > + */ > + return install_session_keyring_to_cred(cred, keyring); > +} > + > +static void umh_keys_cleanup(struct subprocess_info *info) > +{ > + struct key *keyring = info->data; > + key_put(keyring); > +} > + > +static int call_usermodehelper_keys(char *path, char **argv, char **envp, > + struct key *session_keyring, enum umh_wait wait) > +{ > + gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; > + struct subprocess_info *info = > + call_usermodehelper_setup(path, argv, envp, gfp_mask); > + > + if (!info) > + return -ENOMEM; > + > + call_usermodehelper_setfns(info, umh_keys_init, umh_keys_cleanup, > + key_get(session_keyring)); > + return call_usermodehelper_exec(info, wait); > +} > + > /* > * request userspace finish the construction of a key > * - execute "/sbin/request-key " > >