Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Two small cifs fixes, including one spnego upcall cifs security fix
  for stable"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
  CIFS: Remove some obsolete comments
  cifs: Create dedicated keyring for spnego operations
This commit is contained in:
Linus Torvalds 2016-05-20 19:16:12 -07:00
commit b99a9e8776
3 changed files with 72 additions and 8 deletions

View File

@ -24,10 +24,13 @@
#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"
#include "cifsproto.h"
static const struct cred *spnego_cred;
/* create a new cifs key */
static int
@ -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 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
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, 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);
}

View File

@ -890,7 +890,6 @@ const struct inode_operations cifs_dir_inode_ops = {
.rmdir = cifs_rmdir,
.rename2 = cifs_rename2,
.permission = cifs_permission,
/* revalidate:cifs_revalidate, */
.setattr = cifs_setattr,
.symlink = cifs_symlink,
.mknod = cifs_mknod,
@ -901,9 +900,8 @@ const struct inode_operations cifs_dir_inode_ops = {
};
const struct inode_operations cifs_file_inode_ops = {
/* revalidate:cifs_revalidate, */
.setattr = cifs_setattr,
.getattr = cifs_getattr, /* do we need this anymore? */
.getattr = cifs_getattr,
.permission = cifs_permission,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
@ -915,9 +913,6 @@ const struct inode_operations cifs_symlink_inode_ops = {
.readlink = generic_readlink,
.get_link = cifs_get_link,
.permission = cifs_permission,
/* BB add the following two eventually */
/* revalidate: cifs_revalidate,
setattr: cifs_notify_change, *//* BB do we need notify change */
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.listxattr = cifs_listxattr,
@ -1303,7 +1298,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 */
@ -1326,7 +1321,7 @@ init_cifs(void)
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();

View File

@ -58,6 +58,8 @@ do { \
} while (0)
extern int init_cifs_idmap(void);
extern void exit_cifs_idmap(void);
extern int init_cifs_spnego(void);
extern void 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,