Merged into cifs-2.6.git On Tue, May 17, 2016 at 10:35 AM, Sachin Prabhu <sprabhu@xxxxxxxxxx> wrote: > On Sat, 2016-04-23 at 17:58 -0500, Shirish Pargaonkar wrote: >> Looks correct. May be init functions for idmap and spnego could be >> merged.. > > Thanks Sirish, > > They have #ifdef..#endif set for different config options so I thought > it is better that they are initialised separately. > > Sachin Prabhu > >> >> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> >> >> On Fri, Apr 22, 2016 at 2:58 PM, Sachin Prabhu <sprabhu@xxxxxxxxxx> >> wrote: >> > >> > The session key is the default keyring set for request_key >> > operations. >> > This session key is revoked when the user owning the session logs >> > out. >> > Any long running daemon processes started by this session ends up >> > with >> > revoked session keyring which prevents these processes from using >> > the >> > request_key mechanism from obtaining the krb5 keys. >> > >> > The problem has been reported by a large number of autofs users. >> > The >> > problem is also seen with multiuser mounts where the share may be >> > used >> > by processes run by a user who has since logged out. A reproducer >> > using >> > automount is available on the Red Hat bz. >> > >> > The patch creates a new keyring which is used to cache cifs spnego >> > upcalls. >> > >> > Red Hat bz: 1267754 >> > >> > Signed-off-by: Sachin Prabhu <sprabhu@xxxxxxxxxx> >> > Reported-by: Scott Mayhew <smayhew@xxxxxxxxxx> >> > --- >> > fs/cifs/cifs_spnego.c | 67 >> > +++++++++++++++++++++++++++++++++++++++++++++++++++ >> > fs/cifs/cifsfs.c | 4 +-- >> > fs/cifs/cifsproto.h | 2 ++ >> > 3 files changed, 71 insertions(+), 2 deletions(-) >> > >> > diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c >> > index 6908080..248ab43 100644 >> > --- a/fs/cifs/cifs_spnego.c >> > +++ b/fs/cifs/cifs_spnego.c >> > @@ -24,11 +24,14 @@ >> > #include <linux/string.h> >> > #include <keys/user-type.h> >> > #include <linux/key-type.h> >> > +#include <linux/keyctl.h> >> > #include <linux/inet.h> >> > #include "cifsglob.h" >> > #include "cifs_spnego.h" >> > #include "cifs_debug.h" >> > >> > +static const struct cred *spnego_cred; >> > + >> > /* create a new cifs key */ >> > static int >> > cifs_spnego_key_instantiate(struct key *key, struct >> > key_preparsed_payload *prep) >> > @@ -102,6 +105,7 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo) >> > size_t desc_len; >> > struct key *spnego_key; >> > const char *hostname = server->hostname; >> > + const struct cred *saved_cred; >> > >> > /* length of fields (with semicolons): ver=0xyz >> > ip4=ipaddress >> > host=hostname sec=mechanism uid=0xFF user=username */ >> > @@ -163,7 +167,9 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo) >> > sprintf(dp, ";pid=0x%x", current->pid); >> > >> > cifs_dbg(FYI, "key description = %s\n", description); >> > + saved_cred = override_creds(spnego_cred); >> > spnego_key = request_key(&cifs_spnego_key_type, >> > description, ""); >> > + revert_creds(saved_cred); >> > >> > #ifdef CONFIG_CIFS_DEBUG2 >> > if (cifsFYI && !IS_ERR(spnego_key)) { >> > @@ -177,3 +183,64 @@ out: >> > kfree(description); >> > return spnego_key; >> > } >> > + >> > +int >> > +init_cifs_spnego(void) >> > +{ >> > + struct cred *cred; >> > + struct key *keyring; >> > + int ret; >> > + >> > + cifs_dbg(FYI, "Registering the %s key type\n", >> > + cifs_spnego_key_type.name); >> > + >> > + /* >> > + * Create an override credential set with special thread >> > keyring for >> > + * spnego upcalls. >> > + */ >> > + >> > + cred = prepare_kernel_cred(NULL); >> > + if (!cred) >> > + return -ENOMEM; >> > + >> > + keyring = keyring_alloc(".cifs_spnego", >> > + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, >> > cred, >> > + (KEY_POS_ALL & ~KEY_POS_SETATTR) | >> > + KEY_USR_VIEW | KEY_USR_READ, >> > + KEY_ALLOC_NOT_IN_QUOTA, NULL); >> > + if (IS_ERR(keyring)) { >> > + ret = PTR_ERR(keyring); >> > + goto failed_put_cred; >> > + } >> > + >> > + ret = register_key_type(&cifs_spnego_key_type); >> > + if (ret < 0) >> > + goto failed_put_key; >> > + >> > + /* >> > + * instruct request_key() to use this special keyring as a >> > cache for >> > + * the results it looks up >> > + */ >> > + set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); >> > + cred->thread_keyring = keyring; >> > + cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; >> > + spnego_cred = cred; >> > + >> > + cifs_dbg(FYI, "cifs spnego keyring: %d\n", >> > key_serial(keyring)); >> > + return 0; >> > + >> > +failed_put_key: >> > + key_put(keyring); >> > +failed_put_cred: >> > + put_cred(cred); >> > + return ret; >> > +} >> > + >> > +void >> > +exit_cifs_spnego(void) >> > +{ >> > + key_revoke(spnego_cred->thread_keyring); >> > + unregister_key_type(&cifs_spnego_key_type); >> > + put_cred(spnego_cred); >> > + cifs_dbg(FYI, "Unregistered %s key type\n", >> > cifs_spnego_key_type.name); >> > +} >> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c >> > index 8920156..9852044 100644 >> > --- a/fs/cifs/cifsfs.c >> > +++ b/fs/cifs/cifsfs.c >> > @@ -1307,7 +1307,7 @@ init_cifs(void) >> > goto out_destroy_mids; >> > >> > #ifdef CONFIG_CIFS_UPCALL >> > - rc = register_key_type(&cifs_spnego_key_type); >> > + rc = init_cifs_spnego(); >> > if (rc) >> > goto out_destroy_request_bufs; >> > #endif /* CONFIG_CIFS_UPCALL */ >> > @@ -1330,7 +1330,7 @@ out_init_cifs_idmap: >> > out_register_key_type: >> > #endif >> > #ifdef CONFIG_CIFS_UPCALL >> > - unregister_key_type(&cifs_spnego_key_type); >> > + exit_cifs_spnego(); >> > out_destroy_request_bufs: >> > #endif >> > cifs_destroy_request_bufs(); >> > diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >> > index eed7ff5..ca618b0 100644 >> > --- a/fs/cifs/cifsproto.h >> > +++ b/fs/cifs/cifsproto.h >> > @@ -60,6 +60,8 @@ do >> > { \ >> > } while (0) >> > extern int init_cifs_idmap(void); >> > extern void exit_cifs_idmap(void); >> > +extern int init_cifs_spnego(void); >> > +extern int exit_cifs_spnego(void); >> > extern char *build_path_from_dentry(struct dentry *); >> > extern char *cifs_build_path_to_root(struct smb_vol *vol, >> > struct cifs_sb_info *cifs_sb, >> > -- >> > 2.5.5 >> > >> > -- >> > To unsubscribe from this list: send the line "unsubscribe linux- >> > cifs" in >> > the body of a message to majordomo@xxxxxxxxxxxxxxx >> > More majordomo info at http://vger.kernel.org/majordomo-info.html >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-cifs" >> in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Thanks, Steve -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html