From: Greg Kroah-Hartman Date: Mon, 27 Sep 2021 13:22:07 +0000 (+0200) Subject: 5.14-stable patches X-Git-Tag: v5.4.150~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=089e357a751ffe31cc4e4745c71ca9dd4b24213a;p=thirdparty%2Fkernel%2Fstable-queue.git 5.14-stable patches added patches: qnx4-work-around-gcc-false-positive-warning-bug.patch xen-balloon-fix-balloon-kthread-freezing.patch --- diff --git a/queue-5.14/qnx4-work-around-gcc-false-positive-warning-bug.patch b/queue-5.14/qnx4-work-around-gcc-false-positive-warning-bug.patch new file mode 100644 index 00000000000..7785286dddf --- /dev/null +++ b/queue-5.14/qnx4-work-around-gcc-false-positive-warning-bug.patch @@ -0,0 +1,120 @@ +From d5f6545934c47e97c0b48a645418e877b452a992 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Mon, 20 Sep 2021 10:26:21 -0700 +Subject: qnx4: work around gcc false positive warning bug + +From: Linus Torvalds + +commit d5f6545934c47e97c0b48a645418e877b452a992 upstream. + +In commit b7213ffa0e58 ("qnx4: avoid stringop-overread errors") I tried +to teach gcc about how the directory entry structure can be two +different things depending on a status flag. It made the code clearer, +and it seemed to make gcc happy. + +However, Arnd points to a gcc bug, where despite using two different +members of a union, gcc then gets confused, and uses the size of one of +the members to decide if a string overrun happens. And not necessarily +the rigth one. + +End result: with some configurations, gcc-11 will still complain about +the source buffer size being overread: + + fs/qnx4/dir.c: In function 'qnx4_readdir': + fs/qnx4/dir.c:76:32: error: 'strnlen' specified bound [16, 48] exceeds source size 1 [-Werror=stringop-overread] + 76 | size = strnlen(name, size); + | ^~~~~~~~~~~~~~~~~~~ + fs/qnx4/dir.c:26:22: note: source object declared here + 26 | char de_name; + | ^~~~~~~ + +because gcc will get confused about which union member entry is actually +getting accessed, even when the source code is very clear about it. Gcc +internally will have combined two "redundant" pointers (pointing to +different union elements that are at the same offset), and takes the +size checking from one or the other - not necessarily the right one. + +This is clearly a gcc bug, but we can work around it fairly easily. The +biggest thing here is the big honking comment about why we do what we +do. + +Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6 +Reported-and-tested-by: Arnd Bergmann +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/qnx4/dir.c | 36 +++++++++++++++++++++++++++--------- + 1 file changed, 27 insertions(+), 9 deletions(-) + +--- a/fs/qnx4/dir.c ++++ b/fs/qnx4/dir.c +@@ -20,12 +20,33 @@ + * depending on the status field in the last byte. The + * first byte is where the name start either way, and a + * zero means it's empty. ++ * ++ * Also, due to a bug in gcc, we don't want to use the ++ * real (differently sized) name arrays in the inode and ++ * link entries, but always the 'de_name[]' one in the ++ * fake struct entry. ++ * ++ * See ++ * ++ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578#c6 ++ * ++ * for details, but basically gcc will take the size of the ++ * 'name' array from one of the used union entries randomly. ++ * ++ * This use of 'de_name[]' (48 bytes) avoids the false positive ++ * warnings that would happen if gcc decides to use 'inode.di_name' ++ * (16 bytes) even when the pointer and size were to come from ++ * 'link.dl_name' (48 bytes). ++ * ++ * In all cases the actual name pointer itself is the same, it's ++ * only the gcc internal 'what is the size of this field' logic ++ * that can get confused. + */ + union qnx4_directory_entry { + struct { +- char de_name; +- char de_pad[62]; +- char de_status; ++ const char de_name[48]; ++ u8 de_pad[15]; ++ u8 de_status; + }; + struct qnx4_inode_entry inode; + struct qnx4_link_info link; +@@ -53,29 +74,26 @@ static int qnx4_readdir(struct file *fil + ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK; + for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) { + union qnx4_directory_entry *de; +- const char *name; + + offset = ix * QNX4_DIR_ENTRY_SIZE; + de = (union qnx4_directory_entry *) (bh->b_data + offset); + +- if (!de->de_name) ++ if (!de->de_name[0]) + continue; + if (!(de->de_status & (QNX4_FILE_USED|QNX4_FILE_LINK))) + continue; + if (!(de->de_status & QNX4_FILE_LINK)) { + size = sizeof(de->inode.di_fname); +- name = de->inode.di_fname; + ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1; + } else { + size = sizeof(de->link.dl_fname); +- name = de->link.dl_fname; + ino = ( le32_to_cpu(de->link.dl_inode_blk) - 1 ) * + QNX4_INODES_PER_BLOCK + + de->link.dl_inode_ndx; + } +- size = strnlen(name, size); ++ size = strnlen(de->de_name, size); + QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, name)); +- if (!dir_emit(ctx, name, size, ino, DT_UNKNOWN)) { ++ if (!dir_emit(ctx, de->de_name, size, ino, DT_UNKNOWN)) { + brelse(bh); + return 0; + } diff --git a/queue-5.14/series b/queue-5.14/series index e5b54a0d6eb..22c61a1d361 100644 --- a/queue-5.14/series +++ b/queue-5.14/series @@ -155,3 +155,5 @@ irqchip-armada-370-xp-fix-ack-eoi-breakage.patch arm64-add-mte-supported-check-to-thread-switching-and-syscall-entry-exit.patch usb-serial-cp210x-fix-dropped-characters-with-cp2102.patch software-node-balance-refcount-for-managed-software-nodes.patch +xen-balloon-fix-balloon-kthread-freezing.patch +qnx4-work-around-gcc-false-positive-warning-bug.patch diff --git a/queue-5.14/xen-balloon-fix-balloon-kthread-freezing.patch b/queue-5.14/xen-balloon-fix-balloon-kthread-freezing.patch new file mode 100644 index 00000000000..5691bf7202f --- /dev/null +++ b/queue-5.14/xen-balloon-fix-balloon-kthread-freezing.patch @@ -0,0 +1,37 @@ +From 96f5bd03e1be606987644b71899ea56a8d05f825 Mon Sep 17 00:00:00 2001 +From: Juergen Gross +Date: Mon, 20 Sep 2021 12:03:45 +0200 +Subject: xen/balloon: fix balloon kthread freezing + +From: Juergen Gross + +commit 96f5bd03e1be606987644b71899ea56a8d05f825 upstream. + +Commit 8480ed9c2bbd56 ("xen/balloon: use a kernel thread instead a +workqueue") switched the Xen balloon driver to use a kernel thread. +Unfortunately the patch omitted to call try_to_freeze() or to use +wait_event_freezable_timeout(), causing a system suspend to fail. + +Fixes: 8480ed9c2bbd56 ("xen/balloon: use a kernel thread instead a workqueue") +Signed-off-by: Juergen Gross +Reviewed-by: Boris Ostrovsky +Link: https://lore.kernel.org/r/20210920100345.21939-1-jgross@suse.com +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/balloon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -522,8 +522,8 @@ static int balloon_thread(void *unused) + timeout = 3600 * HZ; + credit = current_credit(); + +- wait_event_interruptible_timeout(balloon_thread_wq, +- balloon_thread_cond(state, credit), timeout); ++ wait_event_freezable_timeout(balloon_thread_wq, ++ balloon_thread_cond(state, credit), timeout); + + if (kthread_should_stop()) + return 0;