Skip to content

Commit

Permalink
Merge tag '5.15-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/c…
Browse files Browse the repository at this point in the history
…ifs-2.6

Pull cifs client updates from Steve French:
 "Eleven cifs/smb3 client fixes:

   - mostly restructuring to allow disabling less secure algorithms
     (this will allow eventual removing rc4 and md4 from general use in
     the kernel)

   - four fixes, including two for stable

   - enable r/w support with fscache and cifs.ko

  I am working on a larger set of changes (the usual ... multichannel,
  auth and signing improvements), but wanted to get these in earlier to
  reduce chance of merge conflicts later in the merge window"

* tag '5.15-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Do not leak EDEADLK to dgetents64 for STATUS_USER_SESSION_DELETED
  cifs: add cifs_common directory to MAINTAINERS file
  cifs: cifs_md4 convert to SPDX identifier
  cifs: create a MD4 module and switch cifs.ko to use it
  cifs: fork arc4 and create a separate module for it for cifs and other users
  cifs: remove support for NTLM and weaker authentication algorithms
  cifs: enable fscache usage even for files opened as rw
  oid_registry: Add OIDs for missing Spnego auth mechanisms to Macs
  smb3: fix posix extensions mount option
  cifs: fix wrong release in sess_alloc_buffer() failed path
  CIFS: Fix a potencially linear read overflow
  • Loading branch information
torvalds committed Aug 31, 2021
2 parents e24c567 + 3998f0b commit 9c849ce
Show file tree
Hide file tree
Showing 30 changed files with 485 additions and 763 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4629,6 +4629,7 @@ W: http://linux-cifs.samba.org/
T: git git://git.samba.org/sfrench/cifs-2.6.git
F: Documentation/admin-guide/cifs/
F: fs/cifs/
F: fs/cifs_common/

COMPACTPCI HOTPLUG CORE
M: Scott Murray <[email protected]>
Expand Down
7 changes: 7 additions & 0 deletions fs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,15 @@ config NFS_V4_2_SSC_HELPER

source "net/sunrpc/Kconfig"
source "fs/ceph/Kconfig"

source "fs/cifs/Kconfig"
source "fs/ksmbd/Kconfig"

config CIFS_COMMON
tristate
default y if CIFS=y
default m if CIFS=m

source "fs/coda/Kconfig"
source "fs/afs/Kconfig"
source "fs/9p/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions fs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ obj-$(CONFIG_LOCKD) += lockd/
obj-$(CONFIG_NLS) += nls/
obj-$(CONFIG_UNICODE) += unicode/
obj-$(CONFIG_SYSV_FS) += sysv/
obj-$(CONFIG_CIFS_COMMON) += cifs_common/
obj-$(CONFIG_CIFS) += cifs/
obj-$(CONFIG_SMB_SERVER) += ksmbd/
obj-$(CONFIG_HPFS_FS) += hpfs/
Expand Down
30 changes: 0 additions & 30 deletions fs/cifs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ config CIFS
depends on INET
select NLS
select CRYPTO
select CRYPTO_MD4
select CRYPTO_MD5
select CRYPTO_SHA256
select CRYPTO_SHA512
select CRYPTO_CMAC
select CRYPTO_HMAC
select CRYPTO_LIB_ARC4
select CRYPTO_AEAD2
select CRYPTO_CCM
select CRYPTO_GCM
select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_LIB_DES
select KEYS
select DNS_RESOLVER
select ASN1
Expand Down Expand Up @@ -85,33 +82,6 @@ config CIFS_ALLOW_INSECURE_LEGACY

If unsure, say Y.

