From: Greg Kroah-Hartman Date: Thu, 19 May 2022 12:49:02 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.9.316~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b1ef576627c49df2eac5c858656e3a1c305007e9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: floppy-use-a-statically-allocated-error-counter.patch --- diff --git a/queue-5.4/floppy-use-a-statically-allocated-error-counter.patch b/queue-5.4/floppy-use-a-statically-allocated-error-counter.patch new file mode 100644 index 00000000000..561d09a78ee --- /dev/null +++ b/queue-5.4/floppy-use-a-statically-allocated-error-counter.patch @@ -0,0 +1,115 @@ +From f71f01394f742fc4558b3f9f4c7ef4c4cf3b07c8 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Sun, 8 May 2022 11:37:07 +0200 +Subject: floppy: use a statically allocated error counter + +From: Willy Tarreau + +commit f71f01394f742fc4558b3f9f4c7ef4c4cf3b07c8 upstream. + +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 +Suggested-by: Linus Torvalds +Tested-by: Denis Efremov +Signed-off-by: Willy Tarreau +Signed-off-by: Linus Torvalds +Signed-off-by: Denis Efremov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/floppy.c | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -521,8 +521,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; +@@ -542,7 +542,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); +@@ -1435,7 +1434,7 @@ static int interpret_errors(void) + if (DP->flags & FTD_MSG) + DPRINT("Over/Underrun - retrying\n"); + bad = 0; +- } else if (*errors >= DP->max_errors.reporting) { ++ } else if (floppy_errors >= DP->max_errors.reporting) { + print_errors(); + } + if (ST2 & ST2_WC || ST2 & ST2_BC) +@@ -2055,7 +2054,7 @@ static void bad_flp_intr(void) + if (!next_valid_format()) + return; + } +- err_count = ++(*errors); ++ err_count = ++floppy_errors; + INFBOUND(DRWE->badness, err_count); + if (err_count > DP->max_errors.abort) + cont->done(0); +@@ -2200,9 +2199,8 @@ static int do_format(int drive, struct f + 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; +@@ -2677,7 +2675,7 @@ static int make_raw_rw_request(void) + */ + if (!direct || + (indirect * 2 > direct * 3 && +- *errors < DP->max_errors.read_track && ++ floppy_errors < DP->max_errors.read_track && + ((!probing || + (DP->read_track & (1 << DRS->probed_format)))))) { + max_size = blk_rq_sectors(current_req); +@@ -2801,10 +2799,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; ++ floppy_errors = 0; + list_del_init(¤t_req->queuelist); ++ return 1; + } +- return current_req != NULL; ++ return 0; + } + + static void redo_fd_request(void) +@@ -2860,7 +2859,6 @@ do_request: + _floppy = floppy_type + DP->autodetect[DRS->probed_format]; + } else + probing = 0; +- errors = &(current_req->error_count); + tmp = make_raw_rw_request(); + if (tmp < 2) { + request_done(tmp); diff --git a/queue-5.4/series b/queue-5.4/series index e69de29bb2d..0a3d63c4ea5 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -0,0 +1 @@ +floppy-use-a-statically-allocated-error-counter.patch