Hi,
On 5/8/22 13:37, Willy Tarreau wrote:
Interrupt handler bad_flp_intr() may cause a UAF on the recently freed request just to increment the error count. There's no point keeping that one in the request anyway, and since the interrupt handler uses a static pointer to the error which cannot be kept in sync with the pending request, better make it use a static error counter that's reset for each new request. This reset now happens when entering redo_fd_request() for a new request via set_next_request().
One initial concern about a single error counter was that errors on one floppy drive could be reported on another one, but this problem is not real given that the driver uses a single drive at a time, as that PC-compatible controllers also have this limitation by using shared signals. As such the error count is always for the "current" drive.
Reported-by: Minh Yuan yuanmingbuaa@gmail.com Suggested-by: Linus Torvalds torvalds@linuxfoundation.org Tested-by: Denis Efremov efremov@linux.com Signed-off-by: Willy Tarreau w@1wt.eu
Could you please take this patch (only this one) to the stable trees?
commit f71f01394f742fc4558b3f9f4c7ef4c4cf3b07c8 upstream.
The patch applies cleanly to 5.17, 5.15, 5.10 kernels. I'll send a backport for 5.4 and older kernels.
Thanks, Denis
drivers/block/floppy.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index d5b9ff9bcbb2..015841f50f4e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -509,8 +509,8 @@ static unsigned long fdc_busy; static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); static DECLARE_WAIT_QUEUE_HEAD(command_done); -/* Errors during formatting are counted here. */ -static int format_errors; +/* errors encountered on the current (or last) request */ +static int floppy_errors; /* Format request descriptor. */ static struct format_descr format_req; @@ -530,7 +530,6 @@ static struct format_descr format_req; static char *floppy_track_buffer; static int max_buffer_sectors; -static int *errors; typedef void (*done_f)(int); static const struct cont_t { void (*interrupt)(void); @@ -1455,7 +1454,7 @@ static int interpret_errors(void) if (drive_params[current_drive].flags & FTD_MSG) DPRINT("Over/Underrun - retrying\n"); bad = 0;
} else if (*errors >= drive_params[current_drive].max_errors.reporting) {
} if (reply_buffer[ST2] & ST2_WC || reply_buffer[ST2] & ST2_BC)} else if (floppy_errors >= drive_params[current_drive].max_errors.reporting) { print_errors();
@@ -2095,7 +2094,7 @@ static void bad_flp_intr(void) if (!next_valid_format(current_drive)) return; }
- err_count = ++(*errors);
- err_count = ++floppy_errors; INFBOUND(write_errors[current_drive].badness, err_count); if (err_count > drive_params[current_drive].max_errors.abort) cont->done(0);
@@ -2241,9 +2240,8 @@ static int do_format(int drive, struct format_descr *tmp_format_req) return -EINVAL; } format_req = *tmp_format_req;
- format_errors = 0; cont = &format_cont;
- errors = &format_errors;
- floppy_errors = 0; ret = wait_til_done(redo_format, true); if (ret == -EINTR) return -EINTR;
@@ -2759,10 +2757,11 @@ static int set_next_request(void) current_req = list_first_entry_or_null(&floppy_reqs, struct request, queuelist); if (current_req) {
current_req->error_count = 0;
list_del_init(¤t_req->queuelist);floppy_errors = 0;
}return 1;
- return current_req != NULL;
- return 0;
} /* Starts or continues processing request. Will automatically unlock the @@ -2821,7 +2820,6 @@ static void redo_fd_request(void) _floppy = floppy_type + drive_params[current_drive].autodetect[drive_state[current_drive].probed_format]; } else probing = 0;
- errors = &(current_req->error_count); tmp = make_raw_rw_request(); if (tmp < 2) { request_done(tmp);
On Tue, May 17, 2022 at 09:47:57PM +0400, Denis Efremov wrote:
Hi,
On 5/8/22 13:37, Willy Tarreau wrote:
Interrupt handler bad_flp_intr() may cause a UAF on the recently freed request just to increment the error count. There's no point keeping that one in the request anyway, and since the interrupt handler uses a static pointer to the error which cannot be kept in sync with the pending request, better make it use a static error counter that's reset for each new request. This reset now happens when entering redo_fd_request() for a new request via set_next_request().
One initial concern about a single error counter was that errors on one floppy drive could be reported on another one, but this problem is not real given that the driver uses a single drive at a time, as that PC-compatible controllers also have this limitation by using shared signals. As such the error count is always for the "current" drive.
Reported-by: Minh Yuan yuanmingbuaa@gmail.com Suggested-by: Linus Torvalds torvalds@linuxfoundation.org Tested-by: Denis Efremov efremov@linux.com Signed-off-by: Willy Tarreau w@1wt.eu
Could you please take this patch (only this one) to the stable trees?
commit f71f01394f742fc4558b3f9f4c7ef4c4cf3b07c8 upstream.
The patch applies cleanly to 5.17, 5.15, 5.10 kernels. I'll send a backport for 5.4 and older kernels.
All now queued up, thanks.
greg k-h
linux-stable-mirror@lists.linaro.org