config CIFS_WEAK_PW_HASH
bool "Support legacy servers which use weaker LANMAN security"
depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY
help
Modern CIFS servers including Samba and most Windows versions
(since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
security mechanisms. These hash the password more securely
than the mechanisms used in the older LANMAN version of the
SMB protocol but LANMAN based authentication is needed to
establish sessions with some old SMB servers.

Enabling this option allows the cifs module to mount to older
LANMAN based servers such as OS/2 and Windows 95, but such
mounts may be less secure than mounts using NTLM or more recent
security mechanisms if you are on a public network. Unless you
have a need to access old SMB servers (and are on a private
network) you probably want to say N. Even if this support
is enabled in the kernel build, LANMAN authentication will not be
used automatically. At runtime LANMAN mounts are disabled but
can be set to required (or optional) either in
/proc/fs/cifs (see Documentation/admin-guide/cifs/usage.rst for
more detail) or via an option on the mount command. This support
is disabled by default in order to reduce the possibility of a
downgrade attack.

If unsure, say N.

config CIFS_UPCALL
bool "Kerberos/SPNEGO advanced session setup"
depends on CIFS
Expand Down
11 changes: 0 additions & 11 deletions fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
seq_printf(m, ",ALLOW_INSECURE_LEGACY");
#endif
#ifdef CONFIG_CIFS_WEAK_PW_HASH
seq_printf(m, ",WEAK_PW_HASH");
#endif
#ifdef CONFIG_CIFS_POSIX
seq_printf(m, ",CIFS_POSIX");
#endif
Expand Down Expand Up @@ -929,14 +926,6 @@ cifs_security_flags_handle_must_flags(unsigned int *flags)
*flags = CIFSSEC_MUST_NTLMSSP;
else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
*flags = CIFSSEC_MUST_NTLMV2;
else if ((*flags & CIFSSEC_MUST_NTLM) == CIFSSEC_MUST_NTLM)
*flags = CIFSSEC_MUST_NTLM;
else if (CIFSSEC_MUST_LANMAN &&
(*flags & CIFSSEC_MUST_LANMAN) == CIFSSEC_MUST_LANMAN)
*flags = CIFSSEC_MUST_LANMAN;
else if (CIFSSEC_MUST_PLNTXT &&
(*flags & CIFSSEC_MUST_PLNTXT) == CIFSSEC_MUST_PLNTXT)
*flags = CIFSSEC_MUST_PLNTXT;

*flags |= signflags;
}
Expand Down
2 changes: 0 additions & 2 deletions fs/cifs/cifs_swn.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ static int cifs_swn_send_register_message(struct cifs_swn_reg *swnreg)
goto nlmsg_fail;
}
break;
case LANMAN:
case NTLM:
case NTLMv2:
case RawNTLMSSP:
ret = cifs_swn_auth_info_ntlm(swnreg->tcon, skb);
Expand Down
9 changes: 2 additions & 7 deletions fs/cifs/cifs_unicode.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,14 +358,9 @@ cifs_strndup_from_utf16(const char *src, const int maxlen,
if (!dst)
return NULL;
cifs_from_utf16(dst, (__le16 *) src, len, maxlen, codepage,
NO_MAP_UNI_RSVD);
NO_MAP_UNI_RSVD);
} else {
len = strnlen(src, maxlen);
len++;
dst = kmalloc(len, GFP_KERNEL);
if (!dst)
return NULL;
strlcpy(dst, src, len);
dst = kstrndup(src, maxlen, GFP_KERNEL);
}

return dst;
Expand Down
89 changes: 4 additions & 85 deletions fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <linux/random.h>
#include <linux/highmem.h>
#include <linux/fips.h>
#include <crypto/arc4.h>
#include "../cifs_common/arc4.h"
#include <crypto/aead.h>

int __cifs_calc_signature(struct smb_rqst *rqst,
Expand Down Expand Up @@ -250,87 +250,6 @@ int cifs_verify_signature(struct smb_rqst *rqst,

}

/* first calculate 24 bytes ntlm response and then 16 byte session key */
int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
int rc = 0;
unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
char temp_key[CIFS_SESS_KEY_SIZE];

if (!ses)
return -EINVAL;

ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
if (!ses->auth_key.response)
return -ENOMEM;

ses->auth_key.len = temp_len;

rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
if (rc) {
cifs_dbg(FYI, "%s Can't generate NTLM response, error: %d\n",
__func__, rc);
return rc;
}

rc = E_md4hash(ses->password, temp_key, nls_cp);
if (rc) {
cifs_dbg(FYI, "%s Can't generate NT hash, error: %d\n",
__func__, rc);
return rc;
}

rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
if (rc)
cifs_dbg(FYI, "%s Can't generate NTLM session key, error: %d\n",
__func__, rc);

return rc;
}

#ifdef CONFIG_CIFS_WEAK_PW_HASH
int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
char *lnm_session_key)
{
int i, len;
int rc;
char password_with_pad[CIFS_ENCPWD_SIZE] = {0};

if (password) {
for (len = 0; len < CIFS_ENCPWD_SIZE; len++)
if (!password[len])
break;

memcpy(password_with_pad, password, len);
}

if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
memcpy(lnm_session_key, password_with_pad,
CIFS_ENCPWD_SIZE);
return 0;
}

/* calculate old style session key */
/* calling toupper is less broken than repeatedly
calling nls_toupper would be since that will never
work for UTF8, but neither handles multibyte code pages
but the only alternative would be converting to UCS-16 (Unicode)
(using a routine something like UniStrupr) then
uppercasing and then converting back from Unicode - which
would only worth doing it if we knew it were utf8. Basically
utf8 and other multibyte codepages each need their own strupper
function since a byte at a time will ont work. */

for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
password_with_pad[i] = toupper(password_with_pad[i]);

rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);

return rc;
}
#endif /* CIFS_WEAK_PW_HASH */

