]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Jun 2024 12:33:12 +0000 (14:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Jun 2024 12:33:12 +0000 (14:33 +0200)
added patches:
input-try-trimming-too-long-modalias-strings.patch
powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch

queue-5.15/input-try-trimming-too-long-modalias-strings.patch [new file with mode: 0644]
queue-5.15/powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch [new file with mode: 0644]
queue-5.15/series

diff --git a/queue-5.15/input-try-trimming-too-long-modalias-strings.patch b/queue-5.15/input-try-trimming-too-long-modalias-strings.patch
new file mode 100644 (file)
index 0000000..b09198e
--- /dev/null
@@ -0,0 +1,212 @@
+From 0774d19038c496f0c3602fb505c43e1b2d8eed85 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 29 Apr 2024 14:50:41 -0700
+Subject: Input: try trimming too long modalias strings
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 0774d19038c496f0c3602fb505c43e1b2d8eed85 upstream.
+
+If an input device declares too many capability bits then modalias
+string for such device may become too long and not fit into uevent
+buffer, resulting in failure of sending said uevent. This, in turn,
+may prevent userspace from recognizing existence of such devices.
+
+This is typically not a concern for real hardware devices as they have
+limited number of keys, but happen with synthetic devices such as
+ones created by xen-kbdfront driver, which creates devices as being
+capable of delivering all possible keys, since it doesn't know what
+keys the backend may produce.
+
+To deal with such devices input core will attempt to trim key data,
+in the hope that the rest of modalias string will fit in the given
+buffer. When trimming key data it will indicate that it is not
+complete by placing "+," sign, resulting in conversions like this:
+
+old: k71,72,73,74,78,7A,7B,7C,7D,8E,9E,A4,AD,E0,E1,E4,F8,174,
+new: k71,72,73,74,78,7A,7B,7C,+,
+
+This should allow existing udev rules continue to work with existing
+devices, and will also allow writing more complex rules that would
+recognize trimmed modalias and check input device characteristics by
+other means (for example by parsing KEY= data in uevent or parsing
+input device sysfs attributes).
+
+Note that the driver core may try adding more uevent environment
+variables once input core is done adding its own, so when forming
+modalias we can not use the entire available buffer, so we reduce
+it by somewhat an arbitrary amount (96 bytes).
+
+Reported-by: Jason Andryuk <jandryuk@gmail.com>
+Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
+Tested-by: Jason Andryuk <jandryuk@gmail.com>
+Link: https://lore.kernel.org/r/ZjAWMQCJdrxZkvkB@google.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
+---
+
+---
+ drivers/input/input.c |  105 ++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 90 insertions(+), 15 deletions(-)
+
+--- a/drivers/input/input.c
++++ b/drivers/input/input.c
+@@ -1360,19 +1360,19 @@ static int input_print_modalias_bits(cha
+                                    char name, unsigned long *bm,
+                                    unsigned int min_bit, unsigned int max_bit)
+ {
+-      int len = 0, i;
++      int bit = min_bit;
++      int len = 0;
+       len += snprintf(buf, max(size, 0), "%c", name);
+-      for (i = min_bit; i < max_bit; i++)
+-              if (bm[BIT_WORD(i)] & BIT_MASK(i))
+-                      len += snprintf(buf + len, max(size - len, 0), "%X,", i);
++      for_each_set_bit_from(bit, bm, max_bit)
++              len += snprintf(buf + len, max(size - len, 0), "%X,", bit);
+       return len;
+ }
+-static int input_print_modalias(char *buf, int size, struct input_dev *id,
+-                              int add_cr)
++static int input_print_modalias_parts(char *buf, int size, int full_len,
++                                    struct input_dev *id)
+ {
+-      int len;
++      int len, klen, remainder, space;
+       len = snprintf(buf, max(size, 0),
+                      "input:b%04Xv%04Xp%04Xe%04X-",
+@@ -1381,8 +1381,49 @@ static int input_print_modalias(char *bu
+       len += input_print_modalias_bits(buf + len, size - len,
+                               'e', id->evbit, 0, EV_MAX);
+-      len += input_print_modalias_bits(buf + len, size - len,
++
++      /*
++       * Calculate the remaining space in the buffer making sure we
++       * have place for the terminating 0.
++       */
++      space = max(size - (len + 1), 0);
++
++      klen = input_print_modalias_bits(buf + len, size - len,
+                               'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
++      len += klen;
++
++      /*
++       * If we have more data than we can fit in the buffer, check
++       * if we can trim key data to fit in the rest. We will indicate
++       * that key data is incomplete by adding "+" sign at the end, like
++       * this: * "k1,2,3,45,+,".
++       *
++       * Note that we shortest key info (if present) is "k+," so we
++       * can only try to trim if key data is longer than that.
++       */
++      if (full_len && size < full_len + 1 && klen > 3) {
++              remainder = full_len - len;
++              /*
++               * We can only trim if we have space for the remainder
++               * and also for at least "k+," which is 3 more characters.
++               */
++              if (remainder <= space - 3) {
++                      int i;
++                      /*
++                       * We are guaranteed to have 'k' in the buffer, so
++                       * we need at least 3 additional bytes for storing
++                       * "+," in addition to the remainder.
++                       */
++                      for (i = size - 1 - remainder - 3; i >= 0; i--) {
++                              if (buf[i] == 'k' || buf[i] == ',') {
++                                      strcpy(buf + i + 1, "+,");
++                                      len = i + 3; /* Not counting '\0' */
++                                      break;
++                              }
++                      }
++              }
++      }
++
+       len += input_print_modalias_bits(buf + len, size - len,
+                               'r', id->relbit, 0, REL_MAX);
+       len += input_print_modalias_bits(buf + len, size - len,
+@@ -1398,12 +1439,25 @@ static int input_print_modalias(char *bu
+       len += input_print_modalias_bits(buf + len, size - len,
+                               'w', id->swbit, 0, SW_MAX);
+-      if (add_cr)
+-              len += snprintf(buf + len, max(size - len, 0), "\n");
+-
+       return len;
+ }
++static int input_print_modalias(char *buf, int size, struct input_dev *id)
++{
++      int full_len;
++
++      /*
++       * Printing is done in 2 passes: first one figures out total length
++       * needed for the modalias string, second one will try to trim key
++       * data in case when buffer is too small for the entire modalias.
++       * If the buffer is too small regardless, it will fill as much as it
++       * can (without trimming key data) into the buffer and leave it to
++       * the caller to figure out what to do with the result.
++       */
++      full_len = input_print_modalias_parts(NULL, 0, 0, id);
++      return input_print_modalias_parts(buf, size, full_len, id);
++}
++
+ static ssize_t input_dev_show_modalias(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+@@ -1411,7 +1465,9 @@ static ssize_t input_dev_show_modalias(s
+       struct input_dev *id = to_input_dev(dev);
+       ssize_t len;
+-      len = input_print_modalias(buf, PAGE_SIZE, id, 1);
++      len = input_print_modalias(buf, PAGE_SIZE, id);
++      if (len < PAGE_SIZE - 2)
++              len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+       return min_t(int, len, PAGE_SIZE);
+ }
+@@ -1623,6 +1679,23 @@ static int input_add_uevent_bm_var(struc
+       return 0;
+ }
++/*
++ * This is a pretty gross hack. When building uevent data the driver core
++ * may try adding more environment variables to kobj_uevent_env without
++ * telling us, so we have no idea how much of the buffer we can use to
++ * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially
++ * reduce amount of memory we will use for the modalias environment variable.
++ *
++ * The potential additions are:
++ *
++ * SEQNUM=18446744073709551615 - (%llu - 28 bytes)
++ * HOME=/ (6 bytes)
++ * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes)
++ *
++ * 68 bytes total. Allow extra buffer - 96 bytes
++ */
++#define UEVENT_ENV_EXTRA_LEN  96
++
+ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
+                                        struct input_dev *dev)
+ {
+@@ -1632,9 +1705,11 @@ static int input_add_uevent_modalias_var
+               return -ENOMEM;
+       len = input_print_modalias(&env->buf[env->buflen - 1],
+-                                 sizeof(env->buf) - env->buflen,
+-                                 dev, 0);
+-      if (len >= (sizeof(env->buf) - env->buflen))
++                                 (int)sizeof(env->buf) - env->buflen -
++                                      UEVENT_ENV_EXTRA_LEN,
++                                 dev);
++      if (len >= ((int)sizeof(env->buf) - env->buflen -
++                                      UEVENT_ENV_EXTRA_LEN))
+               return -ENOMEM;
+       env->buflen += len;
diff --git a/queue-5.15/powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch b/queue-5.15/powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch
new file mode 100644 (file)
index 0000000..3767685
--- /dev/null
@@ -0,0 +1,86 @@
+From 2d43cc701b96f910f50915ac4c2a0cae5deb734c Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 29 May 2024 22:30:28 +1000
+Subject: powerpc/uaccess: Fix build errors seen with GCC 13/14
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 2d43cc701b96f910f50915ac4c2a0cae5deb734c upstream.
+
+Building ppc64le_defconfig with GCC 14 fails with assembler errors:
+
+    CC      fs/readdir.o
+  /tmp/ccdQn0mD.s: Assembler messages:
+  /tmp/ccdQn0mD.s:212: Error: operand out of domain (18 is not a multiple of 4)
+  /tmp/ccdQn0mD.s:226: Error: operand out of domain (18 is not a multiple of 4)
+  ... [6 lines]
+  /tmp/ccdQn0mD.s:1699: Error: operand out of domain (18 is not a multiple of 4)
+
+A snippet of the asm shows:
+
+  # ../fs/readdir.c:210:         unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
+         ld 9,0(29)       # MEM[(u64 *)name_38(D) + _88 * 1], MEM[(u64 *)name_38(D) + _88 * 1]
+  # 210 "../fs/readdir.c" 1
+         1:      std 9,18(8)     # put_user       # *__pus_addr_52, MEM[(u64 *)name_38(D) + _88 * 1]
+
+The 'std' instruction requires a 4-byte aligned displacement because
+it is a DS-form instruction, and as the assembler says, 18 is not a
+multiple of 4.
+
+A similar error is seen with GCC 13 and CONFIG_UBSAN_SIGNED_WRAP=y.
+
+The fix is to change the constraint on the memory operand to put_user(),
+from "m" which is a general memory reference to "YZ".
+
+The "Z" constraint is documented in the GCC manual PowerPC machine
+constraints, and specifies a "memory operand accessed with indexed or
+indirect addressing". "Y" is not documented in the manual but specifies
+a "memory operand for a DS-form instruction". Using both allows the
+compiler to generate a DS-form "std" or X-form "stdx" as appropriate.
+
+The change has to be conditional on CONFIG_PPC_KERNEL_PREFIXED because
+the "Y" constraint does not guarantee 4-byte alignment when prefixed
+instructions are enabled.
+
+Unfortunately clang doesn't support the "Y" constraint so that has to be
+behind an ifdef.
+
+Although the build error is only seen with GCC 13/14, that appears
+to just be luck. The constraint has been incorrect since it was first
+added.
+
+Fixes: c20beffeec3c ("powerpc/uaccess: Use flexible addressing with __put_user()/__get_user()")
+Cc: stable@vger.kernel.org # v5.10+
+Suggested-by: Kewen Lin <linkw@gcc.gnu.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240529123029.146953-1-mpe@ellerman.id.au
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/uaccess.h |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/include/asm/uaccess.h
++++ b/arch/powerpc/include/asm/uaccess.h
+@@ -90,9 +90,20 @@ __pu_failed:                                                        \
+               :                                               \
+               : label)
++#ifdef CONFIG_CC_IS_CLANG
++#define DS_FORM_CONSTRAINT "Z<>"
++#else
++#define DS_FORM_CONSTRAINT "YZ<>"
++#endif
++
+ #ifdef __powerpc64__
+-#define __put_user_asm2_goto(x, ptr, label)                   \
+-      __put_user_asm_goto(x, ptr, label, "std")
++#define __put_user_asm2_goto(x, addr, label)                  \
++      asm goto ("1: std%U1%X1 %0,%1   # put_user\n"           \
++              EX_TABLE(1b, %l2)                               \
++              :                                               \
++              : "r" (x), DS_FORM_CONSTRAINT (*addr)           \
++              :                                               \
++              : label)
+ #else /* __powerpc64__ */
+ #define __put_user_asm2_goto(x, addr, label)                  \
+       asm_volatile_goto(                                      \
index ce7af6379dcb303d469e9427b6143c218da559da..d726cbc7064388601ff837c581b2849a9351447d 100644 (file)
@@ -93,3 +93,5 @@ xhci-apply-reset-resume-quirk-to-etron-ej188-xhci-host.patch
 xhci-handle-td-clearing-for-multiple-streams-case.patch
 xhci-apply-broken-streams-quirk-to-etron-ej188-xhci-host.patch
 scsi-mpt3sas-avoid-test-set_bit-operating-in-non-allocated-memory.patch
+powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch
+input-try-trimming-too-long-modalias-strings.patch