From: Hui Peng <benquike@gmail.com>
To: martin.petersen@oracle.com, linux-scsi@vger.kernel.org
Cc: john.garry@linux.dev, dgilbert@interlog.com, jejb@linux.ibm.com,
stable@vger.kernel.org, linux-kernel@vger.kernel.org,
Hui Peng <benquike@gmail.com>
Subject: [PATCH v2] scsi: sg: finish request on error in sg_read()
Date: Thu, 24 Sep 2026 05:46:25 +0000 [thread overview]
Message-ID: <20260924054625.2282544-1-benquike@gmail.com> (raw)
In-Reply-To: <69218179-d750-4880-8be0-2ccab7d76a6d@linux.dev>
In sg_read(), for the legacy sg_header interface, a completed request
(srp) is dequeued from the ready list via sg_get_rq_mark(). However, if
kzalloc() fails, or if copy_to_user() or sg_read_oxfer() fails with
-EFAULT, sg_read() returns immediately without calling
sg_finish_rem_req(srp) and sg_remove_request(sfp, srp).
Because sg_get_rq_mark() clears the request from the ready list, this
completed request is left orphaned on sfp->rq_list in an active state,
leaking its kernel buffers and pages until the file descriptor is
closed. Fix this by jumping to finish_req and calling
sg_finish_rem_req() and sg_remove_request() before returning on error.
This was tested in QEMU (7.3.0-rc3) using scsi_debug (/dev/sg0):
1. Queued a legacy struct sg_header INQUIRY command via write().
2. Waited for completion via poll().
3. Invoked read() with an unmapped userspace buffer (NULL, count = 64),
returning -EFAULT.
4. Queried the request state via the SG_GET_REQUEST_TABLE ioctl.
Before this fix, req_tbl[0].req_state remained 2 (active/orphaned on
sfp->rq_list) after the failed read(); with this fix, req_tbl[0].req_state
is 0 (properly finished and removed).
The C reproducer (PoC) can be provided upon request.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Suggested-by: John Garry <john.garry@linux.dev>
Signed-off-by: Hui Peng <benquike@gmail.com>
---
Changes in v2:
- Rename error cleanup label from `free_old_hdr:` to `finish_req:`
since it now finishes and removes `srp` in addition to freeing `old_hdr`
(John Garry).
- Also handle `kzalloc(SZ_SG_HEADER, GFP_KERNEL)` failure by setting
`retval = -ENOMEM` and jumping to `finish_req`, as `srp` has already
been dequeued by `sg_get_rq_mark()` at that point.
- Moved testing explanation into the commit message body.
- Added note that C reproducer (PoC) can be provided upon request.
drivers/scsi/sg.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 5408f002e6c0..5d635349e06e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -480,8 +480,10 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
hp = &srp->header;
old_hdr = kzalloc(SZ_SG_HEADER, GFP_KERNEL);
- if (!old_hdr)
- return -ENOMEM;
+ if (!old_hdr) {
+ retval = -ENOMEM;
+ goto finish_req;
+ }
old_hdr->reply_len = (int) hp->timeout;
old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */
@@ -543,10 +545,10 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
}
} else
count = (old_hdr->result == 0) ? 0 : -EIO;
- sg_finish_rem_req(srp);
- sg_remove_request(sfp, srp);
retval = count;
-free_old_hdr:
+finish_req:
+ sg_finish_rem_req(srp);
+ sg_remove_request(sfp, srp);
kfree(old_hdr);
return retval;
}
--
2.53.0.797.g7842e34a66-goog
next prev parent reply other threads:[~2026-09-24 5:46 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 20:48 [PATCH] scsi: sg: clean up request on error paths in sg_read() Hui Peng
2026-09-21 14:47 ` John Garry
2026-09-24 5:46 ` Hui Peng [this message]
2026-09-24 5:54 ` [PATCH v2] scsi: sg: finish request on error " sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260924054625.2282544-1-benquike@gmail.com \
--to=benquike@gmail.com \
--cc=dgilbert@interlog.com \
--cc=jejb@linux.ibm.com \
--cc=john.garry@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.