]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Nov 2024 13:12:45 +0000 (14:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 19 Nov 2024 13:12:45 +0000 (14:12 +0100)
added patches:
fs-9p-fix-uninitialized-values-during-inode-evict.patch
ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch
ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch
mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch
mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch
mptcp-define-more-local-variables-sk.patch
mptcp-drop-lookup_by_id-in-lookup_addr.patch
mptcp-hold-pm-lock-when-deleting-entry.patch
mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch
mptcp-update-local-address-flags-when-setting-it.patch
net-add-copy_safe_from_sockptr-helper.patch
nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch

13 files changed:
queue-6.1/fs-9p-fix-uninitialized-values-during-inode-evict.patch [new file with mode: 0644]
queue-6.1/ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch [new file with mode: 0644]
queue-6.1/ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch [new file with mode: 0644]
queue-6.1/mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch [new file with mode: 0644]
queue-6.1/mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch [new file with mode: 0644]
queue-6.1/mptcp-define-more-local-variables-sk.patch [new file with mode: 0644]
queue-6.1/mptcp-drop-lookup_by_id-in-lookup_addr.patch [new file with mode: 0644]
queue-6.1/mptcp-hold-pm-lock-when-deleting-entry.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch [new file with mode: 0644]
queue-6.1/mptcp-update-local-address-flags-when-setting-it.patch [new file with mode: 0644]
queue-6.1/net-add-copy_safe_from_sockptr-helper.patch [new file with mode: 0644]
queue-6.1/nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/fs-9p-fix-uninitialized-values-during-inode-evict.patch b/queue-6.1/fs-9p-fix-uninitialized-values-during-inode-evict.patch
new file mode 100644 (file)
index 0000000..b14a1e6
--- /dev/null
@@ -0,0 +1,67 @@
+From stable+bounces-93895-greg=kroah.com@vger.kernel.org Tue Nov 19 04:43:37 2024
+From: Xiangyu Chen <xiangyu.chen@eng.windriver.com>
+Date: Tue, 19 Nov 2024 11:43:16 +0800
+Subject: fs/9p: fix uninitialized values during inode evict
+To: ericvh@kernel.org
+Cc: stable@vger.kernel.org
+Message-ID: <20241119034317.3364577-2-xiangyu.chen@eng.windriver.com>
+
+From: Eric Van Hensbergen <ericvh@kernel.org>
+
+[ Upstream commit 6630036b7c228f57c7893ee0403e92c2db2cd21d ]
+
+If an iget fails due to not being able to retrieve information
+from the server then the inode structure is only partially
+initialized.  When the inode gets evicted, references to
+uninitialized structures (like fscache cookies) were being
+made.
+
+This patch checks for a bad_inode before doing anything other
+than clearing the inode from the cache.  Since the inode is
+bad, it shouldn't have any state associated with it that needs
+to be written back (and there really isn't a way to complete
+those anyways).
+
+Reported-by: syzbot+eb83fe1cce5833cd66a0@syzkaller.appspotmail.com
+Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
+(cherry picked from commit 1b4cb6e91f19b81217ad98142ee53a1ab25893fd)
+[Xiangyu: CVE-2024-36923 Minor conflict resolution due to missing 4eb31178 ]
+Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/9p/vfs_inode.c |   23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+--- a/fs/9p/vfs_inode.c
++++ b/fs/9p/vfs_inode.c
+@@ -392,17 +392,20 @@ void v9fs_evict_inode(struct inode *inod
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       __le32 version;
+-      truncate_inode_pages_final(&inode->i_data);
+-      version = cpu_to_le32(v9inode->qid.version);
+-      fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode,
++      if (!is_bad_inode(inode)) {
++              truncate_inode_pages_final(&inode->i_data);
++              version = cpu_to_le32(v9inode->qid.version);
++              fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode,
+                                     &version);
+-      clear_inode(inode);
+-      filemap_fdatawrite(&inode->i_data);
+-
+-      fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
+-      /* clunk the fid stashed in writeback_fid */
+-      p9_fid_put(v9inode->writeback_fid);
+-      v9inode->writeback_fid = NULL;
++              clear_inode(inode);
++              filemap_fdatawrite(&inode->i_data);
++              if (v9fs_inode_cookie(v9inode))
++                      fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
++              /* clunk the fid stashed in writeback_fid */
++              p9_fid_put(v9inode->writeback_fid);
++              v9inode->writeback_fid = NULL;
++      } else
++              clear_inode(inode);
+ }
+ static int v9fs_test_inode(struct inode *inode, void *data)
diff --git a/queue-6.1/ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch b/queue-6.1/ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch
new file mode 100644 (file)
index 0000000..b6cff10
--- /dev/null
@@ -0,0 +1,311 @@
+From c6cd2e8d2d9aa7ee35b1fa6a668e32a22a9753da Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Tue, 19 Mar 2024 08:40:48 +0900
+Subject: ksmbd: fix potencial out-of-bounds when buffer offset is invalid
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit c6cd2e8d2d9aa7ee35b1fa6a668e32a22a9753da upstream.
+
+I found potencial out-of-bounds when buffer offset fields of a few requests
+is invalid. This patch set the minimum value of buffer offset field to
+->Buffer offset to validate buffer length.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Vamsi Krishna Brahmajosyula <vamsi-krishna.brahmajosyula@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/smb2misc.c |   23 +++++++++++++++-------
+ fs/smb/server/smb2pdu.c  |   48 +++++++++++++++++++++++++----------------------
+ 2 files changed, 42 insertions(+), 29 deletions(-)
+
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -101,7 +101,9 @@ static int smb2_get_data_area_len(unsign
+               *len = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength);
+               break;
+       case SMB2_TREE_CONNECT:
+-              *off = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset);
++              *off = max_t(unsigned short int,
++                           le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathOffset),
++                           offsetof(struct smb2_tree_connect_req, Buffer));
+               *len = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathLength);
+               break;
+       case SMB2_CREATE:
+@@ -110,7 +112,6 @@ static int smb2_get_data_area_len(unsign
+                       max_t(unsigned short int,
+                             le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset),
+                             offsetof(struct smb2_create_req, Buffer));
+-
+               unsigned short int name_len =
+                       le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength);
+@@ -131,11 +132,15 @@ static int smb2_get_data_area_len(unsign
+               break;
+       }
+       case SMB2_QUERY_INFO:
+-              *off = le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset);
++              *off = max_t(unsigned int,
++                           le16_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferOffset),
++                           offsetof(struct smb2_query_info_req, Buffer));
+               *len = le32_to_cpu(((struct smb2_query_info_req *)hdr)->InputBufferLength);
+               break;
+       case SMB2_SET_INFO:
+-              *off = le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset);
++              *off = max_t(unsigned int,
++                           le16_to_cpu(((struct smb2_set_info_req *)hdr)->BufferOffset),
++                           offsetof(struct smb2_set_info_req, Buffer));
+               *len = le32_to_cpu(((struct smb2_set_info_req *)hdr)->BufferLength);
+               break;
+       case SMB2_READ:
+@@ -145,7 +150,7 @@ static int smb2_get_data_area_len(unsign
+       case SMB2_WRITE:
+               if (((struct smb2_write_req *)hdr)->DataOffset ||
+                   ((struct smb2_write_req *)hdr)->Length) {
+-                      *off = max_t(unsigned int,
++                      *off = max_t(unsigned short int,
+                                    le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset),
+                                    offsetof(struct smb2_write_req, Buffer));
+                       *len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length);
+@@ -156,7 +161,9 @@ static int smb2_get_data_area_len(unsign
+               *len = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoLength);
+               break;
+       case SMB2_QUERY_DIRECTORY:
+-              *off = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset);
++              *off = max_t(unsigned short int,
++                           le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameOffset),
++                           offsetof(struct smb2_query_directory_req, Buffer));
+               *len = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameLength);
+               break;
+       case SMB2_LOCK:
+@@ -171,7 +178,9 @@ static int smb2_get_data_area_len(unsign
+               break;
+       }
+       case SMB2_IOCTL:
+-              *off = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset);
++              *off = max_t(unsigned int,
++                           le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset),
++                           offsetof(struct smb2_ioctl_req, Buffer));
+               *len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);
+               break;
+       default:
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -1961,7 +1961,7 @@ int smb2_tree_connect(struct ksmbd_work
+       WORK_BUFFERS(work, req, rsp);
+-      treename = smb_strndup_from_utf16(req->Buffer,
++      treename = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->PathOffset),
+                                         le16_to_cpu(req->PathLength), true,
+                                         conn->local_nls);
+       if (IS_ERR(treename)) {
+@@ -2723,7 +2723,7 @@ int smb2_open(struct ksmbd_work *work)
+                       goto err_out2;
+               }
+-              name = smb2_get_name(req->Buffer,
++              name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset),
+                                    le16_to_cpu(req->NameLength),
+                                    work->conn->local_nls);
+               if (IS_ERR(name)) {
+@@ -4096,7 +4096,7 @@ int smb2_query_dir(struct ksmbd_work *wo
+       }
+       srch_flag = req->Flags;
+-      srch_ptr = smb_strndup_from_utf16(req->Buffer,
++      srch_ptr = smb_strndup_from_utf16((char *)req + le16_to_cpu(req->FileNameOffset),
+                                         le16_to_cpu(req->FileNameLength), 1,
+                                         conn->local_nls);
+       if (IS_ERR(srch_ptr)) {
+@@ -4357,7 +4357,8 @@ static int smb2_get_ea(struct ksmbd_work
+                   sizeof(struct smb2_ea_info_req))
+                       return -EINVAL;
+-              ea_req = (struct smb2_ea_info_req *)req->Buffer;
++              ea_req = (struct smb2_ea_info_req *)((char *)req +
++                                                   le16_to_cpu(req->InputBufferOffset));
+       } else {
+               /* need to send all EAs, if no specific EA is requested*/
+               if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY)
+@@ -5971,6 +5972,7 @@ static int smb2_set_info_file(struct ksm
+                             struct ksmbd_share_config *share)
+ {
+       unsigned int buf_len = le32_to_cpu(req->BufferLength);
++      char *buffer = (char *)req + le16_to_cpu(req->BufferOffset);
+       switch (req->FileInfoClass) {
+       case FILE_BASIC_INFORMATION:
+@@ -5978,7 +5980,7 @@ static int smb2_set_info_file(struct ksm
+               if (buf_len < sizeof(struct smb2_file_basic_info))
+                       return -EINVAL;
+-              return set_file_basic_info(fp, (struct smb2_file_basic_info *)req->Buffer, share);
++              return set_file_basic_info(fp, (struct smb2_file_basic_info *)buffer, share);
+       }
+       case FILE_ALLOCATION_INFORMATION:
+       {
+@@ -5986,7 +5988,7 @@ static int smb2_set_info_file(struct ksm
+                       return -EINVAL;
+               return set_file_allocation_info(work, fp,
+-                                              (struct smb2_file_alloc_info *)req->Buffer);
++                                              (struct smb2_file_alloc_info *)buffer);
+       }
+       case FILE_END_OF_FILE_INFORMATION:
+       {
+@@ -5994,7 +5996,7 @@ static int smb2_set_info_file(struct ksm
+                       return -EINVAL;
+               return set_end_of_file_info(work, fp,
+-                                          (struct smb2_file_eof_info *)req->Buffer);
++                                          (struct smb2_file_eof_info *)buffer);
+       }
+       case FILE_RENAME_INFORMATION:
+       {
+@@ -6002,7 +6004,7 @@ static int smb2_set_info_file(struct ksm
+                       return -EINVAL;
+               return set_rename_info(work, fp,
+-                                     (struct smb2_file_rename_info *)req->Buffer,
++                                     (struct smb2_file_rename_info *)buffer,
+                                      buf_len);
+       }
+       case FILE_LINK_INFORMATION:
+@@ -6011,7 +6013,7 @@ static int smb2_set_info_file(struct ksm
+                       return -EINVAL;
+               return smb2_create_link(work, work->tcon->share_conf,
+-                                      (struct smb2_file_link_info *)req->Buffer,
++                                      (struct smb2_file_link_info *)buffer,
+                                       buf_len, fp->filp,
+                                       work->conn->local_nls);
+       }
+@@ -6021,7 +6023,7 @@ static int smb2_set_info_file(struct ksm
+                       return -EINVAL;
+               return set_file_disposition_info(fp,
+-                                               (struct smb2_file_disposition_info *)req->Buffer);
++                                               (struct smb2_file_disposition_info *)buffer);
+       }
+       case FILE_FULL_EA_INFORMATION:
+       {
+@@ -6034,7 +6036,7 @@ static int smb2_set_info_file(struct ksm
+               if (buf_len < sizeof(struct smb2_ea_info))
+                       return -EINVAL;
+-              return smb2_set_ea((struct smb2_ea_info *)req->Buffer,
++              return smb2_set_ea((struct smb2_ea_info *)buffer,
+                                  buf_len, &fp->filp->f_path, true);
+       }
+       case FILE_POSITION_INFORMATION:
+@@ -6042,14 +6044,14 @@ static int smb2_set_info_file(struct ksm
+               if (buf_len < sizeof(struct smb2_file_pos_info))
+                       return -EINVAL;
+-              return set_file_position_info(fp, (struct smb2_file_pos_info *)req->Buffer);
++              return set_file_position_info(fp, (struct smb2_file_pos_info *)buffer);
+       }
+       case FILE_MODE_INFORMATION:
+       {
+               if (buf_len < sizeof(struct smb2_file_mode_info))
+                       return -EINVAL;
+-              return set_file_mode_info(fp, (struct smb2_file_mode_info *)req->Buffer);
++              return set_file_mode_info(fp, (struct smb2_file_mode_info *)buffer);
+       }
+       }
+@@ -6130,7 +6132,7 @@ int smb2_set_info(struct ksmbd_work *wor
+               }
+               rc = smb2_set_info_sec(fp,
+                                      le32_to_cpu(req->AdditionalInformation),
+-                                     req->Buffer,
++                                     (char *)req + le16_to_cpu(req->BufferOffset),
+                                      le32_to_cpu(req->BufferLength));
+               ksmbd_revert_fsids(work);
+               break;
+@@ -7576,7 +7578,7 @@ static int fsctl_pipe_transceive(struct
+                                struct smb2_ioctl_rsp *rsp)
+ {
+       struct ksmbd_rpc_command *rpc_resp;
+-      char *data_buf = (char *)&req->Buffer[0];
++      char *data_buf = (char *)req + le32_to_cpu(req->InputOffset);
+       int nbytes = 0;
+       rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
+@@ -7689,6 +7691,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+       u64 id = KSMBD_NO_FID;
+       struct ksmbd_conn *conn = work->conn;
+       int ret = 0;
++      char *buffer;
+       if (work->next_smb2_rcv_hdr_off) {
+               req = ksmbd_req_buf_next(work);
+@@ -7711,6 +7714,8 @@ int smb2_ioctl(struct ksmbd_work *work)
+               goto out;
+       }
++      buffer = (char *)req + le32_to_cpu(req->InputOffset);
++
+       cnt_code = le32_to_cpu(req->CtlCode);
+       ret = smb2_calc_max_out_buf_len(work, 48,
+                                       le32_to_cpu(req->MaxOutputResponse));
+@@ -7768,7 +7773,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+               }
+               ret = fsctl_validate_negotiate_info(conn,
+-                      (struct validate_negotiate_info_req *)&req->Buffer[0],
++                      (struct validate_negotiate_info_req *)buffer,
+                       (struct validate_negotiate_info_rsp *)&rsp->Buffer[0],
+                       in_buf_len);
+               if (ret < 0)
+@@ -7821,7 +7826,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+               rsp->VolatileFileId = req->VolatileFileId;
+               rsp->PersistentFileId = req->PersistentFileId;
+               fsctl_copychunk(work,
+-                              (struct copychunk_ioctl_req *)&req->Buffer[0],
++                              (struct copychunk_ioctl_req *)buffer,
+                               le32_to_cpu(req->CtlCode),
+                               le32_to_cpu(req->InputCount),
+                               req->VolatileFileId,
+@@ -7834,8 +7839,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+                       goto out;
+               }
+-              ret = fsctl_set_sparse(work, id,
+-                                     (struct file_sparse *)&req->Buffer[0]);
++              ret = fsctl_set_sparse(work, id, (struct file_sparse *)buffer);
+               if (ret < 0)
+                       goto out;
+               break;
+@@ -7858,7 +7862,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+               }
+               zero_data =
+-                      (struct file_zero_data_information *)&req->Buffer[0];
++                      (struct file_zero_data_information *)buffer;
+               off = le64_to_cpu(zero_data->FileOffset);
+               bfz = le64_to_cpu(zero_data->BeyondFinalZero);
+@@ -7889,7 +7893,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+               }
+               ret = fsctl_query_allocated_ranges(work, id,
+-                      (struct file_allocated_range_buffer *)&req->Buffer[0],
++                      (struct file_allocated_range_buffer *)buffer,
+                       (struct file_allocated_range_buffer *)&rsp->Buffer[0],
+                       out_buf_len /
+                       sizeof(struct file_allocated_range_buffer), &nbytes);
+@@ -7933,7 +7937,7 @@ int smb2_ioctl(struct ksmbd_work *work)
+                       goto out;
+               }
+-              dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0];
++              dup_ext = (struct duplicate_extents_to_file *)buffer;
+               fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle,
+                                            dup_ext->PersistentFileHandle);
diff --git a/queue-6.1/ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch b/queue-6.1/ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch
new file mode 100644 (file)
index 0000000..b0a552c
--- /dev/null
@@ -0,0 +1,39 @@
+From a80a486d72e20bd12c335bcd38b6e6f19356b0aa Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <linkinjeon@kernel.org>
+Date: Sat, 16 Mar 2024 23:36:36 +0900
+Subject: ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+commit a80a486d72e20bd12c335bcd38b6e6f19356b0aa upstream.
+
+If ->NameOffset of smb2_create_req is smaller than Buffer offset of
+smb2_create_req, slab-out-of-bounds read can happen from smb2_open.
+This patch set the minimum value of the name offset to the buffer offset
+to validate name length of smb2_create_req().
+
+Cc: stable@vger.kernel.org
+Reported-by: Xuanzhe Yu <yuxuanzhe@outlook.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: c6cd2e8d2d9a ("ksmbd: fix potencial out-of-bounds when buffer offset is invalid")
+Signed-off-by: Vamsi Krishna Brahmajosyula <vamsi-krishna.brahmajosyula@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/smb2misc.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/smb/server/smb2misc.c
++++ b/fs/smb/server/smb2misc.c
+@@ -107,7 +107,10 @@ static int smb2_get_data_area_len(unsign
+       case SMB2_CREATE:
+       {
+               unsigned short int name_off =
+-                      le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset);
++                      max_t(unsigned short int,
++                            le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset),
++                            offsetof(struct smb2_create_req, Buffer));
++
+               unsigned short int name_len =
+                       le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength);
diff --git a/queue-6.1/mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch b/queue-6.1/mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch
new file mode 100644 (file)
index 0000000..99583c3
--- /dev/null
@@ -0,0 +1,92 @@
+From stable+bounces-93938-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:45 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:51 +0100
+Subject: mptcp: add userspace_pm_lookup_addr_by_id helper
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <tanggeliang@kylinos.cn>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, "David S . Miller" <davem@davemloft.net>
+Message-ID: <20241119083547.3234013-12-matttbe@kernel.org>
+
+From: Geliang Tang <tanggeliang@kylinos.cn>
+
+commit 06afe09091ee69dc7ab058b4be9917ae59cc81e5 upstream.
+
+Corresponding __lookup_addr_by_id() helper in the in-kernel netlink PM,
+this patch adds a new helper mptcp_userspace_pm_lookup_addr_by_id() to
+lookup the address entry with the given id on the userspace pm local
+address list.
+
+Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: f642c5c4d528 ("mptcp: hold pm lock when deleting entry")
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c |   31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -106,22 +106,29 @@ static int mptcp_userspace_pm_delete_loc
+       return -EINVAL;
+ }
++static struct mptcp_pm_addr_entry *
++mptcp_userspace_pm_lookup_addr_by_id(struct mptcp_sock *msk, unsigned int id)
++{
++      struct mptcp_pm_addr_entry *entry;
++
++      list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
++              if (entry->addr.id == id)
++                      return entry;
++      }
++      return NULL;
++}
++
+ int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk,
+                                                  unsigned int id,
+                                                  u8 *flags, int *ifindex)
+ {
+-      struct mptcp_pm_addr_entry *entry, *match = NULL;
++      struct mptcp_pm_addr_entry *match;
+       *flags = 0;
+       *ifindex = 0;
+       spin_lock_bh(&msk->pm.lock);
+-      list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+-              if (id == entry->addr.id) {
+-                      match = entry;
+-                      break;
+-              }
+-      }
++      match = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
+       spin_unlock_bh(&msk->pm.lock);
+       if (match) {
+               *flags = match->flags;
+@@ -282,7 +289,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+ {
+       struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN];
+       struct nlattr *id = info->attrs[MPTCP_PM_ATTR_LOC_ID];
+-      struct mptcp_pm_addr_entry *match = NULL;
++      struct mptcp_pm_addr_entry *match;
+       struct mptcp_pm_addr_entry *entry;
+       struct mptcp_sock *msk;
+       LIST_HEAD(free_list);
+@@ -319,13 +326,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+       lock_sock(sk);
+-      list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+-              if (entry->addr.id == id_val) {
+-                      match = entry;
+-                      break;
+-              }
+-      }
+-
++      match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
+       if (!match) {
+               GENL_SET_ERR_MSG(info, "address with specified id not found");
+               release_sock(sk);
diff --git a/queue-6.1/mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch b/queue-6.1/mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch
new file mode 100644 (file)
index 0000000..de47890
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-93936-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:20 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:49 +0100
+Subject: mptcp: cope racing subflow creation in mptcp_rcv_space_adjust
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Paolo Abeni <pabeni@redhat.com>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-10-matttbe@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit ce7356ae35943cc6494cc692e62d51a734062b7d upstream.
+
+Additional active subflows - i.e. created by the in kernel path
+manager - are included into the subflow list before starting the
+3whs.
+
+A racing recvmsg() spooling data received on an already established
+subflow would unconditionally call tcp_cleanup_rbuf() on all the
+current subflows, potentially hitting a divide by zero error on
+the newly created ones.
+
+Explicitly check that the subflow is in a suitable state before
+invoking tcp_cleanup_rbuf().
+
+Fixes: c76c6956566f ("mptcp: call tcp_cleanup_rbuf on subflows")
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/02374660836e1b52afc91966b7535c8c5f7bafb0.1731060874.git.pabeni@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflicts in protocol.c, because commit f410cbea9f3d ("tcp: annotate
+  data-races around tp->window_clamp") has not been backported to this
+  version. The conflict is easy to resolve, because only the context is
+  different, but not the line to modify. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2057,7 +2057,8 @@ static void mptcp_rcv_space_adjust(struc
+                               slow = lock_sock_fast(ssk);
+                               WRITE_ONCE(ssk->sk_rcvbuf, rcvbuf);
+                               tcp_sk(ssk)->window_clamp = window_clamp;
+-                              tcp_cleanup_rbuf(ssk, 1);
++                              if (tcp_can_send_ack(ssk))
++                                      tcp_cleanup_rbuf(ssk, 1);
+                               unlock_sock_fast(ssk, slow);
+                       }
+               }
diff --git a/queue-6.1/mptcp-define-more-local-variables-sk.patch b/queue-6.1/mptcp-define-more-local-variables-sk.patch
new file mode 100644 (file)
index 0000000..317fb9a
--- /dev/null
@@ -0,0 +1,156 @@
+From stable+bounces-93937-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:32 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:50 +0100
+Subject: mptcp: define more local variables sk
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <geliang.tang@suse.com>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-11-matttbe@kernel.org>
+
+From: Geliang Tang <geliang.tang@suse.com>
+
+commit 14cb0e0bf39bd10429ba14e9e2f905f1144226fc upstream.
+
+'(struct sock *)msk' is used several times in mptcp_nl_cmd_announce(),
+mptcp_nl_cmd_remove() or mptcp_userspace_pm_set_flags() in pm_userspace.c,
+it's worth adding a local variable sk to point it.
+
+Reviewed-by: Matthieu Baerts <matttbe@kernel.org>
+Signed-off-by: Geliang Tang <geliang.tang@suse.com>
+Signed-off-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20231025-send-net-next-20231025-v1-8-db8f25f798eb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 06afe09091ee ("mptcp: add userspace_pm_lookup_addr_by_id helper")
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c |   31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -185,6 +185,7 @@ int mptcp_nl_cmd_announce(struct sk_buff
+       struct mptcp_pm_addr_entry addr_val;
+       struct mptcp_sock *msk;
+       int err = -EINVAL;
++      struct sock *sk;
+       u32 token_val;
+       if (!addr || !token) {
+@@ -200,6 +201,8 @@ int mptcp_nl_cmd_announce(struct sk_buff
+               return err;
+       }
++      sk = (struct sock *)msk;
++
+       if (!mptcp_pm_is_userspace(msk)) {
+               GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
+               goto announce_err;
+@@ -223,7 +226,7 @@ int mptcp_nl_cmd_announce(struct sk_buff
+               goto announce_err;
+       }
+-      lock_sock((struct sock *)msk);
++      lock_sock(sk);
+       spin_lock_bh(&msk->pm.lock);
+       if (mptcp_pm_alloc_anno_list(msk, &addr_val.addr)) {
+@@ -233,11 +236,11 @@ int mptcp_nl_cmd_announce(struct sk_buff
+       }
+       spin_unlock_bh(&msk->pm.lock);
+-      release_sock((struct sock *)msk);
++      release_sock(sk);
+       err = 0;
+  announce_err:
+-      sock_put((struct sock *)msk);
++      sock_put(sk);
+       return err;
+ }
+@@ -284,6 +287,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+       struct mptcp_sock *msk;
+       LIST_HEAD(free_list);
+       int err = -EINVAL;
++      struct sock *sk;
+       u32 token_val;
+       u8 id_val;
+@@ -301,6 +305,8 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+               return err;
+       }
++      sk = (struct sock *)msk;
++
+       if (!mptcp_pm_is_userspace(msk)) {
+               GENL_SET_ERR_MSG(info, "invalid request; userspace PM not selected");
+               goto remove_err;
+@@ -311,7 +317,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+               goto remove_err;
+       }
+-      lock_sock((struct sock *)msk);
++      lock_sock(sk);
+       list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
+               if (entry->addr.id == id_val) {
+@@ -322,7 +328,7 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+       if (!match) {
+               GENL_SET_ERR_MSG(info, "address with specified id not found");
+-              release_sock((struct sock *)msk);
++              release_sock(sk);
+               goto remove_err;
+       }
+@@ -330,15 +336,15 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+       mptcp_pm_remove_addrs(msk, &free_list);
+-      release_sock((struct sock *)msk);
++      release_sock(sk);
+       list_for_each_entry_safe(match, entry, &free_list, list) {
+-              sock_kfree_s((struct sock *)msk, match, sizeof(*match));
++              sock_kfree_s(sk, match, sizeof(*match));
+       }
+       err = 0;
+  remove_err:
+-      sock_put((struct sock *)msk);
++      sock_put(sk);
+       return err;
+ }
+@@ -560,6 +566,7 @@ int mptcp_userspace_pm_set_flags(struct
+ {
+       struct mptcp_sock *msk;
+       int ret = -EINVAL;
++      struct sock *sk;
+       u32 token_val;
+       token_val = nla_get_u32(token);
+@@ -568,6 +575,8 @@ int mptcp_userspace_pm_set_flags(struct
+       if (!msk)
+               return ret;
++      sk = (struct sock *)msk;
++
+       if (!mptcp_pm_is_userspace(msk))
+               goto set_flags_err;
+@@ -575,11 +584,11 @@ int mptcp_userspace_pm_set_flags(struct
+           rem->addr.family == AF_UNSPEC)
+               goto set_flags_err;
+-      lock_sock((struct sock *)msk);
++      lock_sock(sk);
+       ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
+-      release_sock((struct sock *)msk);
++      release_sock(sk);
+ set_flags_err:
+-      sock_put((struct sock *)msk);
++      sock_put(sk);
+       return ret;
+ }
diff --git a/queue-6.1/mptcp-drop-lookup_by_id-in-lookup_addr.patch b/queue-6.1/mptcp-drop-lookup_by_id-in-lookup_addr.patch
new file mode 100644 (file)
index 0000000..faeff77
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-93941-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:48 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:54 +0100
+Subject: mptcp: drop lookup_by_id in lookup_addr
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <tanggeliang@kylinos.cn>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-15-matttbe@kernel.org>
+
+From: Geliang Tang <tanggeliang@kylinos.cn>
+
+commit af250c27ea1c404e210fc3a308b20f772df584d6 upstream.
+
+When the lookup_by_id parameter of __lookup_addr() is true, it's the same
+as __lookup_addr_by_id(), it can be replaced by __lookup_addr_by_id()
+directly. So drop this parameter, let __lookup_addr() only looks up address
+on the local address list by comparing addresses in it, not address ids.
+
+Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://lore.kernel.org/r/20240305-upstream-net-next-20240304-mptcp-misc-cleanup-v1-4-c436ba5e569b@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: db3eab8110bc ("mptcp: pm: use _rcu variant under rcu_read_lock")
+[ Conflicts in pm_netlink.c, because commit 6a42477fe449 ("mptcp: update
+  set_flags interfaces") is not in this version, and causes too many
+  conflicts when backporting it. The conflict is easy to resolve: addr
+  is a pointer here here in mptcp_pm_nl_set_flags(), the rest of the
+  code is the same. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -525,15 +525,12 @@ __lookup_addr_by_id(struct pm_nl_pernet
+ }
+ static struct mptcp_pm_addr_entry *
+-__lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info,
+-            bool lookup_by_id)
++__lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
+ {
+       struct mptcp_pm_addr_entry *entry;
+       list_for_each_entry(entry, &pernet->local_addr_list, list) {
+-              if ((!lookup_by_id &&
+-                   mptcp_addresses_equal(&entry->addr, info, entry->addr.port)) ||
+-                  (lookup_by_id && entry->addr.id == info->id))
++              if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
+                       return entry;
+       }
+       return NULL;
+@@ -564,7 +561,7 @@ static void mptcp_pm_create_subflow_or_s
+               mptcp_local_address((struct sock_common *)msk->first, &mpc_addr);
+               rcu_read_lock();
+-              entry = __lookup_addr(pernet, &mpc_addr, false);
++              entry = __lookup_addr(pernet, &mpc_addr);
+               if (entry) {
+                       __clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
+                       msk->mpc_endpoint_id = entry->addr.id;
+@@ -2081,7 +2078,8 @@ static int mptcp_nl_cmd_set_flags(struct
+                                                   token, &addr, &remote, bkup);
+       spin_lock_bh(&pernet->lock);
+-      entry = __lookup_addr(pernet, &addr.addr, lookup_by_id);
++      entry = lookup_by_id ? __lookup_addr_by_id(pernet, addr.addr.id) :
++                             __lookup_addr(pernet, &addr.addr);
+       if (!entry) {
+               spin_unlock_bh(&pernet->lock);
+               return -EINVAL;
diff --git a/queue-6.1/mptcp-hold-pm-lock-when-deleting-entry.patch b/queue-6.1/mptcp-hold-pm-lock-when-deleting-entry.patch
new file mode 100644 (file)
index 0000000..90c5a9a
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-93940-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:48 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:53 +0100
+Subject: mptcp: hold pm lock when deleting entry
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <tanggeliang@kylinos.cn>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-14-matttbe@kernel.org>
+
+From: Geliang Tang <tanggeliang@kylinos.cn>
+
+commit f642c5c4d528d11bd78b6c6f84f541cd3c0bea86 upstream.
+
+When traversing userspace_pm_local_addr_list and deleting an entry from
+it in mptcp_pm_nl_remove_doit(), msk->pm.lock should be held.
+
+This patch holds this lock before mptcp_userspace_pm_lookup_addr_by_id()
+and releases it after list_move() in mptcp_pm_nl_remove_doit().
+
+Fixes: d9a4594edabf ("mptcp: netlink: Add MPTCP_PM_CMD_REMOVE")
+Cc: stable@vger.kernel.org
+Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-2-b835580cefa8@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -326,14 +326,17 @@ int mptcp_nl_cmd_remove(struct sk_buff *
+       lock_sock(sk);
++      spin_lock_bh(&msk->pm.lock);
+       match = mptcp_userspace_pm_lookup_addr_by_id(msk, id_val);
+       if (!match) {
+               GENL_SET_ERR_MSG(info, "address with specified id not found");
++              spin_unlock_bh(&msk->pm.lock);
+               release_sock(sk);
+               goto remove_err;
+       }
+       list_move(&match->list, &free_list);
++      spin_unlock_bh(&msk->pm.lock);
+       mptcp_pm_remove_addrs(msk, &free_list);
diff --git a/queue-6.1/mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch b/queue-6.1/mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch
new file mode 100644 (file)
index 0000000..2f2f325
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-93942-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:52 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:55 +0100
+Subject: mptcp: pm: use _rcu variant under rcu_read_lock
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, sashal@kernel.org, Geliang Tang <geliang@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-16-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+commit db3eab8110bc0520416101b6a5b52f44a43fb4cf upstream.
+
+In mptcp_pm_create_subflow_or_signal_addr(), rcu_read_(un)lock() are
+used as expected to iterate over the list of local addresses, but
+list_for_each_entry() was used instead of list_for_each_entry_rcu() in
+__lookup_addr(). It is important to use this variant which adds the
+required READ_ONCE() (and diagnostic checks if enabled).
+
+Because __lookup_addr() is also used in mptcp_pm_nl_set_flags() where it
+is called under the pernet->lock and not rcu_read_lock(), an extra
+condition is then passed to help the diagnostic checks making sure
+either the associated spin lock or the RCU lock is held.
+
+Fixes: 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk")
+Cc: stable@vger.kernel.org
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-3-b835580cefa8@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -529,7 +529,8 @@ __lookup_addr(struct pm_nl_pernet *perne
+ {
+       struct mptcp_pm_addr_entry *entry;
+-      list_for_each_entry(entry, &pernet->local_addr_list, list) {
++      list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
++                              lockdep_is_held(&pernet->lock)) {
+               if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
+                       return entry;
+       }
diff --git a/queue-6.1/mptcp-update-local-address-flags-when-setting-it.patch b/queue-6.1/mptcp-update-local-address-flags-when-setting-it.patch
new file mode 100644 (file)
index 0000000..2432130
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-93939-greg=kroah.com@vger.kernel.org Tue Nov 19 09:36:47 2024
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 19 Nov 2024 09:35:52 +0100
+Subject: mptcp: update local address flags when setting it
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Geliang Tang <tanggeliang@kylinos.cn>, sashal@kernel.org, Matthieu Baerts <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20241119083547.3234013-13-matttbe@kernel.org>
+
+From: Geliang Tang <tanggeliang@kylinos.cn>
+
+commit e0266319413d5d687ba7b6df7ca99e4b9724a4f2 upstream.
+
+Just like in-kernel pm, when userspace pm does set_flags, it needs to send
+out MP_PRIO signal, and also modify the flags of the corresponding address
+entry in the local address list. This patch implements the missing logic.
+
+Traverse all address entries on userspace_pm_local_addr_list to find the
+local address entry, if bkup is true, set the flags of this entry with
+FLAG_BACKUP, otherwise, clear FLAG_BACKUP.
+
+Fixes: 892f396c8e68 ("mptcp: netlink: issue MP_PRIO signals from userspace PMs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-1-b835580cefa8@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflicts in pm_userspace.c, because commit 6a42477fe449 ("mptcp:
+  update set_flags interfaces"), is not in this version, and causes too
+  many conflicts when backporting it. The same code can still be added
+  at the same place, before sending the ACK. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_userspace.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -565,6 +565,7 @@ int mptcp_userspace_pm_set_flags(struct
+                                struct mptcp_pm_addr_entry *loc,
+                                struct mptcp_pm_addr_entry *rem, u8 bkup)
+ {
++      struct mptcp_pm_addr_entry *entry;
+       struct mptcp_sock *msk;
+       int ret = -EINVAL;
+       struct sock *sk;
+@@ -585,6 +586,17 @@ int mptcp_userspace_pm_set_flags(struct
+           rem->addr.family == AF_UNSPEC)
+               goto set_flags_err;
++      spin_lock_bh(&msk->pm.lock);
++      list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) {
++              if (mptcp_addresses_equal(&entry->addr, &loc->addr, false)) {
++                      if (bkup)
++                              entry->flags |= MPTCP_PM_ADDR_FLAG_BACKUP;
++                      else
++                              entry->flags &= ~MPTCP_PM_ADDR_FLAG_BACKUP;
++              }
++      }
++      spin_unlock_bh(&msk->pm.lock);
++
+       lock_sock(sk);
+       ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup);
+       release_sock(sk);
diff --git a/queue-6.1/net-add-copy_safe_from_sockptr-helper.patch b/queue-6.1/net-add-copy_safe_from_sockptr-helper.patch
new file mode 100644 (file)
index 0000000..69e73c3
--- /dev/null
@@ -0,0 +1,86 @@
+From stable+bounces-93889-greg=kroah.com@vger.kernel.org Tue Nov 19 03:06:03 2024
+From: Xiangyu Chen <xiangyu.chen@eng.windriver.com>
+Date: Tue, 19 Nov 2024 10:05:36 +0800
+Subject: net: add copy_safe_from_sockptr() helper
+To: edumazet@google.com, gregkh@linuxfoundation.org
+Cc: stable@vger.kernel.org, xiangyu.chen@aol.com
+Message-ID: <20241119020537.3050784-2-xiangyu.chen@eng.windriver.com>
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 6309863b31dd80317cd7d6824820b44e254e2a9c ]
+
+copy_from_sockptr() helper is unsafe, unless callers
+did the prior check against user provided optlen.
+
+Too many callers get this wrong, lets add a helper to
+fix them and avoid future copy/paste bugs.
+
+Instead of :
+
+   if (optlen < sizeof(opt)) {
+       err = -EINVAL;
+       break;
+   }
+   if (copy_from_sockptr(&opt, optval, sizeof(opt)) {
+       err = -EFAULT;
+       break;
+   }
+
+Use :
+
+   err = copy_safe_from_sockptr(&opt, sizeof(opt),
+                                optval, optlen);
+   if (err)
+       break;
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20240408082845.3957374-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 7a87441c9651 ("nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/sockptr.h |   25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/include/linux/sockptr.h
++++ b/include/linux/sockptr.h
+@@ -50,11 +50,36 @@ static inline int copy_from_sockptr_offs
+       return 0;
+ }
++/* Deprecated.
++ * This is unsafe, unless caller checked user provided optlen.
++ * Prefer copy_safe_from_sockptr() instead.
++ */
+ static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size)
+ {
+       return copy_from_sockptr_offset(dst, src, 0, size);
+ }
++/**
++ * copy_safe_from_sockptr: copy a struct from sockptr
++ * @dst:   Destination address, in kernel space. This buffer must be @ksize
++ *         bytes long.
++ * @ksize: Size of @dst struct.
++ * @optval: Source address. (in user or kernel space)
++ * @optlen: Size of @optval data.
++ *
++ * Returns:
++ *  * -EINVAL: @optlen < @ksize
++ *  * -EFAULT: access to userspace failed.
++ *  * 0 : @ksize bytes were copied
++ */
++static inline int copy_safe_from_sockptr(void *dst, size_t ksize,
++                                       sockptr_t optval, unsigned int optlen)
++{
++      if (optlen < ksize)
++              return -EINVAL;
++      return copy_from_sockptr(dst, optval, ksize);
++}
++
+ static inline int copy_to_sockptr_offset(sockptr_t dst, size_t offset,
+               const void *src, size_t size)
+ {
diff --git a/queue-6.1/nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch b/queue-6.1/nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch
new file mode 100644 (file)
index 0000000..5b6cb0e
--- /dev/null
@@ -0,0 +1,93 @@
+From stable+bounces-93890-greg=kroah.com@vger.kernel.org Tue Nov 19 03:06:01 2024
+From: Xiangyu Chen <xiangyu.chen@eng.windriver.com>
+Date: Tue, 19 Nov 2024 10:05:37 +0800
+Subject: nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies
+To: edumazet@google.com, gregkh@linuxfoundation.org
+Cc: stable@vger.kernel.org, xiangyu.chen@aol.com
+Message-ID: <20241119020537.3050784-3-xiangyu.chen@eng.windriver.com>
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 7a87441c9651ba37842f4809224aca13a554a26f ]
+
+syzbot reported unsafe calls to copy_from_sockptr() [1]
+
+Use copy_safe_from_sockptr() instead.
+
+[1]
+
+BUG: KASAN: slab-out-of-bounds in copy_from_sockptr_offset include/linux/sockptr.h:49 [inline]
+ BUG: KASAN: slab-out-of-bounds in copy_from_sockptr include/linux/sockptr.h:55 [inline]
+ BUG: KASAN: slab-out-of-bounds in nfc_llcp_setsockopt+0x6c2/0x850 net/nfc/llcp_sock.c:255
+Read of size 4 at addr ffff88801caa1ec3 by task syz-executor459/5078
+
+CPU: 0 PID: 5078 Comm: syz-executor459 Not tainted 6.8.0-syzkaller-08951-gfe46a7dd189e #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
+Call Trace:
+ <TASK>
+  __dump_stack lib/dump_stack.c:88 [inline]
+  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
+  print_address_description mm/kasan/report.c:377 [inline]
+  print_report+0x169/0x550 mm/kasan/report.c:488
+  kasan_report+0x143/0x180 mm/kasan/report.c:601
+  copy_from_sockptr_offset include/linux/sockptr.h:49 [inline]
+  copy_from_sockptr include/linux/sockptr.h:55 [inline]
+  nfc_llcp_setsockopt+0x6c2/0x850 net/nfc/llcp_sock.c:255
+  do_sock_setsockopt+0x3b1/0x720 net/socket.c:2311
+  __sys_setsockopt+0x1ae/0x250 net/socket.c:2334
+  __do_sys_setsockopt net/socket.c:2343 [inline]
+  __se_sys_setsockopt net/socket.c:2340 [inline]
+  __x64_sys_setsockopt+0xb5/0xd0 net/socket.c:2340
+ do_syscall_64+0xfd/0x240
+ entry_SYSCALL_64_after_hwframe+0x6d/0x75
+RIP: 0033:0x7f7fac07fd89
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 91 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fff660eb788 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
+RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f7fac07fd89
+RDX: 0000000000000000 RSI: 0000000000000118 RDI: 0000000000000004
+RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000000
+R10: 0000000020000a80 R11: 0000000000000246 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20240408082845.3957374-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/nfc/llcp_sock.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -252,10 +252,10 @@ static int nfc_llcp_setsockopt(struct so
+                       break;
+               }
+-              if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
+-                      err = -EFAULT;
++              err = copy_safe_from_sockptr(&opt, sizeof(opt),
++                                           optval, optlen);
++              if (err)
+                       break;
+-              }
+               if (opt > LLCP_MAX_RW) {
+                       err = -EINVAL;
+@@ -274,10 +274,10 @@ static int nfc_llcp_setsockopt(struct so
+                       break;
+               }
+-              if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
+-                      err = -EFAULT;
++              err = copy_safe_from_sockptr(&opt, sizeof(opt),
++                                           optval, optlen);
++              if (err)
+                       break;
+-              }
+               if (opt > LLCP_MAX_MIUX) {
+                       err = -EINVAL;
index 327baf98b64855a9aae27e5a225ce9cc43820f74..978438ba32b2edd1a09231664468c633562905d3 100644 (file)
@@ -43,3 +43,15 @@ nfsd-async-copy-result-needs-to-return-a-write-verifier.patch
 nfsd-limit-the-number-of-concurrent-async-copy-operations.patch
 nfsd-initialize-struct-nfsd4_copy-earlier.patch
 nfsd-never-decrement-pending_async_copies-on-error.patch
+mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch
+mptcp-define-more-local-variables-sk.patch
+mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch
+mptcp-update-local-address-flags-when-setting-it.patch
+mptcp-hold-pm-lock-when-deleting-entry.patch
+mptcp-drop-lookup_by_id-in-lookup_addr.patch
+mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch
+ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch
+ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch
+net-add-copy_safe_from_sockptr-helper.patch
+nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch
+fs-9p-fix-uninitialized-values-during-inode-evict.patch