/* Build a proper attribute value/target info pairs blob.
* Fill in netbios and dns domain name and workstation name
* and client time (total five av pairs and + one end of fields indicator.
Expand Down Expand Up @@ -780,9 +699,9 @@ calc_seckey(struct cifs_ses *ses)
return -ENOMEM;
}

arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE);
arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key,
CIFS_CPHTXT_SIZE);
cifs_arc4_setkey(ctx_arc4, ses->auth_key.response, CIFS_SESS_KEY_SIZE);
cifs_arc4_crypt(ctx_arc4, ses->ntlmssp->ciphertext, sec_key,
CIFS_CPHTXT_SIZE);

/* make secondary_key/nonce as session key */
memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
Expand Down
8 changes: 0 additions & 8 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ cifs_evict_inode(struct inode *inode)
{
truncate_inode_pages_final(&inode->i_data);
clear_inode(inode);
cifs_fscache_release_inode_cookie(inode);
}

static void
Expand Down Expand Up @@ -438,15 +437,9 @@ cifs_show_security(struct seq_file *s, struct cifs_ses *ses)
seq_puts(s, ",sec=");

switch (ses->sectype) {
case LANMAN:
seq_puts(s, "lanman");
break;
case NTLMv2:
seq_puts(s, "ntlmv2");
break;
case NTLM:
seq_puts(s, "ntlm");
break;
case Kerberos:
seq_puts(s, "krb5");
break;
Expand Down Expand Up @@ -1755,7 +1748,6 @@ MODULE_DESCRIPTION
MODULE_VERSION(CIFS_VERSION);
MODULE_SOFTDEP("ecb");
MODULE_SOFTDEP("hmac");
MODULE_SOFTDEP("md4");
MODULE_SOFTDEP("md5");
MODULE_SOFTDEP("nls");
MODULE_SOFTDEP("aes");
Expand Down
32 changes: 2 additions & 30 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ enum statusEnum {

enum securityEnum {
Unspecified = 0, /* not specified */
LANMAN, /* Legacy LANMAN auth */
NTLM, /* Legacy NTLM012 auth with NTLM hash */
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
Kerberos, /* Kerberos via SPNEGO */
Expand Down Expand Up @@ -634,7 +632,6 @@ struct TCP_Server_Info {
struct session_key session_key;
unsigned long lstrp; /* when we got last response from this server */
struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
#define CIFS_NEGFLAVOR_LANMAN 0 /* wct == 13, LANMAN */
#define CIFS_NEGFLAVOR_UNENCAP 1 /* wct == 17, but no ext_sec */
#define CIFS_NEGFLAVOR_EXTENDED 2 /* wct == 17, ext_sec bit set */
char negflavor; /* NEGOTIATE response flavor */
Expand Down Expand Up @@ -1734,49 +1731,28 @@ static inline bool is_retryable_error(int error)

/* Security Flags: indicate type of session setup needed */
#define CIFSSEC_MAY_SIGN 0x00001
#define CIFSSEC_MAY_NTLM 0x00002
#define CIFSSEC_MAY_NTLMV2 0x00004
#define CIFSSEC_MAY_KRB5 0x00008
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MAY_LANMAN 0x00010
#define CIFSSEC_MAY_PLNTXT 0x00020
#else
#define CIFSSEC_MAY_LANMAN 0
#define CIFSSEC_MAY_PLNTXT 0
#endif /* weak passwords */
#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */

#define CIFSSEC_MUST_SIGN 0x01001
/* note that only one of the following can be set so the
result of setting MUST flags more than once will be to
require use of the stronger protocol */
#define CIFSSEC_MUST_NTLM 0x02002
#define CIFSSEC_MUST_NTLMV2 0x04004
#define CIFSSEC_MUST_KRB5 0x08008
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MUST_LANMAN 0x10010
#define CIFSSEC_MUST_PLNTXT 0x20020
#ifdef CONFIG_CIFS_UPCALL
#define CIFSSEC_MASK 0xBF0BF /* allows weak security but also krb5 */
#else
#define CIFSSEC_MASK 0xB70B7 /* current flags supported if weak */
#endif /* UPCALL */
#else /* do not allow weak pw hash */
#define CIFSSEC_MUST_LANMAN 0
#define CIFSSEC_MUST_PLNTXT 0
#ifdef CONFIG_CIFS_UPCALL
#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
#else
#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */
#endif /* UPCALL */
#endif /* WEAK_PW_HASH */
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */

#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP)
#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
#define CIFSSEC_MAX (CIFSSEC_MUST_NTLMV2)
#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
/*
*****************************************************************
* All constants go here
Expand Down Expand Up @@ -1940,10 +1916,6 @@ static inline char *get_security_type_str(enum securityEnum sectype)
return "Kerberos";
case NTLMv2:
return "NTLMv2";
case NTLM:
return "NTLM";
case LANMAN:
return "LANMAN";
default:
return "Unknown";
}
Expand Down
Loading

0 comments on commit 9c849ce

Please sign in to comment.