From: Greg Kroah-Hartman Date: Thu, 18 Aug 2016 09:36:50 +0000 (+0200) Subject: 3.14-stable patches X-Git-Tag: v3.14.77~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10915df918e8be893180b78c68961d3c0932e155;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch random-properly-align-get_random_int_hash.patch --- diff --git a/queue-3.14/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch b/queue-3.14/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch new file mode 100644 index 00000000000..29dc6d22e2e --- /dev/null +++ b/queue-3.14/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch @@ -0,0 +1,74 @@ +From 8d9535b6efd86e6c07da59f97e68f44efb7fe080 Mon Sep 17 00:00:00 2001 +From: Sachin Prabhu +Date: Thu, 7 Jul 2016 21:28:27 +0100 +Subject: cifs: Check for existing directory when opening file with O_CREAT + +From: Sachin Prabhu + +commit 8d9535b6efd86e6c07da59f97e68f44efb7fe080 upstream. + +When opening a file with O_CREAT flag, check to see if the file opened +is an existing directory. + +This prevents the directory from being opened which subsequently causes +a crash when the close function for directories cifs_closedir() is called +which frees up the file->private_data memory while the file is still +listed on the open file list for the tcon. + +Signed-off-by: Sachin Prabhu +Signed-off-by: Steve French +Reported-by: Xiaoli Feng +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/dir.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -229,6 +229,13 @@ cifs_do_create(struct inode *inode, stru + goto cifs_create_get_file_info; + } + ++ if (S_ISDIR(newinode->i_mode)) { ++ CIFSSMBClose(xid, tcon, fid->netfid); ++ iput(newinode); ++ rc = -EISDIR; ++ goto out; ++ } ++ + if (!S_ISREG(newinode->i_mode)) { + /* + * The server may allow us to open things like +@@ -399,10 +406,14 @@ cifs_create_set_dentry: + if (rc != 0) { + cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n", + rc); +- if (server->ops->close) +- server->ops->close(xid, tcon, fid); +- goto out; ++ goto out_err; + } ++ ++ if (S_ISDIR(newinode->i_mode)) { ++ rc = -EISDIR; ++ goto out_err; ++ } ++ + d_drop(direntry); + d_add(direntry, newinode); + +@@ -410,6 +421,13 @@ out: + kfree(buf); + kfree(full_path); + return rc; ++ ++out_err: ++ if (server->ops->close) ++ server->ops->close(xid, tcon, fid); ++ if (newinode) ++ iput(newinode); ++ goto out; + } + + int diff --git a/queue-3.14/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch b/queue-3.14/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch new file mode 100644 index 00000000000..15d351ab8ba --- /dev/null +++ b/queue-3.14/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch @@ -0,0 +1,81 @@ +From 7893242e2465aea6f2cbc2639da8fa5ce96e8cc2 Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Sun, 24 Jul 2016 10:37:38 +0300 +Subject: CIFS: Fix a possible invalid memory access in smb2_query_symlink() + +From: Pavel Shilovsky + +commit 7893242e2465aea6f2cbc2639da8fa5ce96e8cc2 upstream. + +During following a symbolic link we received err_buf from SMB2_open(). +While the validity of SMB2 error response is checked previously +in smb2_check_message() a symbolic link payload is not checked at all. +Fix it by adding such checks. + +Cc: Dan Carpenter +Signed-off-by: Pavel Shilovsky +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2ops.c | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -858,6 +858,9 @@ smb2_new_lease_key(struct cifs_fid *fid) + get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE); + } + ++#define SMB2_SYMLINK_STRUCT_SIZE \ ++ (sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp)) ++ + static int + smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, + const char *full_path, char **target_path, +@@ -870,7 +873,10 @@ smb2_query_symlink(const unsigned int xi + struct cifs_fid fid; + struct smb2_err_rsp *err_buf = NULL; + struct smb2_symlink_err_rsp *symlink; +- unsigned int sub_len, sub_offset; ++ unsigned int sub_len; ++ unsigned int sub_offset; ++ unsigned int print_len; ++ unsigned int print_offset; + + cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); + +@@ -891,11 +897,33 @@ smb2_query_symlink(const unsigned int xi + kfree(utf16_path); + return -ENOENT; + } ++ ++ if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) || ++ get_rfc1002_length(err_buf) + 4 < SMB2_SYMLINK_STRUCT_SIZE) { ++ kfree(utf16_path); ++ return -ENOENT; ++ } ++ + /* open must fail on symlink - reset rc */ + rc = 0; + symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData; + sub_len = le16_to_cpu(symlink->SubstituteNameLength); + sub_offset = le16_to_cpu(symlink->SubstituteNameOffset); ++ print_len = le16_to_cpu(symlink->PrintNameLength); ++ print_offset = le16_to_cpu(symlink->PrintNameOffset); ++ ++ if (get_rfc1002_length(err_buf) + 4 < ++ SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) { ++ kfree(utf16_path); ++ return -ENOENT; ++ } ++ ++ if (get_rfc1002_length(err_buf) + 4 < ++ SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) { ++ kfree(utf16_path); ++ return -ENOENT; ++ } ++ + *target_path = cifs_strndup_from_utf16( + (char *)symlink->PathBuffer + sub_offset, + sub_len, true, cifs_sb->local_nls); diff --git a/queue-3.14/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch b/queue-3.14/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch new file mode 100644 index 00000000000..f949c7ae3de --- /dev/null +++ b/queue-3.14/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch @@ -0,0 +1,132 @@ +From bd975d1eead2558b76e1079e861eacf1f678b73b Mon Sep 17 00:00:00 2001 +From: Rabin Vincent +Date: Tue, 19 Jul 2016 09:26:21 +0200 +Subject: cifs: fix crash due to race in hmac(md5) handling + +From: Rabin Vincent + +commit bd975d1eead2558b76e1079e861eacf1f678b73b upstream. + +The secmech hmac(md5) structures are present in the TCP_Server_Info +struct and can be shared among multiple CIFS sessions. However, the +server mutex is not currently held when these structures are allocated +and used, which can lead to a kernel crashes, as in the scenario below: + +mount.cifs(8) #1 mount.cifs(8) #2 + +Is secmech.sdeschmaccmd5 allocated? +// false + + Is secmech.sdeschmaccmd5 allocated? + // false + +secmech.hmacmd = crypto_alloc_shash.. +secmech.sdeschmaccmd5 = kzalloc.. +sdeschmaccmd5->shash.tfm = &secmec.hmacmd; + + secmech.sdeschmaccmd5 = kzalloc + // sdeschmaccmd5->shash.tfm + // not yet assigned + +crypto_shash_update() + deref NULL sdeschmaccmd5->shash.tfm + + Unable to handle kernel paging request at virtual address 00000030 + epc : 8027ba34 crypto_shash_update+0x38/0x158 + ra : 8020f2e8 setup_ntlmv2_rsp+0x4bc/0xa84 + Call Trace: + crypto_shash_update+0x38/0x158 + setup_ntlmv2_rsp+0x4bc/0xa84 + build_ntlmssp_auth_blob+0xbc/0x34c + sess_auth_rawntlmssp_authenticate+0xac/0x248 + CIFS_SessSetup+0xf0/0x178 + cifs_setup_session+0x4c/0x84 + cifs_get_smb_ses+0x2c8/0x314 + cifs_mount+0x38c/0x76c + cifs_do_mount+0x98/0x440 + mount_fs+0x20/0xc0 + vfs_kern_mount+0x58/0x138 + do_mount+0x1e8/0xccc + SyS_mount+0x88/0xd4 + syscall_common+0x30/0x54 + +Fix this by locking the srv_mutex around the code which uses these +hmac(md5) structures. All the other secmech algos already have similar +locking. + +Fixes: 95dc8dd14e2e84cc ("Limit allocation of crypto mechanisms to dialect which requires") +Signed-off-by: Rabin Vincent +Acked-by: Sachin Prabhu +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsencrypt.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -727,24 +727,26 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c + + memcpy(ses->auth_key.response + baselen, tiblob, tilen); + ++ mutex_lock(&ses->server->srv_mutex); ++ + rc = crypto_hmacmd5_alloc(ses->server); + if (rc) { + cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + /* calculate ntlmv2_hash */ + rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); + if (rc) { + cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + /* calculate first part of the client response (CR1) */ + rc = CalcNTLMv2_response(ses, ntlmv2_hash); + if (rc) { + cifs_dbg(VFS, "Could not calculate CR1 rc: %d\n", rc); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + /* now calculate the session key for NTLMv2 */ +@@ -753,13 +755,13 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c + if (rc) { + cifs_dbg(VFS, "%s: Could not set NTLMV2 Hash as a key\n", + __func__); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); + if (rc) { + cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, +@@ -767,7 +769,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c + CIFS_HMAC_MD5_HASH_SIZE); + if (rc) { + cifs_dbg(VFS, "%s: Could not update with response\n", __func__); +- goto setup_ntlmv2_rsp_ret; ++ goto unlock; + } + + rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, +@@ -775,6 +777,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, c + if (rc) + cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__); + ++unlock: ++ mutex_unlock(&ses->server->srv_mutex); + setup_ntlmv2_rsp_ret: + kfree(tiblob); + diff --git a/queue-3.14/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch b/queue-3.14/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch new file mode 100644 index 00000000000..f60fb1278b3 --- /dev/null +++ b/queue-3.14/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch @@ -0,0 +1,44 @@ +From 9b4d008787f864f17d008c9c15bbe8a0f7e2fc24 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Mon, 13 Jun 2016 10:10:51 -0400 +Subject: random: print a warning for the first ten uninitialized random users + +From: Theodore Ts'o + +commit 9b4d008787f864f17d008c9c15bbe8a0f7e2fc24 upstream. + +Since systemd is consistently using /dev/urandom before it is +initialized, we can't see the other potentially dangerous users of +/dev/urandom immediately after boot. So print the first ten such +complaints instead. + +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1339,12 +1339,16 @@ random_read(struct file *file, char __us + static ssize_t + urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) + { ++ static int maxwarn = 10; + int ret; + +- if (unlikely(nonblocking_pool.initialized == 0)) +- printk_once(KERN_NOTICE "random: %s urandom read " +- "with %d bits of entropy available\n", +- current->comm, nonblocking_pool.entropy_total); ++ if (unlikely(nonblocking_pool.initialized == 0) && ++ maxwarn > 0) { ++ maxwarn--; ++ printk(KERN_NOTICE "random: %s: uninitialized urandom read " ++ "(%zd bytes read, %d bits of entropy available)\n", ++ current->comm, nbytes, nonblocking_pool.entropy_total); ++ } + + ret = extract_entropy_user(&nonblocking_pool, buf, nbytes); + diff --git a/queue-3.14/random-properly-align-get_random_int_hash.patch b/queue-3.14/random-properly-align-get_random_int_hash.patch new file mode 100644 index 00000000000..94439644cf6 --- /dev/null +++ b/queue-3.14/random-properly-align-get_random_int_hash.patch @@ -0,0 +1,40 @@ +From b1132deac01c2332d234fa821a70022796b79182 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 4 May 2016 21:08:39 -0400 +Subject: random: properly align get_random_int_hash + +From: Eric Biggers + +commit b1132deac01c2332d234fa821a70022796b79182 upstream. + +get_random_long() reads from the get_random_int_hash array using an +unsigned long pointer. For this code to be guaranteed correct on all +architectures, the array must be aligned to an unsigned long boundary. + +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/random.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1632,13 +1632,15 @@ int random_int_secret_init(void) + return 0; + } + ++static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) ++ __aligned(sizeof(unsigned long)); ++ + /* + * Get a random word for internal kernel use only. Similar to urandom but + * with the goal of minimal entropy pool depletion. As a result, the random + * value is not cryptographically secure but for several uses the cost of + * depleting entropy is too high + */ +-static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); + unsigned int get_random_int(void) + { + __u32 *hash; diff --git a/queue-3.14/series b/queue-3.14/series index c0e429ed013..a52e5fd5509 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -8,3 +8,8 @@ hp-wmi-fix-wifi-cannot-be-hard-unblocked.patch s5p-mfc-set-device-name-for-reserved-memory-region-devs.patch s5p-mfc-add-release-callback-for-memory-region-devs.patch bluetooth-fix-l2cap_sock_setsockopt-with-optname-bt_rcvmtu.patch +cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch +cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch +cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch +random-properly-align-get_random_int_hash.patch +random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch