From: Greg Kroah-Hartman Date: Tue, 19 Nov 2024 13:12:45 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v6.12.1~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6da5ae1997486ba8084c827a7120f83a5ce7763;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches 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 --- 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 index 00000000000..b14a1e6afb3 --- /dev/null +++ b/queue-6.1/fs-9p-fix-uninitialized-values-during-inode-evict.patch @@ -0,0 +1,67 @@ +From stable+bounces-93895-greg=kroah.com@vger.kernel.org Tue Nov 19 04:43:37 2024 +From: Xiangyu Chen +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 + +[ 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 +(cherry picked from commit 1b4cb6e91f19b81217ad98142ee53a1ab25893fd) +[Xiangyu: CVE-2024-36923 Minor conflict resolution due to missing 4eb31178 ] +Signed-off-by: Xiangyu Chen +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b6cff10d3d6 --- /dev/null +++ b/queue-6.1/ksmbd-fix-potencial-out-of-bounds-when-buffer-offset-is-invalid.patch @@ -0,0 +1,311 @@ +From c6cd2e8d2d9aa7ee35b1fa6a668e32a22a9753da Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Tue, 19 Mar 2024 08:40:48 +0900 +Subject: ksmbd: fix potencial out-of-bounds when buffer offset is invalid + +From: Namjae Jeon + +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 +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +Signed-off-by: Vamsi Krishna Brahmajosyula +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..b0a552c09c7 --- /dev/null +++ b/queue-6.1/ksmbd-fix-slab-out-of-bounds-in-smb_strndup_from_utf16.patch @@ -0,0 +1,39 @@ +From a80a486d72e20bd12c335bcd38b6e6f19356b0aa Mon Sep 17 00:00:00 2001 +From: Namjae Jeon +Date: Sat, 16 Mar 2024 23:36:36 +0900 +Subject: ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16() + +From: Namjae Jeon + +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 +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: c6cd2e8d2d9a ("ksmbd: fix potencial out-of-bounds when buffer offset is invalid") +Signed-off-by: Vamsi Krishna Brahmajosyula +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..99583c360d0 --- /dev/null +++ b/queue-6.1/mptcp-add-userspace_pm_lookup_addr_by_id-helper.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Mat Martineau , "David S . Miller" +Message-ID: <20241119083547.3234013-12-matttbe@kernel.org> + +From: Geliang Tang + +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 +Reviewed-by: Matthieu Baerts (NGI0) +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: David S. Miller +Stable-dep-of: f642c5c4d528 ("mptcp: hold pm lock when deleting entry") +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..de4789027eb --- /dev/null +++ b/queue-6.1/mptcp-cope-racing-subflow-creation-in-mptcp_rcv_space_adjust.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Jakub Kicinski +Message-ID: <20241119083547.3234013-10-matttbe@kernel.org> + +From: Paolo Abeni + +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 +Reviewed-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/02374660836e1b52afc91966b7535c8c5f7bafb0.1731060874.git.pabeni@redhat.com +Signed-off-by: Jakub Kicinski +[ 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) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..317fb9a153d --- /dev/null +++ b/queue-6.1/mptcp-define-more-local-variables-sk.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Mat Martineau , Jakub Kicinski +Message-ID: <20241119083547.3234013-11-matttbe@kernel.org> + +From: Geliang Tang + +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 +Signed-off-by: Geliang Tang +Signed-off-by: Mat Martineau +Link: https://lore.kernel.org/r/20231025-send-net-next-20231025-v1-8-db8f25f798eb@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 06afe09091ee ("mptcp: add userspace_pm_lookup_addr_by_id helper") +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..faeff7788e2 --- /dev/null +++ b/queue-6.1/mptcp-drop-lookup_by_id-in-lookup_addr.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Jakub Kicinski +Message-ID: <20241119083547.3234013-15-matttbe@kernel.org> + +From: Geliang Tang + +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 +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://lore.kernel.org/r/20240305-upstream-net-next-20240304-mptcp-misc-cleanup-v1-4-c436ba5e569b@kernel.org +Signed-off-by: Jakub Kicinski +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) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..90c5a9a1cbf --- /dev/null +++ b/queue-6.1/mptcp-hold-pm-lock-when-deleting-entry.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Jakub Kicinski +Message-ID: <20241119083547.3234013-14-matttbe@kernel.org> + +From: Geliang Tang + +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 +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-2-b835580cefa8@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..2f2f3251495 --- /dev/null +++ b/queue-6.1/mptcp-pm-use-_rcu-variant-under-rcu_read_lock.patch @@ -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)" +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)" , sashal@kernel.org, Geliang Tang , Jakub Kicinski +Message-ID: <20241119083547.3234013-16-matttbe@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +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 +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-3-b835580cefa8@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Matthieu Baerts (NGI0) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..243213061d4 --- /dev/null +++ b/queue-6.1/mptcp-update-local-address-flags-when-setting-it.patch @@ -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)" +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 , sashal@kernel.org, Matthieu Baerts , Jakub Kicinski +Message-ID: <20241119083547.3234013-13-matttbe@kernel.org> + +From: Geliang Tang + +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 +Reviewed-by: Matthieu Baerts (NGI0) +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20241112-net-mptcp-misc-6-12-pm-v1-1-b835580cefa8@kernel.org +Signed-off-by: Jakub Kicinski +[ 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) +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..69e73c3c615 --- /dev/null +++ b/queue-6.1/net-add-copy_safe_from_sockptr-helper.patch @@ -0,0 +1,86 @@ +From stable+bounces-93889-greg=kroah.com@vger.kernel.org Tue Nov 19 03:06:03 2024 +From: Xiangyu Chen +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 + +[ 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 +Link: https://lore.kernel.org/r/20240408082845.3957374-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 7a87441c9651 ("nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies") +Signed-off-by: Sasha Levin +Signed-off-by: Xiangyu Chen +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..5b6cb0ebaf4 --- /dev/null +++ b/queue-6.1/nfc-llcp-fix-nfc_llcp_setsockopt-unsafe-copies.patch @@ -0,0 +1,93 @@ +From stable+bounces-93890-greg=kroah.com@vger.kernel.org Tue Nov 19 03:06:01 2024 +From: Xiangyu Chen +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 + +[ 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: + + __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 +Reported-by: syzbot +Reviewed-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20240408082845.3957374-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +Signed-off-by: Xiangyu Chen +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.1/series b/queue-6.1/series index 327baf98b64..978438ba32b 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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