diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 02:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 02:21:44 +0000 |
commit | cd65511a2c0c1892e5e83fe110f3a1eebdc10ba6 (patch) | |
tree | 039a11a456a0b5140fd615884a20b09a90a8de64 /debian/patches/bugfix/all | |
parent | Merging upstream version 6.1.90. (diff) | |
download | linux-cd65511a2c0c1892e5e83fe110f3a1eebdc10ba6.tar.xz linux-cd65511a2c0c1892e5e83fe110f3a1eebdc10ba6.zip |
Merging debian version 6.1.90-1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/bugfix/all')
6 files changed, 179 insertions, 513 deletions
diff --git a/debian/patches/bugfix/all/Revert-scsi-core-Add-struct-for-args-to-execution-fu.patch b/debian/patches/bugfix/all/Revert-scsi-core-Add-struct-for-args-to-execution-fu.patch deleted file mode 100644 index 5e77d7985..000000000 --- a/debian/patches/bugfix/all/Revert-scsi-core-Add-struct-for-args-to-execution-fu.patch +++ /dev/null @@ -1,198 +0,0 @@ -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 11 Apr 2024 09:26:49 +0200 -Subject: Revert "scsi: core: Add struct for args to execution functions" -Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=d1e620297a84caac1cd67615f4f4f6901527ca2b - -This reverts commit cf33e6ca12d814e1be2263cb76960d0019d7fb94 which is -commit d0949565811f0896c1c7e781ab2ad99d34273fdf upstream. - -It is known to cause problems and has asked to be dropped. - -Link: https://lore.kernel.org/r/yq1frvvpymp.fsf@ca-mkp.ca.oracle.com -Cc: Tasos Sahanidis <tasos@tasossah.com> -Cc: Ewan D. Milne <emilne@redhat.com> -Cc: Bart Van Assche <bvanassche@acm.org> -Cc: Tasos Sahanidis <tasos@tasossah.com> -Cc: Martin K. Petersen <martin.petersen@oracle.com> -Cc: James Bottomley <jejb@linux.ibm.com> -Cc: Sasha Levin <sashal@kernel.org> -Reported-by: John David Anglin <dave.anglin@bell.net> -Reported-by: Cyril Brulebois <kibi@debian.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/scsi/scsi_lib.c | 52 ++++++++++++++++++++------------------ - include/scsi/scsi_device.h | 51 ++++++++++--------------------------- - 2 files changed, 41 insertions(+), 62 deletions(-) - -diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c -index edd296f950a3..5c5954b78585 100644 ---- a/drivers/scsi/scsi_lib.c -+++ b/drivers/scsi/scsi_lib.c -@@ -185,37 +185,39 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) - __scsi_queue_insert(cmd, reason, true); - } - -+ - /** -- * scsi_execute_cmd - insert request and wait for the result -- * @sdev: scsi_device -+ * __scsi_execute - insert request and wait for the result -+ * @sdev: scsi device - * @cmd: scsi command -- * @opf: block layer request cmd_flags -+ * @data_direction: data direction - * @buffer: data buffer - * @bufflen: len of buffer -+ * @sense: optional sense buffer -+ * @sshdr: optional decoded sense header - * @timeout: request timeout in HZ - * @retries: number of times to retry request -- * @args: Optional args. See struct definition for field descriptions -+ * @flags: flags for ->cmd_flags -+ * @rq_flags: flags for ->rq_flags -+ * @resid: optional residual length - * - * Returns the scsi_cmnd result field if a command was executed, or a negative - * Linux error code if we didn't get that far. - */ --int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, -- blk_opf_t opf, void *buffer, unsigned int bufflen, -- int timeout, int retries, -- const struct scsi_exec_args *args) -+int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, -+ int data_direction, void *buffer, unsigned bufflen, -+ unsigned char *sense, struct scsi_sense_hdr *sshdr, -+ int timeout, int retries, blk_opf_t flags, -+ req_flags_t rq_flags, int *resid) - { -- static const struct scsi_exec_args default_args; - struct request *req; - struct scsi_cmnd *scmd; - int ret; - -- if (!args) -- args = &default_args; -- else if (WARN_ON_ONCE(args->sense && -- args->sense_len != SCSI_SENSE_BUFFERSIZE)) -- return -EINVAL; -- -- req = scsi_alloc_request(sdev->request_queue, opf, args->req_flags); -+ req = scsi_alloc_request(sdev->request_queue, -+ data_direction == DMA_TO_DEVICE ? -+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN, -+ rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); - if (IS_ERR(req)) - return PTR_ERR(req); - -@@ -230,7 +232,8 @@ int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, - memcpy(scmd->cmnd, cmd, scmd->cmd_len); - scmd->allowed = retries; - req->timeout = timeout; -- req->rq_flags |= RQF_QUIET; -+ req->cmd_flags |= flags; -+ req->rq_flags |= rq_flags | RQF_QUIET; - - /* - * head injection *required* here otherwise quiesce won't work -@@ -246,21 +249,20 @@ int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, - if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) - memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); - -- if (args->resid) -- *args->resid = scmd->resid_len; -- if (args->sense) -- memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -- if (args->sshdr) -+ if (resid) -+ *resid = scmd->resid_len; -+ if (sense && scmd->sense_len) -+ memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); -+ if (sshdr) - scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, -- args->sshdr); -- -+ sshdr); - ret = scmd->result; - out: - blk_mq_free_request(req); - - return ret; - } --EXPORT_SYMBOL(scsi_execute_cmd); -+EXPORT_SYMBOL(__scsi_execute); - - /* - * Wake up the error handler if necessary. Avoid as follows that the error -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index b407807cc669..d2751ed536df 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -479,51 +479,28 @@ extern const char *scsi_device_state_name(enum scsi_device_state); - extern int scsi_is_sdev_device(const struct device *); - extern int scsi_is_target_device(const struct device *); - extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); -- --/* Optional arguments to scsi_execute_cmd */ --struct scsi_exec_args { -- unsigned char *sense; /* sense buffer */ -- unsigned int sense_len; /* sense buffer len */ -- struct scsi_sense_hdr *sshdr; /* decoded sense header */ -- blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */ -- int *resid; /* residual length */ --}; -- --int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd, -- blk_opf_t opf, void *buffer, unsigned int bufflen, -- int timeout, int retries, -- const struct scsi_exec_args *args); -- -+extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, -+ int data_direction, void *buffer, unsigned bufflen, -+ unsigned char *sense, struct scsi_sense_hdr *sshdr, -+ int timeout, int retries, blk_opf_t flags, -+ req_flags_t rq_flags, int *resid); - /* Make sure any sense buffer is the correct size. */ --#define scsi_execute(_sdev, _cmd, _data_dir, _buffer, _bufflen, _sense, \ -- _sshdr, _timeout, _retries, _flags, _rq_flags, \ -- _resid) \ -+#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ -+ sshdr, timeout, retries, flags, rq_flags, resid) \ - ({ \ -- scsi_execute_cmd(_sdev, _cmd, (_data_dir == DMA_TO_DEVICE ? \ -- REQ_OP_DRV_OUT : REQ_OP_DRV_IN) | _flags, \ -- _buffer, _bufflen, _timeout, _retries, \ -- &(struct scsi_exec_args) { \ -- .sense = _sense, \ -- .sshdr = _sshdr, \ -- .req_flags = _rq_flags & RQF_PM ? \ -- BLK_MQ_REQ_PM : 0, \ -- .resid = _resid, \ -- }); \ -+ BUILD_BUG_ON((sense) != NULL && \ -+ sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \ -+ __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \ -+ sense, sshdr, timeout, retries, flags, rq_flags, \ -+ resid); \ - }) -- - static inline int scsi_execute_req(struct scsi_device *sdev, - const unsigned char *cmd, int data_direction, void *buffer, - unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, - int retries, int *resid) - { -- return scsi_execute_cmd(sdev, cmd, -- data_direction == DMA_TO_DEVICE ? -- REQ_OP_DRV_OUT : REQ_OP_DRV_IN, buffer, -- bufflen, timeout, retries, -- &(struct scsi_exec_args) { -- .sshdr = sshdr, -- .resid = resid, -- }); -+ return scsi_execute(sdev, cmd, data_direction, buffer, -+ bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); - } - extern void sdev_disable_disk_events(struct scsi_device *sdev); - extern void sdev_enable_disk_events(struct scsi_device *sdev); --- -2.43.0 - diff --git a/debian/patches/bugfix/all/Revert-scsi-sd-usb_storage-uas-Access-media-prior-to.patch b/debian/patches/bugfix/all/Revert-scsi-sd-usb_storage-uas-Access-media-prior-to.patch deleted file mode 100644 index 2b03fad36..000000000 --- a/debian/patches/bugfix/all/Revert-scsi-sd-usb_storage-uas-Access-media-prior-to.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 11 Apr 2024 09:24:48 +0200 -Subject: Revert "scsi: sd: usb_storage: uas: Access media prior to querying - device properties" -Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=fc7309d7c76e446d7804fcc075da53694cecd755 -Bug-Debian: https://bugs.debian.org/1068675 - -This reverts commit b73dd5f9997279715cd450ee8ca599aaff2eabb9 which is -commit 321da3dc1f3c92a12e3c5da934090d2992a8814c upstream. - -It is known to cause problems and has asked to be dropped. - -Link: https://lore.kernel.org/r/yq1frvvpymp.fsf@ca-mkp.ca.oracle.com -Cc: Tasos Sahanidis <tasos@tasossah.com> -Cc: Ewan D. Milne <emilne@redhat.com> -Cc: Bart Van Assche <bvanassche@acm.org> -Cc: Tasos Sahanidis <tasos@tasossah.com> -Cc: Martin K. Petersen <martin.petersen@oracle.com> -Cc: James Bottomley <jejb@linux.ibm.com> -Cc: Sasha Levin <sashal@kernel.org> -Reported-by: John David Anglin <dave.anglin@bell.net> -Reported-by: Cyril Brulebois <kibi@debian.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/scsi/sd.c | 26 +------------------------- - drivers/usb/storage/scsiglue.c | 7 ------- - drivers/usb/storage/uas.c | 7 ------- - include/scsi/scsi_device.h | 1 - - 4 files changed, 1 insertion(+), 40 deletions(-) - -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index f32236c3f81c..ad619f7c7418 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -3286,24 +3286,6 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, - return true; - } - --static void sd_read_block_zero(struct scsi_disk *sdkp) --{ -- unsigned int buf_len = sdkp->device->sector_size; -- char *buffer, cmd[10] = { }; -- -- buffer = kmalloc(buf_len, GFP_KERNEL); -- if (!buffer) -- return; -- -- cmd[0] = READ_10; -- put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */ -- put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */ -- -- scsi_execute_cmd(sdkp->device, cmd, REQ_OP_DRV_IN, buffer, buf_len, -- SD_TIMEOUT, sdkp->max_retries, NULL); -- kfree(buffer); --} -- - /** - * sd_revalidate_disk - called the first time a new disk is seen, - * performs disk spin up, read_capacity, etc. -@@ -3343,13 +3325,7 @@ static int sd_revalidate_disk(struct gendisk *disk) - */ - if (sdkp->media_present) { - sd_read_capacity(sdkp, buffer); -- /* -- * Some USB/UAS devices return generic values for mode pages -- * until the media has been accessed. Trigger a READ operation -- * to force the device to populate mode pages. -- */ -- if (sdp->read_before_ms) -- sd_read_block_zero(sdkp); -+ - /* - * set the default to rotational. All non-rotational devices - * support the block characteristics VPD page, which will -diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c -index 12cf9940e5b6..c54e9805da53 100644 ---- a/drivers/usb/storage/scsiglue.c -+++ b/drivers/usb/storage/scsiglue.c -@@ -179,13 +179,6 @@ static int slave_configure(struct scsi_device *sdev) - */ - sdev->use_192_bytes_for_3f = 1; - -- /* -- * Some devices report generic values until the media has been -- * accessed. Force a READ(10) prior to querying device -- * characteristics. -- */ -- sdev->read_before_ms = 1; -- - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c -index af619efe8eab..ee5621bdb11e 100644 ---- a/drivers/usb/storage/uas.c -+++ b/drivers/usb/storage/uas.c -@@ -876,13 +876,6 @@ static int uas_slave_configure(struct scsi_device *sdev) - if (devinfo->flags & US_FL_CAPACITY_HEURISTICS) - sdev->guess_capacity = 1; - -- /* -- * Some devices report generic values until the media has been -- * accessed. Force a READ(10) prior to querying device -- * characteristics. -- */ -- sdev->read_before_ms = 1; -- - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index a64713fe5264..b407807cc669 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -204,7 +204,6 @@ struct scsi_device { - unsigned use_10_for_rw:1; /* first try 10-byte read / write */ - unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ - unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ -- unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ - unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ - unsigned no_write_same:1; /* no WRITE SAME command */ - unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ --- -2.43.0 - diff --git a/debian/patches/bugfix/all/scsi-sd-usb_storage-uas-Access-media-prior-to-queryi.patch b/debian/patches/bugfix/all/scsi-sd-usb_storage-uas-Access-media-prior-to-queryi.patch deleted file mode 100644 index c59abc9f8..000000000 --- a/debian/patches/bugfix/all/scsi-sd-usb_storage-uas-Access-media-prior-to-queryi.patch +++ /dev/null @@ -1,155 +0,0 @@ -From: "Martin K. Petersen" <martin.petersen@oracle.com> -Date: Tue, 13 Feb 2024 09:33:06 -0500 -Subject: scsi: sd: usb_storage: uas: Access media prior to querying device - properties -Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=46e587855c060a0fdcbb4349accb62b31e9ce70f - -[ Upstream commit 321da3dc1f3c92a12e3c5da934090d2992a8814c ] - -It has been observed that some USB/UAS devices return generic properties -hardcoded in firmware for mode pages for a period of time after a device -has been discovered. The reported properties are either garbage or they do -not accurately reflect the characteristics of the physical storage device -attached in the case of a bridge. - -Prior to commit 1e029397d12f ("scsi: sd: Reorganize DIF/DIX code to -avoid calling revalidate twice") we would call revalidate several -times during device discovery. As a result, incorrect values would -eventually get replaced with ones accurately describing the attached -storage. When we did away with the redundant revalidate pass, several -cases were reported where devices reported nonsensical values or would -end up in write-protected state. - -An initial attempt at addressing this issue involved introducing a -delayed second revalidate invocation. However, this approach still -left some devices reporting incorrect characteristics. - -Tasos Sahanidis debugged the problem further and identified that -introducing a READ operation prior to MODE SENSE fixed the problem and that -it wasn't a timing issue. Issuing a READ appears to cause the devices to -update their state to reflect the actual properties of the storage -media. Device properties like vendor, model, and storage capacity appear to -be correctly reported from the get-go. It is unclear why these devices -defer populating the remaining characteristics. - -Match the behavior of a well known commercial operating system and -trigger a READ operation prior to querying device characteristics to -force the device to populate the mode pages. - -The additional READ is triggered by a flag set in the USB storage and -UAS drivers. We avoid issuing the READ for other transport classes -since some storage devices identify Linux through our particular -discovery command sequence. - -Link: https://lore.kernel.org/r/20240213143306.2194237-1-martin.petersen@oracle.com -Fixes: 1e029397d12f ("scsi: sd: Reorganize DIF/DIX code to avoid calling revalidate twice") -Cc: stable@vger.kernel.org -Reported-by: Tasos Sahanidis <tasos@tasossah.com> -Reviewed-by: Ewan D. Milne <emilne@redhat.com> -Reviewed-by: Bart Van Assche <bvanassche@acm.org> -Tested-by: Tasos Sahanidis <tasos@tasossah.com> -Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> -Signed-off-by: Sasha Levin <sashal@kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/scsi/sd.c | 26 +++++++++++++++++++++++++- - drivers/usb/storage/scsiglue.c | 7 +++++++ - drivers/usb/storage/uas.c | 7 +++++++ - include/scsi/scsi_device.h | 1 + - 4 files changed, 40 insertions(+), 1 deletion(-) - -diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index ad619f7c7418..3ec9b324fdcf 100644 ---- a/drivers/scsi/sd.c -+++ b/drivers/scsi/sd.c -@@ -3286,6 +3286,24 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, - return true; - } - -+static void sd_read_block_zero(struct scsi_disk *sdkp) -+{ -+ unsigned int buf_len = sdkp->device->sector_size; -+ char *buffer, cmd[10] = { }; -+ -+ buffer = kmalloc(buf_len, GFP_KERNEL); -+ if (!buffer) -+ return; -+ -+ cmd[0] = READ_10; -+ put_unaligned_be32(0, &cmd[2]); /* Logical block address 0 */ -+ put_unaligned_be16(1, &cmd[7]); /* Transfer 1 logical block */ -+ -+ scsi_execute_req(sdkp->device, cmd, DMA_FROM_DEVICE, buffer, buf_len, -+ NULL, SD_TIMEOUT, sdkp->max_retries, NULL); -+ kfree(buffer); -+} -+ - /** - * sd_revalidate_disk - called the first time a new disk is seen, - * performs disk spin up, read_capacity, etc. -@@ -3325,7 +3343,13 @@ static int sd_revalidate_disk(struct gendisk *disk) - */ - if (sdkp->media_present) { - sd_read_capacity(sdkp, buffer); -- -+ /* -+ * Some USB/UAS devices return generic values for mode pages -+ * until the media has been accessed. Trigger a READ operation -+ * to force the device to populate mode pages. -+ */ -+ if (sdp->read_before_ms) -+ sd_read_block_zero(sdkp); - /* - * set the default to rotational. All non-rotational devices - * support the block characteristics VPD page, which will -diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c -index c54e9805da53..12cf9940e5b6 100644 ---- a/drivers/usb/storage/scsiglue.c -+++ b/drivers/usb/storage/scsiglue.c -@@ -179,6 +179,13 @@ static int slave_configure(struct scsi_device *sdev) - */ - sdev->use_192_bytes_for_3f = 1; - -+ /* -+ * Some devices report generic values until the media has been -+ * accessed. Force a READ(10) prior to querying device -+ * characteristics. -+ */ -+ sdev->read_before_ms = 1; -+ - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c -index ee5621bdb11e..af619efe8eab 100644 ---- a/drivers/usb/storage/uas.c -+++ b/drivers/usb/storage/uas.c -@@ -876,6 +876,13 @@ static int uas_slave_configure(struct scsi_device *sdev) - if (devinfo->flags & US_FL_CAPACITY_HEURISTICS) - sdev->guess_capacity = 1; - -+ /* -+ * Some devices report generic values until the media has been -+ * accessed. Force a READ(10) prior to querying device -+ * characteristics. -+ */ -+ sdev->read_before_ms = 1; -+ - /* - * Some devices don't like MODE SENSE with page=0x3f, - * which is the command used for checking if a device -diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h -index d2751ed536df..1504d3137cc6 100644 ---- a/include/scsi/scsi_device.h -+++ b/include/scsi/scsi_device.h -@@ -204,6 +204,7 @@ struct scsi_device { - unsigned use_10_for_rw:1; /* first try 10-byte read / write */ - unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ - unsigned set_dbd_for_ms:1; /* Set "DBD" field in mode sense */ -+ unsigned read_before_ms:1; /* perform a READ before MODE SENSE */ - unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ - unsigned no_write_same:1; /* no WRITE SAME command */ - unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ --- -2.43.0 - diff --git a/debian/patches/bugfix/all/tipc-fix-UAF-in-error-path.patch b/debian/patches/bugfix/all/tipc-fix-UAF-in-error-path.patch new file mode 100644 index 000000000..b21318ecc --- /dev/null +++ b/debian/patches/bugfix/all/tipc-fix-UAF-in-error-path.patch @@ -0,0 +1,141 @@ +From: Paolo Abeni <pabeni@redhat.com> +Date: Tue, 30 Apr 2024 15:53:37 +0200 +Subject: tipc: fix UAF in error path +Origin: https://git.kernel.org/linus/080cbb890286cd794f1ee788bbc5463e2deb7c2b + +Sam Page (sam4k) working with Trend Micro Zero Day Initiative reported +a UAF in the tipc_buf_append() error path: + +BUG: KASAN: slab-use-after-free in kfree_skb_list_reason+0x47e/0x4c0 +linux/net/core/skbuff.c:1183 +Read of size 8 at addr ffff88804d2a7c80 by task poc/8034 + +CPU: 1 PID: 8034 Comm: poc Not tainted 6.8.2 #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.16.0-debian-1.16.0-5 04/01/2014 +Call Trace: + <IRQ> + __dump_stack linux/lib/dump_stack.c:88 + dump_stack_lvl+0xd9/0x1b0 linux/lib/dump_stack.c:106 + print_address_description linux/mm/kasan/report.c:377 + print_report+0xc4/0x620 linux/mm/kasan/report.c:488 + kasan_report+0xda/0x110 linux/mm/kasan/report.c:601 + kfree_skb_list_reason+0x47e/0x4c0 linux/net/core/skbuff.c:1183 + skb_release_data+0x5af/0x880 linux/net/core/skbuff.c:1026 + skb_release_all linux/net/core/skbuff.c:1094 + __kfree_skb linux/net/core/skbuff.c:1108 + kfree_skb_reason+0x12d/0x210 linux/net/core/skbuff.c:1144 + kfree_skb linux/./include/linux/skbuff.h:1244 + tipc_buf_append+0x425/0xb50 linux/net/tipc/msg.c:186 + tipc_link_input+0x224/0x7c0 linux/net/tipc/link.c:1324 + tipc_link_rcv+0x76e/0x2d70 linux/net/tipc/link.c:1824 + tipc_rcv+0x45f/0x10f0 linux/net/tipc/node.c:2159 + tipc_udp_recv+0x73b/0x8f0 linux/net/tipc/udp_media.c:390 + udp_queue_rcv_one_skb+0xad2/0x1850 linux/net/ipv4/udp.c:2108 + udp_queue_rcv_skb+0x131/0xb00 linux/net/ipv4/udp.c:2186 + udp_unicast_rcv_skb+0x165/0x3b0 linux/net/ipv4/udp.c:2346 + __udp4_lib_rcv+0x2594/0x3400 linux/net/ipv4/udp.c:2422 + ip_protocol_deliver_rcu+0x30c/0x4e0 linux/net/ipv4/ip_input.c:205 + ip_local_deliver_finish+0x2e4/0x520 linux/net/ipv4/ip_input.c:233 + NF_HOOK linux/./include/linux/netfilter.h:314 + NF_HOOK linux/./include/linux/netfilter.h:308 + ip_local_deliver+0x18e/0x1f0 linux/net/ipv4/ip_input.c:254 + dst_input linux/./include/net/dst.h:461 + ip_rcv_finish linux/net/ipv4/ip_input.c:449 + NF_HOOK linux/./include/linux/netfilter.h:314 + NF_HOOK linux/./include/linux/netfilter.h:308 + ip_rcv+0x2c5/0x5d0 linux/net/ipv4/ip_input.c:569 + __netif_receive_skb_one_core+0x199/0x1e0 linux/net/core/dev.c:5534 + __netif_receive_skb+0x1f/0x1c0 linux/net/core/dev.c:5648 + process_backlog+0x101/0x6b0 linux/net/core/dev.c:5976 + __napi_poll.constprop.0+0xba/0x550 linux/net/core/dev.c:6576 + napi_poll linux/net/core/dev.c:6645 + net_rx_action+0x95a/0xe90 linux/net/core/dev.c:6781 + __do_softirq+0x21f/0x8e7 linux/kernel/softirq.c:553 + do_softirq linux/kernel/softirq.c:454 + do_softirq+0xb2/0xf0 linux/kernel/softirq.c:441 + </IRQ> + <TASK> + __local_bh_enable_ip+0x100/0x120 linux/kernel/softirq.c:381 + local_bh_enable linux/./include/linux/bottom_half.h:33 + rcu_read_unlock_bh linux/./include/linux/rcupdate.h:851 + __dev_queue_xmit+0x871/0x3ee0 linux/net/core/dev.c:4378 + dev_queue_xmit linux/./include/linux/netdevice.h:3169 + neigh_hh_output linux/./include/net/neighbour.h:526 + neigh_output linux/./include/net/neighbour.h:540 + ip_finish_output2+0x169f/0x2550 linux/net/ipv4/ip_output.c:235 + __ip_finish_output linux/net/ipv4/ip_output.c:313 + __ip_finish_output+0x49e/0x950 linux/net/ipv4/ip_output.c:295 + ip_finish_output+0x31/0x310 linux/net/ipv4/ip_output.c:323 + NF_HOOK_COND linux/./include/linux/netfilter.h:303 + ip_output+0x13b/0x2a0 linux/net/ipv4/ip_output.c:433 + dst_output linux/./include/net/dst.h:451 + ip_local_out linux/net/ipv4/ip_output.c:129 + ip_send_skb+0x3e5/0x560 linux/net/ipv4/ip_output.c:1492 + udp_send_skb+0x73f/0x1530 linux/net/ipv4/udp.c:963 + udp_sendmsg+0x1a36/0x2b40 linux/net/ipv4/udp.c:1250 + inet_sendmsg+0x105/0x140 linux/net/ipv4/af_inet.c:850 + sock_sendmsg_nosec linux/net/socket.c:730 + __sock_sendmsg linux/net/socket.c:745 + __sys_sendto+0x42c/0x4e0 linux/net/socket.c:2191 + __do_sys_sendto linux/net/socket.c:2203 + __se_sys_sendto linux/net/socket.c:2199 + __x64_sys_sendto+0xe0/0x1c0 linux/net/socket.c:2199 + do_syscall_x64 linux/arch/x86/entry/common.c:52 + do_syscall_64+0xd8/0x270 linux/arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x6f/0x77 linux/arch/x86/entry/entry_64.S:120 +RIP: 0033:0x7f3434974f29 +Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 8b 0d 37 8f 0d 00 f7 d8 64 89 01 48 +RSP: 002b:00007fff9154f2b8 EFLAGS: 00000212 ORIG_RAX: 000000000000002c +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3434974f29 +RDX: 00000000000032c8 RSI: 00007fff9154f300 RDI: 0000000000000003 +RBP: 00007fff915532e0 R08: 00007fff91553360 R09: 0000000000000010 +R10: 0000000000000000 R11: 0000000000000212 R12: 000055ed86d261d0 +R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 + </TASK> + +In the critical scenario, either the relevant skb is freed or its +ownership is transferred into a frag_lists. In both cases, the cleanup +code must not free it again: we need to clear the skb reference earlier. + +Fixes: 1149557d64c9 ("tipc: eliminate unnecessary linearization of incoming buffers") +Cc: stable@vger.kernel.org +Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-23852 +Acked-by: Xin Long <lucien.xin@gmail.com> +Signed-off-by: Paolo Abeni <pabeni@redhat.com> +Reviewed-by: Eric Dumazet <edumazet@google.com> +Link: https://lore.kernel.org/r/752f1ccf762223d109845365d07f55414058e5a3.1714484273.git.pabeni@redhat.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + net/tipc/msg.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index 5c9fd4791c4b..9a6e9bcbf694 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -156,6 +156,11 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + if (!head) + goto err; + ++ /* Either the input skb ownership is transferred to headskb ++ * or the input skb is freed, clear the reference to avoid ++ * bad access on error path. ++ */ ++ *buf = NULL; + if (skb_try_coalesce(head, frag, &headstolen, &delta)) { + kfree_skb_partial(frag, headstolen); + } else { +@@ -179,7 +184,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + *headbuf = NULL; + return 1; + } +- *buf = NULL; + return 0; + err: + kfree_skb(*buf); +-- +2.43.0 + diff --git a/debian/patches/bugfix/all/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch b/debian/patches/bugfix/all/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch new file mode 100644 index 000000000..0b0ac04c6 --- /dev/null +++ b/debian/patches/bugfix/all/tipc-fix-a-possible-memleak-in-tipc_buf_append.patch @@ -0,0 +1,38 @@ +From: Xin Long <lucien.xin@gmail.com> +Date: Tue, 30 Apr 2024 10:03:38 -0400 +Subject: tipc: fix a possible memleak in tipc_buf_append +Origin: https://git.kernel.org/linus/97bf6f81b29a8efaf5d0983251a7450e5794370d + +__skb_linearize() doesn't free the skb when it fails, so move +'*buf = NULL' after __skb_linearize(), so that the skb can be +freed on the err path. + +Fixes: b7df21cf1b79 ("tipc: skb_linearize the head skb when reassembling msgs") +Reported-by: Paolo Abeni <pabeni@redhat.com> +Signed-off-by: Xin Long <lucien.xin@gmail.com> +Reviewed-by: Simon Horman <horms@kernel.org> +Reviewed-by: Tung Nguyen <tung.q.nguyen@dektech.com.au> +Link: https://lore.kernel.org/r/90710748c29a1521efac4f75ea01b3b7e61414cf.1714485818.git.lucien.xin@gmail.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + net/tipc/msg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index 9a6e9bcbf694..76284fc538eb 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -142,9 +142,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + if (fragid == FIRST_FRAGMENT) { + if (unlikely(head)) + goto err; +- *buf = NULL; + if (skb_has_frag_list(frag) && __skb_linearize(frag)) + goto err; ++ *buf = NULL; + frag = skb_unshare(frag, GFP_ATOMIC); + if (unlikely(!frag)) + goto err; +-- +2.43.0 + diff --git a/debian/patches/bugfix/all/tty-n_gsm-require-CAP_NET_ADMIN-to-attach-N_GSM0710-.patch b/debian/patches/bugfix/all/tty-n_gsm-require-CAP_NET_ADMIN-to-attach-N_GSM0710-.patch deleted file mode 100644 index bfb6301cf..000000000 --- a/debian/patches/bugfix/all/tty-n_gsm-require-CAP_NET_ADMIN-to-attach-N_GSM0710-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> -Date: Mon, 31 Jul 2023 15:59:42 -0300 -Subject: tty: n_gsm: require CAP_NET_ADMIN to attach N_GSM0710 ldisc -Origin: https://git.kernel.org/linus/67c37756898a5a6b2941a13ae7260c89b54e0d88 -Bug-Debian: https://bugs.debian.org/1068770 - -Any unprivileged user can attach N_GSM0710 ldisc, but it requires -CAP_NET_ADMIN to create a GSM network anyway. - -Require initial namespace CAP_NET_ADMIN to do that. - -Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> -Link: https://lore.kernel.org/r/20230731185942.279611-1-cascardo@canonical.com -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - drivers/tty/n_gsm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c -index 1cdefac4dd1b..c7a787f10a9c 100644 ---- a/drivers/tty/n_gsm.c -+++ b/drivers/tty/n_gsm.c -@@ -3576,6 +3576,9 @@ static int gsmld_open(struct tty_struct *tty) - { - struct gsm_mux *gsm; - -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ - if (tty->ops->write == NULL) - return -EINVAL; - --- -2.43.0 - |