From 8eaa61d03c181ecf690afe83bd1b3375a9cf37eb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Jun 2024 14:33:12 +0200 Subject: [PATCH] 5.15-stable patches added patches: input-try-trimming-too-long-modalias-strings.patch powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch --- ...y-trimming-too-long-modalias-strings.patch | 212 ++++++++++++++++++ ...fix-build-errors-seen-with-gcc-13-14.patch | 86 +++++++ queue-5.15/series | 2 + 3 files changed, 300 insertions(+) create mode 100644 queue-5.15/input-try-trimming-too-long-modalias-strings.patch create mode 100644 queue-5.15/powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch 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 index 00000000000..b09198eb041 --- /dev/null +++ b/queue-5.15/input-try-trimming-too-long-modalias-strings.patch @@ -0,0 +1,212 @@ +From 0774d19038c496f0c3602fb505c43e1b2d8eed85 Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Mon, 29 Apr 2024 14:50:41 -0700 +Subject: Input: try trimming too long modalias strings + +From: Dmitry Torokhov + +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 +Reviewed-by: Peter Hutterer +Tested-by: Jason Andryuk +Link: https://lore.kernel.org/r/ZjAWMQCJdrxZkvkB@google.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jason Andryuk +--- + +--- + 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 index 00000000000..376768582cf --- /dev/null +++ b/queue-5.15/powerpc-uaccess-fix-build-errors-seen-with-gcc-13-14.patch @@ -0,0 +1,86 @@ +From 2d43cc701b96f910f50915ac4c2a0cae5deb734c Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 29 May 2024 22:30:28 +1000 +Subject: powerpc/uaccess: Fix build errors seen with GCC 13/14 + +From: Michael Ellerman + +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 +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240529123029.146953-1-mpe@ellerman.id.au +Signed-off-by: Greg Kroah-Hartman +--- + 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( \ diff --git a/queue-5.15/series b/queue-5.15/series index ce7af6379dc..d726cbc7064 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -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 -- 2.47.3