Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6
Browse files Browse the repository at this point in the history
Pull CIFS updates from Steve French:
 "This patchset is the final section of the SMB2.1 support merge for
  cifs.ko.  It also includes improvements to the cifs socket handling
  from Jeff, and also fixes a few cifs bug fixes.  It adds SMB2 support
  for file and inode operations as well as moves some existing cifs code
  to use ops server struct of protocol specific callbacks.

  Most of this code is SMB2 specific.  When enabled SMB2.1 does pass
  various functional tests including most of the connectathon test
  suite, For SMB2.1, Connectathon test 4 and some related tests fail due
  to not updating mode bits remotely (cifsacl support where mode bits
  are approximated with the cifs acl is not enable for smb2), and test8
  (symlink) support is not completed for SMB2 yet (note that we will
  likely have a "Unix Extensions" eventually, at least for Samba, so in
  the long run posix locks won't have to be emulated when mounting Linux
  to Linux, but for most NAS and for Windows mounts posix lock emulation
  will still used for SMB2 in a similar fashion as we do for cifs).

  SMB2.1 dialect is supported.  Although additional fixes to enable smb2
  (the original smb2.02) dialect and to add various optional features of
  the smb3 dialect are expected to be added in the future as testing
  progresses, currently mounting with the "vers=2.1" is supported (in
  order to mount using SMB2.1 to servers like Samba 4, and Windows 7,
  Windows 2008R2)."

* 'for-linus' of git://git.samba.org/sfrench/cifs-2.6: (82 commits)
  [CIFS] Fix indentation of fs/cifs/Kconfig entries
  [CIFS] Fix SMB2 negotiation support to select only one dialect (based on vers=)
  cifs: obtain file access during backup intent lookup (resend)
  CIFS: Fix possible freed pointer dereference in CIFS_SessSetup
  CIFS: Fix possible freed pointer dereference in SMB2_sess_setup
  CIFS: Make ops->close return void
  cifs: change DOS/NT/POSIX mapping of ERRnoresource
  cifs: remove support for deprecated "forcedirectio" and "strictcache" mount options
  cifs: remove support for CIFS_IOC_CHECKUMOUNT ioctl
  CIFS: Fix possible memory leaks in SMB2 code
  CIFS: Fix endian conversion of IndexNumber
  Trivial endian fixes
  MARK SMB2 support EXPERIMENTAL
  Update cifs version number
  cifs: add FL_CLOSE to fl_flags mask in cifs_read_flock
  cifs: Mangle string used for unc in /proc/mounts
  cifs: cleanups for cifs_mkdir_qinfo
  CIFS: Fix fast lease break after open problem
  CIFS: Add SMB2.1 lease break support
  CIFS: Fix cache coherency for read oplock case
  ...
  • Loading branch information
Linus Torvalds committed Oct 1, 2012
2 parents 9c0ece0 + 1d4ab90 commit 797b9e5
Show file tree
Hide file tree
Showing 32 changed files with 4,884 additions and 1,547 deletions.
38 changes: 20 additions & 18 deletions fs/cifs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ config CIFS
select CRYPTO_ARC4
select CRYPTO_ECB
select CRYPTO_DES
select CRYPTO_SHA256
help
This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block
(SMB) protocol, the native file sharing mechanism for most early
PC operating systems. The CIFS protocol is fully supported by
file servers such as Windows 2000 (including Windows 2003, NT 4
and Windows XP) as well by Samba (which provides excellent CIFS
file servers such as Windows 2000 (including Windows 2003, Windows 2008,
NT 4 and Windows XP) as well by Samba (which provides excellent CIFS
server support for Linux and many other operating systems). Limited
support for OS/2 and Windows ME and similar servers is provided as
well.
Expand Down Expand Up @@ -114,6 +115,13 @@ config CIFS_POSIX
(such as Samba 3.10 and later) which can negotiate
CIFS POSIX ACL support. If unsure, say N.

config CIFS_ACL
bool "Provide CIFS ACL support"
depends on CIFS_XATTR && KEYS
help
Allows fetching CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.

config CIFS_DEBUG2
bool "Enable additional CIFS debugging routines"
depends on CIFS
Expand All @@ -138,21 +146,6 @@ config CIFS_DFS_UPCALL
IP addresses) which is needed for implicit mounts of DFS junction
points. If unsure, say N.

config CIFS_FSCACHE
bool "Provide CIFS client caching support"
depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
help
Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
to be cached locally on disk through the general filesystem cache
manager. If unsure, say N.

config CIFS_ACL
bool "Provide CIFS ACL support"
depends on CIFS_XATTR && KEYS
help
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.

config CIFS_NFSD_EXPORT
bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL && BROKEN
Expand All @@ -161,7 +154,7 @@ config CIFS_NFSD_EXPORT

config CIFS_SMB2
bool "SMB2 network file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL && INET && BROKEN
depends on CIFS && EXPERIMENTAL && INET
select NLS
select KEYS
select FSCACHE
Expand All @@ -178,3 +171,12 @@ config CIFS_SMB2
(compared to cifs) due to protocol improvements.

Unless you are a developer or tester, say N.

config CIFS_FSCACHE
bool "Provide CIFS client caching support"
depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
help
Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
to be cached locally on disk through the general filesystem cache
manager. If unsure, say N.

2 changes: 1 addition & 1 deletion fs/cifs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o

cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o smb2maperror.o smb2transport.o \
smb2misc.o smb2pdu.o smb2inode.o
smb2misc.o smb2pdu.o smb2inode.o smb2file.o
2 changes: 1 addition & 1 deletion fs/cifs/cifsacl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
if (!open_file)
return get_cifs_acl_by_path(cifs_sb, path, pacllen);

pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
cifsFileInfo_put(open_file);
return pntsd;
}
Expand Down
67 changes: 58 additions & 9 deletions fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ntlmssp.h"
#include <linux/ctype.h>
#include <linux/random.h>
#include <linux/highmem.h>

/*
* Calculate and return the CIFS signature based on the mac key and SMB PDU.
Expand All @@ -37,11 +38,13 @@
* the sequence number before this function is called. Also, this function
* should be called with the server->srv_mutex held.
*/
static int cifs_calc_signature(const struct kvec *iov, int n_vec,
static int cifs_calc_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server, char *signature)
{
int i;
int rc;
struct kvec *iov = rqst->rq_iov;
int n_vec = rqst->rq_nvec;

if (iov == NULL || signature == NULL || server == NULL)
return -EINVAL;
Expand Down Expand Up @@ -91,6 +94,16 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
}
}

/* now hash over the rq_pages array */
for (i = 0; i < rqst->rq_npages; i++) {
struct kvec p_iov;

cifs_rqst_page_to_kvec(rqst, i, &p_iov);
crypto_shash_update(&server->secmech.sdescmd5->shash,
p_iov.iov_base, p_iov.iov_len);
kunmap(rqst->rq_pages[i]);
}

rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
if (rc)
cERROR(1, "%s: Could not generate md5 hash", __func__);
Expand All @@ -99,12 +112,12 @@ static int cifs_calc_signature(const struct kvec *iov, int n_vec,
}

/* must be called with server->srv_mutex held */
int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number)
{
int rc = 0;
char smb_signature[20];
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;

if ((cifs_pdu == NULL) || (server == NULL))
return -EINVAL;
Expand All @@ -125,7 +138,7 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
*pexpected_response_sequence_number = server->sequence_number++;
server->sequence_number++;

rc = cifs_calc_signature(iov, n_vec, server, smb_signature);
rc = cifs_calc_signature(rqst, server, smb_signature);
if (rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
else
Expand All @@ -134,6 +147,15 @@ int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
return rc;
}

int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence)
{
struct smb_rqst rqst = { .rq_iov = iov,
.rq_nvec = n_vec };

return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
}

/* must be called with server->srv_mutex held */
int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
__u32 *pexpected_response_sequence_number)
Expand All @@ -147,14 +169,14 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
pexpected_response_sequence_number);
}

int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
int cifs_verify_signature(struct smb_rqst *rqst,
struct TCP_Server_Info *server,
__u32 expected_sequence_number)
{
unsigned int rc;
char server_response_sig[8];
char what_we_think_sig_should_be[20];
struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;

if (cifs_pdu == NULL || server == NULL)
return -EINVAL;
Expand Down Expand Up @@ -186,8 +208,7 @@ int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
cifs_pdu->Signature.Sequence.Reserved = 0;

mutex_lock(&server->srv_mutex);
rc = cifs_calc_signature(iov, nr_iov, server,
what_we_think_sig_should_be);
rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
mutex_unlock(&server->srv_mutex);

if (rc)
Expand Down Expand Up @@ -686,12 +707,17 @@ calc_seckey(struct cifs_ses *ses)
void
cifs_crypto_shash_release(struct TCP_Server_Info *server)
{
if (server->secmech.hmacsha256)
crypto_free_shash(server->secmech.hmacsha256);

if (server->secmech.md5)
crypto_free_shash(server->secmech.md5);

if (server->secmech.hmacmd5)
crypto_free_shash(server->secmech.hmacmd5);

kfree(server->secmech.sdeschmacsha256);

kfree(server->secmech.sdeschmacmd5);

kfree(server->secmech.sdescmd5);
Expand All @@ -716,6 +742,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
goto crypto_allocate_md5_fail;
}

server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0);
if (IS_ERR(server->secmech.hmacsha256)) {
cERROR(1, "could not allocate crypto hmacsha256\n");
rc = PTR_ERR(server->secmech.hmacsha256);
goto crypto_allocate_hmacsha256_fail;
}

size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.hmacmd5);
server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
Expand All @@ -727,7 +760,6 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
server->secmech.sdeschmacmd5->shash.flags = 0x0;


size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.md5);
server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
Expand All @@ -739,12 +771,29 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
server->secmech.sdescmd5->shash.flags = 0x0;

size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.hmacsha256);
server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL);
if (!server->secmech.sdeschmacsha256) {
cERROR(1, "%s: Can't alloc hmacsha256\n", __func__);
rc = -ENOMEM;
goto crypto_allocate_hmacsha256_sdesc_fail;
}
server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256;
server->secmech.sdeschmacsha256->shash.flags = 0x0;

return 0;

crypto_allocate_hmacsha256_sdesc_fail:
kfree(server->secmech.sdescmd5);

crypto_allocate_md5_sdesc_fail:
kfree(server->secmech.sdeschmacmd5);

crypto_allocate_hmacmd5_sdesc_fail:
crypto_free_shash(server->secmech.hmacsha256);

crypto_allocate_hmacsha256_fail:
crypto_free_shash(server->secmech.md5);

crypto_allocate_md5_fail:
Expand Down
Loading

0 comments on commit 797b9e5

Please sign in to comment.