--- zzzz-none-000/linux-5.15.111/lib/kstrtox.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/lib/kstrtox.c 2024-02-07 10:23:29.000000000 +0000 @@ -413,3 +413,68 @@ kstrto_from_user(kstrtos16_from_user, kstrtos16, s16); kstrto_from_user(kstrtou8_from_user, kstrtou8, u8); kstrto_from_user(kstrtos8_from_user, kstrtos8, s8); + +/* + * Functions defined by this macro work the same as `kstrtox_from_user` + * functions but they ignore leading and trailing `chars` (typically + * whitespaces) in given string `s`. + * + * This macro is useful for reading /proc input which may have newline unless + * `echo -n` is used while writing to /proc. + */ +#define kstrto_from_user_strip(f, g, type) \ +int f(const char __user *s, size_t count, unsigned int base, type *res, \ + const char *chars) \ +{ \ + /* sign, base 2 representation, newline, terminator */ \ + char buf[1 + sizeof(type) * 8 + 1 + 1]; \ + char *b = buf, *c = NULL; \ + \ + count = min(count, sizeof(buf) - 1); \ + if (copy_from_user(buf, s, count)) \ + return -EFAULT; \ + \ + for (b[count] = '\0'; b && (c = strsep(&b, chars)) && !strlen(c); );\ + \ + return g(c, base, res); \ +} \ +EXPORT_SYMBOL(f) + +kstrto_from_user_strip(kstrtouint_from_user_strip, kstrtouint, unsigned int); +kstrto_from_user_strip(kstrtoint_from_user_strip, kstrtoint, int); +kstrto_from_user_strip(kstrtos32_from_user_strip, kstrtos32, s32); +kstrto_from_user_strip(kstrtou32_from_user_strip, kstrtou32, u32); +kstrto_from_user_strip(kstrtou16_from_user_strip, kstrtou16, u16); +kstrto_from_user_strip(kstrtou8_from_user_strip, kstrtou8, u8); + +#define kstrto_from_user_strip_whitespaces(f, g, type) \ +int f(const char __user *s, size_t count, type *res) \ +{ \ + return g(s, count, 10, res, " \n\t"); \ +} \ +EXPORT_SYMBOL(f) + +kstrto_from_user_strip_whitespaces( + kstrtouint_from_user_strip_whitespaces, + kstrtouint_from_user_strip, + unsigned int); +kstrto_from_user_strip_whitespaces( + kstrtoint_from_user_strip_whitespaces, + kstrtoint_from_user_strip, + int); +kstrto_from_user_strip_whitespaces( + kstrtos32_from_user_strip_whitespaces, + kstrtos32_from_user_strip, + s32); +kstrto_from_user_strip_whitespaces( + kstrtou32_from_user_strip_whitespaces, + kstrtou32_from_user_strip, + u32); +kstrto_from_user_strip_whitespaces( + kstrtou16_from_user_strip_whitespaces, + kstrtou16_from_user_strip, + u16); +kstrto_from_user_strip_whitespaces( + kstrtou8_from_user_strip_whitespaces, + kstrtou8_from_user_strip, + u8);