]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Aug 2016 09:37:15 +0000 (11:37 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Aug 2016 09:37:15 +0000 (11:37 +0200)
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
fs-cifs-make-share-unaccessible-at-root-level-mountable.patch
random-add-interrupt-callback-to-vmbus-irq-handler.patch
random-initialize-the-non-blocking-pool-via-add_hwgenerator_randomness.patch
random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch
random-properly-align-get_random_int_hash.patch

queue-4.4/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch [new file with mode: 0644]
queue-4.4/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch [new file with mode: 0644]
queue-4.4/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch [new file with mode: 0644]
queue-4.4/fs-cifs-make-share-unaccessible-at-root-level-mountable.patch [new file with mode: 0644]
queue-4.4/random-add-interrupt-callback-to-vmbus-irq-handler.patch [new file with mode: 0644]
queue-4.4/random-initialize-the-non-blocking-pool-via-add_hwgenerator_randomness.patch [new file with mode: 0644]
queue-4.4/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch [new file with mode: 0644]
queue-4.4/random-properly-align-get_random_int_hash.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch b/queue-4.4/cifs-check-for-existing-directory-when-opening-file-with-o_creat.patch
new file mode 100644 (file)
index 0000000..5cc4089
--- /dev/null
@@ -0,0 +1,74 @@
+From 8d9535b6efd86e6c07da59f97e68f44efb7fe080 Mon Sep 17 00:00:00 2001
+From: Sachin Prabhu <sprabhu@redhat.com>
+Date: Thu, 7 Jul 2016 21:28:27 +0100
+Subject: cifs: Check for existing directory when opening file with O_CREAT
+
+From: Sachin Prabhu <sprabhu@redhat.com>
+
+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 <sprabhu@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Reported-by: Xiaoli Feng <xifeng@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/dir.c |   24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -245,6 +245,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
+@@ -415,10 +422,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);
+@@ -426,6 +437,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-4.4/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch b/queue-4.4/cifs-fix-a-possible-invalid-memory-access-in-smb2_query_symlink.patch
new file mode 100644 (file)
index 0000000..77a1a9e
--- /dev/null
@@ -0,0 +1,81 @@
+From 7893242e2465aea6f2cbc2639da8fa5ce96e8cc2 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilovsky@samba.org>
+Date: Sun, 24 Jul 2016 10:37:38 +0300
+Subject: CIFS: Fix a possible invalid memory access in smb2_query_symlink()
+
+From: Pavel Shilovsky <pshilovsky@samba.org>
+
+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 <dan.carpenter@oracle.com>
+Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2ops.c |   30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1039,6 +1039,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,
+@@ -1051,7 +1054,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);
+@@ -1072,11 +1078,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-4.4/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch b/queue-4.4/cifs-fix-crash-due-to-race-in-hmac-md5-handling.patch
new file mode 100644 (file)
index 0000000..57cdf62
--- /dev/null
@@ -0,0 +1,132 @@
+From bd975d1eead2558b76e1079e861eacf1f678b73b Mon Sep 17 00:00:00 2001
+From: Rabin Vincent <rabinv@axis.com>
+Date: Tue, 19 Jul 2016 09:26:21 +0200
+Subject: cifs: fix crash due to race in hmac(md5) handling
+
+From: Rabin Vincent <rabinv@axis.com>
+
+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 <rabinv@axis.com>
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsencrypt.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/cifsencrypt.c
++++ b/fs/cifs/cifsencrypt.c
+@@ -731,24 +731,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 */
+@@ -757,13 +759,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,
+@@ -771,7 +773,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,
+@@ -779,6 +781,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-4.4/fs-cifs-make-share-unaccessible-at-root-level-mountable.patch b/queue-4.4/fs-cifs-make-share-unaccessible-at-root-level-mountable.patch
new file mode 100644 (file)
index 0000000..4f8e7b5
--- /dev/null
@@ -0,0 +1,253 @@
+From a6b5058fafdf508904bbf16c29b24042cef3c496 Mon Sep 17 00:00:00 2001
+From: Aurelien Aptel <aaptel@suse.com>
+Date: Wed, 25 May 2016 19:59:09 +0200
+Subject: fs/cifs: make share unaccessible at root level mountable
+
+From: Aurelien Aptel <aaptel@suse.com>
+
+commit a6b5058fafdf508904bbf16c29b24042cef3c496 upstream.
+
+if, when mounting //HOST/share/sub/dir/foo we can query /sub/dir/foo but
+not any of the path components above:
+
+- store the /sub/dir/foo prefix in the cifs super_block info
+- in the superblock, set root dentry to the subpath dentry (instead of
+  the share root)
+- set a flag in the superblock to remember it
+- use prefixpath when building path from a dentry
+
+fixes bso#8950
+
+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
+Reviewed-by: Pavel Shilovsky <pshilovsky@samba.org>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifs_fs_sb.h |    4 ++++
+ fs/cifs/cifsfs.c     |   14 +++++++++++++-
+ fs/cifs/connect.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/cifs/dir.c        |   20 ++++++++++++++++++--
+ fs/cifs/inode.c      |   22 ++++++++++++++++++++--
+ 5 files changed, 104 insertions(+), 5 deletions(-)
+
+--- a/fs/cifs/cifs_fs_sb.h
++++ b/fs/cifs/cifs_fs_sb.h
+@@ -46,6 +46,9 @@
+ #define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user */
+ #define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a group */
+ #define CIFS_MOUNT_MAP_SFM_CHR        0x800000 /* SFM/MAC mapping for illegal chars */
++#define CIFS_MOUNT_USE_PREFIX_PATH 0x1000000 /* make subpath with unaccessible
++                                            * root mountable
++                                            */
+ struct cifs_sb_info {
+       struct rb_root tlink_tree;
+@@ -67,5 +70,6 @@ struct cifs_sb_info {
+       struct backing_dev_info bdi;
+       struct delayed_work prune_tlinks;
+       struct rcu_head rcu;
++      char *prepath;
+ };
+ #endif                                /* _CIFS_FS_SB_H */
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -686,6 +686,14 @@ cifs_do_mount(struct file_system_type *f
+               goto out_cifs_sb;
+       }
++      if (volume_info->prepath) {
++              cifs_sb->prepath = kstrdup(volume_info->prepath, GFP_KERNEL);
++              if (cifs_sb->prepath == NULL) {
++                      root = ERR_PTR(-ENOMEM);
++                      goto out_cifs_sb;
++              }
++      }
++
+       cifs_setup_cifs_sb(volume_info, cifs_sb);
+       rc = cifs_mount(cifs_sb, volume_info);
+@@ -724,7 +732,11 @@ cifs_do_mount(struct file_system_type *f
+               sb->s_flags |= MS_ACTIVE;
+       }
+-      root = cifs_get_root(volume_info, sb);
++      if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
++              root = dget(sb->s_root);
++      else
++              root = cifs_get_root(volume_info, sb);
++
+       if (IS_ERR(root))
+               goto out_super;
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3517,6 +3517,44 @@ cifs_get_volume_info(char *mount_data, c
+       return volume_info;
+ }
++static int
++cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
++                                      unsigned int xid,
++                                      struct cifs_tcon *tcon,
++                                      struct cifs_sb_info *cifs_sb,
++                                      char *full_path)
++{
++      int rc;
++      char *s;
++      char sep, tmp;
++
++      sep = CIFS_DIR_SEP(cifs_sb);
++      s = full_path;
++
++      rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
++      while (rc == 0) {
++              /* skip separators */
++              while (*s == sep)
++                      s++;
++              if (!*s)
++                      break;
++              /* next separator */
++              while (*s && *s != sep)
++                      s++;
++
++              /*
++               * temporarily null-terminate the path at the end of
++               * the current component
++               */
++              tmp = *s;
++              *s = 0;
++              rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
++                                                   full_path);
++              *s = tmp;
++      }
++      return rc;
++}
++
+ int
+ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
+ {
+@@ -3654,6 +3692,16 @@ remote_path_check:
+                       kfree(full_path);
+                       goto mount_fail_check;
+               }
++
++              rc = cifs_are_all_path_components_accessible(server,
++                                                           xid, tcon, cifs_sb,
++                                                           full_path);
++              if (rc != 0) {
++                      cifs_dbg(VFS, "cannot query dirs between root and final path, "
++                               "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
++                      cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
++                      rc = 0;
++              }
+               kfree(full_path);
+       }
+@@ -3923,6 +3971,7 @@ cifs_umount(struct cifs_sb_info *cifs_sb
+       bdi_destroy(&cifs_sb->bdi);
+       kfree(cifs_sb->mountdata);
++      kfree(cifs_sb->prepath);
+       call_rcu(&cifs_sb->rcu, delayed_free);
+ }
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -84,6 +84,7 @@ build_path_from_dentry(struct dentry *di
+       struct dentry *temp;
+       int namelen;
+       int dfsplen;
++      int pplen = 0;
+       char *full_path;
+       char dirsep;
+       struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
+@@ -95,8 +96,12 @@ build_path_from_dentry(struct dentry *di
+               dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
+       else
+               dfsplen = 0;
++
++      if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
++              pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0;
++
+ cifs_bp_rename_retry:
+-      namelen = dfsplen;
++      namelen = dfsplen + pplen;
+       seq = read_seqbegin(&rename_lock);
+       rcu_read_lock();
+       for (temp = direntry; !IS_ROOT(temp);) {
+@@ -137,7 +142,7 @@ cifs_bp_rename_retry:
+               }
+       }
+       rcu_read_unlock();
+-      if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
++      if (namelen != dfsplen + pplen || read_seqretry(&rename_lock, seq)) {
+               cifs_dbg(FYI, "did not end path lookup where expected. namelen=%ddfsplen=%d\n",
+                        namelen, dfsplen);
+               /* presumably this is only possible if racing with a rename
+@@ -153,6 +158,17 @@ cifs_bp_rename_retry:
+          those safely to '/' if any are found in the middle of the prepath */
+       /* BB test paths to Windows with '/' in the midst of prepath */
++      if (pplen) {
++              int i;
++
++              cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath);
++              memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1);
++              full_path[dfsplen] = '\\';
++              for (i = 0; i < pplen-1; i++)
++                      if (full_path[dfsplen+1+i] == '/')
++                              full_path[dfsplen+1+i] = CIFS_DIR_SEP(cifs_sb);
++      }
++
+       if (dfsplen) {
+               strncpy(full_path, tcon->treeName, dfsplen);
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -982,10 +982,26 @@ struct inode *cifs_root_iget(struct supe
+       struct inode *inode = NULL;
+       long rc;
+       struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
++      char *path = NULL;
++      int len;
++
++      if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
++          && cifs_sb->prepath) {
++              len = strlen(cifs_sb->prepath);
++              path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL);
++              if (path == NULL)
++                      return ERR_PTR(-ENOMEM);
++              path[0] = '/';
++              memcpy(path+1, cifs_sb->prepath, len);
++      } else {
++              path = kstrdup("", GFP_KERNEL);
++              if (path == NULL)
++                      return ERR_PTR(-ENOMEM);
++      }
+       xid = get_xid();
+       if (tcon->unix_ext) {
+-              rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
++              rc = cifs_get_inode_info_unix(&inode, path, sb, xid);
+               /* some servers mistakenly claim POSIX support */
+               if (rc != -EOPNOTSUPP)
+                       goto iget_no_retry;
+@@ -993,7 +1009,8 @@ struct inode *cifs_root_iget(struct supe
+               tcon->unix_ext = false;
+       }
+-      rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
++      convert_delimiter(path, CIFS_DIR_SEP(cifs_sb));
++      rc = cifs_get_inode_info(&inode, path, NULL, sb, xid, NULL);
+ iget_no_retry:
+       if (!inode) {
+@@ -1022,6 +1039,7 @@ iget_no_retry:
+       }
+ out:
++      kfree(path);
+       /* can not call macro free_xid here since in a void func
+        * TODO: This is no longer true
+        */
diff --git a/queue-4.4/random-add-interrupt-callback-to-vmbus-irq-handler.patch b/queue-4.4/random-add-interrupt-callback-to-vmbus-irq-handler.patch
new file mode 100644 (file)
index 0000000..6ba306c
--- /dev/null
@@ -0,0 +1,56 @@
+From 4b44f2d18a330565227a7348844493c59366171e Mon Sep 17 00:00:00 2001
+From: Stephan Mueller <smueller@chronox.de>
+Date: Mon, 2 May 2016 02:14:34 -0400
+Subject: random: add interrupt callback to VMBus IRQ handler
+
+From: Stephan Mueller <smueller@chronox.de>
+
+commit 4b44f2d18a330565227a7348844493c59366171e upstream.
+
+The Hyper-V Linux Integration Services use the VMBus implementation for
+communication with the Hypervisor. VMBus registers its own interrupt
+handler that completely bypasses the common Linux interrupt handling.
+This implies that the interrupt entropy collector is not triggered.
+
+This patch adds the interrupt entropy collection callback into the VMBus
+interrupt handler function.
+
+Signed-off-by: Stephan Mueller <stephan.mueller@atsec.com>
+Signed-off-by: Stephan Mueller <smueller@chronox.de>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c  |    1 +
+ drivers/hv/vmbus_drv.c |    3 +++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -948,6 +948,7 @@ void add_interrupt_randomness(int irq, i
+       /* award one bit for the contents of the fast pool */
+       credit_entropy_bits(r, credit + 1);
+ }
++EXPORT_SYMBOL_GPL(add_interrupt_randomness);
+ #ifdef CONFIG_BLOCK
+ void add_disk_randomness(struct gendisk *disk)
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -41,6 +41,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/screen_info.h>
+ #include <linux/kdebug.h>
++#include <linux/random.h>
+ #include "hyperv_vmbus.h"
+ static struct acpi_device  *hv_acpi_dev;
+@@ -826,6 +827,8 @@ static void vmbus_isr(void)
+               else
+                       tasklet_schedule(&msg_dpc);
+       }
++
++      add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
+ }
diff --git a/queue-4.4/random-initialize-the-non-blocking-pool-via-add_hwgenerator_randomness.patch b/queue-4.4/random-initialize-the-non-blocking-pool-via-add_hwgenerator_randomness.patch
new file mode 100644 (file)
index 0000000..5f8f79d
--- /dev/null
@@ -0,0 +1,46 @@
+From 3371f3da08cff4b75c1f2dce742d460539d6566d Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 12 Jun 2016 18:11:51 -0400
+Subject: random: initialize the non-blocking pool via add_hwgenerator_randomness()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 3371f3da08cff4b75c1f2dce742d460539d6566d upstream.
+
+If we have a hardware RNG and are using the in-kernel rngd, we should
+use this to initialize the non-blocking pool so that getrandom(2)
+doesn't block unnecessarily.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1849,12 +1849,18 @@ void add_hwgenerator_randomness(const ch
+ {
+       struct entropy_store *poolp = &input_pool;
+-      /* Suspend writing if we're above the trickle threshold.
+-       * We'll be woken up again once below random_write_wakeup_thresh,
+-       * or when the calling thread is about to terminate.
+-       */
+-      wait_event_interruptible(random_write_wait, kthread_should_stop() ||
++      if (unlikely(nonblocking_pool.initialized == 0))
++              poolp = &nonblocking_pool;
++      else {
++              /* Suspend writing if we're above the trickle
++               * threshold.  We'll be woken up again once below
++               * random_write_wakeup_thresh, or when the calling
++               * thread is about to terminate.
++               */
++              wait_event_interruptible(random_write_wait,
++                                       kthread_should_stop() ||
+                       ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits);
++      }
+       mix_pool_bytes(poolp, buffer, count);
+       credit_entropy_bits(poolp, entropy);
+ }
diff --git a/queue-4.4/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch b/queue-4.4/random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch
new file mode 100644 (file)
index 0000000..9687296
--- /dev/null
@@ -0,0 +1,44 @@
+From 9b4d008787f864f17d008c9c15bbe8a0f7e2fc24 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+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 <tytso@mit.edu>
+
+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 <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1460,12 +1460,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);
++      }
+       nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
+       ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
diff --git a/queue-4.4/random-properly-align-get_random_int_hash.patch b/queue-4.4/random-properly-align-get_random_int_hash.patch
new file mode 100644 (file)
index 0000000..e33879c
--- /dev/null
@@ -0,0 +1,40 @@
+From b1132deac01c2332d234fa821a70022796b79182 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers3@gmail.com>
+Date: Wed, 4 May 2016 21:08:39 -0400
+Subject: random: properly align get_random_int_hash
+
+From: Eric Biggers <ebiggers3@gmail.com>
+
+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 <ebiggers3@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1793,13 +1793,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;
index 334cca15630fcb18021ea3f982028a89d76dca5c..42ac9416edf9035f0e2a1b4c83917cc9c3b83a92 100644 (file)
@@ -47,3 +47,11 @@ ovl-disallow-overlayfs-as-upperdir.patch
 remoteproc-fix-potential-race-condition-in-rproc_add.patch
 arc-mm-don-t-loose-pte_special-in-pte_modify.patch
 jbd2-make-journal-y2038-safe.patch
+fs-cifs-make-share-unaccessible-at-root-level-mountable.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-initialize-the-non-blocking-pool-via-add_hwgenerator_randomness.patch
+random-print-a-warning-for-the-first-ten-uninitialized-random-users.patch
+random-add-interrupt-callback-to-vmbus-irq-handler.patch