Second round of Kbuild fixes for 7.1

- modpost: prevent stack buffer overflow in do_input_entry() and do_dmi_entry()
 
     Defensively replace unbound sprintf() calls in file2alias to prevent
     silent stack overflows and detect alias name overflows with proper
     error message.
 
   - kbuild: pacman-pkg: make "rc" releases adhere to pacman versioning scheme
 
     Enable smooth upgrades from "rc" releases w/ pacman packages.
 
 Cc: Hasan Basbunar <basbunarhasan@gmail.com>
 Cc: Nathan Chancellor <nathan@kernel.org>
 Cc: Randy Dunlap <rdunlap@infradead.org>
 Cc: Thomas Weißschuh <linux@weissschuh.net>
 Cc: Viktor Jägersküpper <viktor_jaegerskuepper@freenet.de>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEh0E3p4c3JKeBvsLGB1IKcBYmEmkFAmoMO7QACgkQB1IKcBYm
 EmnQLQ//XwdHzbKSd+guDxReT8zB+tw12tTNbldidOjzL9W51qxeeQOltBtHG+eN
 fnjaCxnyJTiDDxlo5xn6eiuDoGNOh/1PIYWeN9e3JoxkYIwF0N3nSRjJAcmKvnqw
 H5QYfeNILbYc7ShdgXEZGa9JXXOn29TzU+Li+uG4OjssMVSr2NseyA3KmzIYOIw9
 SwDCkZ+qB1UOJdFmudjjlG7OwsMEfsMfcuC7cjy+NHj6ulSRggHZBDdk2oS5S4kM
 7Y+2EB5E7pJBt2T+gZlrwYC/ip+Y/y35G1ZjJ9UJMWlDvoyHvez4HeeVPZRaIGTz
 cZBB90F5RVqTvQWkrfMX57+Y5uNLxQHmbZM2kBcD5esWxVhMqagGxBB/xq742ugT
 RVAjhWVE4RG8hsK24BOQb0OogQe+UlgqwTR4G7d4IJ5CAzGWUQbIlBpDVczLAIkA
 xyDyp5ke8v+xveLBxTCM1FsxamEzpupc6/R3+oFOtuIvaknTRUEK+9IDXQpESHhU
 bNJBI0fCzxWN7rQpzUZejWHFa19afe4NNJdLwuNZ4GLfidBQSwRsXjPwTZSUm7gR
 JGkd6LKrBK48Z4FEmYft/tfZLUaDXawpp03km5Xh5z1aIaeUK02Vm8USKC8nO9Iy
 DDeulLeRhOjzqy+mWcCwlw2vqcXT5bVJ457XvHiqiM89A7hFli0=
 =4PGV
 -----END PGP SIGNATURE-----

Merge tag 'kbuild-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux

Pull Kbuild fixes from Nicolas Schier:

 - modpost: prevent stack buffer overflow in do_input_entry() and
   do_dmi_entry()

   Defensively replace unbound sprintf() calls in file2alias to prevent
   silent stack overflows and detect alias name overflows with proper
   error message.

 - kbuild: pacman-pkg: make "rc" releases adhere to pacman versioning
   scheme

   Enable smooth upgrades from "rc" releases w/ pacman packages.

* tag 'kbuild-fixes-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux:
  kbuild: pacman-pkg: make "rc" releases adhere to pacman versioning scheme
  modpost: prevent stack buffer overflow in do_input_entry() and do_dmi_entry()
This commit is contained in:
Linus Torvalds 2026-05-19 09:43:24 -07:00
commit 650d21334c
2 changed files with 54 additions and 27 deletions

View File

@ -651,7 +651,26 @@ static void do_vio_entry(struct module *mod, void *symval)
module_alias_printf(mod, true, "%s", alias);
}
static void do_input(char *alias,
static void __attribute__((format(printf, 3, 4)))
alias_append(char *alias, size_t size, const char *fmt, ...)
{
size_t len = strlen(alias);
va_list args;
int n;
if (len >= size)
fatal("alias buffer (%zu) overflow before append\n", size);
va_start(args, fmt);
n = vsnprintf(alias + len, size - len, fmt, args);
va_end(args);
if (n < 0 || (size_t)n >= size - len)
fatal("alias buffer (%zu) overflow on append (need %d, have %zu)\n",
size, n, size - len);
}
static void do_input(char *alias, size_t size,
kernel_ulong_t *arr, unsigned int min, unsigned int max)
{
unsigned int i;
@ -659,13 +678,14 @@ static void do_input(char *alias,
for (i = min; i <= max; i++)
if (get_unaligned_native(arr + i / BITS_PER_LONG) &
(1ULL << (i % BITS_PER_LONG)))
sprintf(alias + strlen(alias), "%X,*", i);
alias_append(alias, size, "%X,*", i);
}
/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
static void do_input_entry(struct module *mod, void *symval)
{
char alias[256] = {};
const size_t sizeof_alias = sizeof(alias);
DEF_FIELD(symval, input_device_id, flags);
DEF_FIELD(symval, input_device_id, bustype);
@ -687,35 +707,35 @@ static void do_input_entry(struct module *mod, void *symval)
ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product);
ADD(alias, "e", flags & INPUT_DEVICE_ID_MATCH_VERSION, version);
sprintf(alias + strlen(alias), "-e*");
alias_append(alias, sizeof_alias, "-e*");
if (flags & INPUT_DEVICE_ID_MATCH_EVBIT)
do_input(alias, *evbit, 0, INPUT_DEVICE_ID_EV_MAX);
sprintf(alias + strlen(alias), "k*");
do_input(alias, sizeof_alias, *evbit, 0, INPUT_DEVICE_ID_EV_MAX);
alias_append(alias, sizeof_alias, "k*");
if (flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
do_input(alias, *keybit,
do_input(alias, sizeof_alias, *keybit,
INPUT_DEVICE_ID_KEY_MIN_INTERESTING,
INPUT_DEVICE_ID_KEY_MAX);
sprintf(alias + strlen(alias), "r*");
alias_append(alias, sizeof_alias, "r*");
if (flags & INPUT_DEVICE_ID_MATCH_RELBIT)
do_input(alias, *relbit, 0, INPUT_DEVICE_ID_REL_MAX);
sprintf(alias + strlen(alias), "a*");
do_input(alias, sizeof_alias, *relbit, 0, INPUT_DEVICE_ID_REL_MAX);
alias_append(alias, sizeof_alias, "a*");
if (flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
do_input(alias, *absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
sprintf(alias + strlen(alias), "m*");
do_input(alias, sizeof_alias, *absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
alias_append(alias, sizeof_alias, "m*");
if (flags & INPUT_DEVICE_ID_MATCH_MSCIT)
do_input(alias, *mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
sprintf(alias + strlen(alias), "l*");
do_input(alias, sizeof_alias, *mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
alias_append(alias, sizeof_alias, "l*");
if (flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
do_input(alias, *ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
sprintf(alias + strlen(alias), "s*");
do_input(alias, sizeof_alias, *ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
alias_append(alias, sizeof_alias, "s*");
if (flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
do_input(alias, *sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
sprintf(alias + strlen(alias), "f*");
do_input(alias, sizeof_alias, *sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
alias_append(alias, sizeof_alias, "f*");
if (flags & INPUT_DEVICE_ID_MATCH_FFBIT)
do_input(alias, *ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
sprintf(alias + strlen(alias), "w*");
do_input(alias, sizeof_alias, *ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
alias_append(alias, sizeof_alias, "w*");
if (flags & INPUT_DEVICE_ID_MATCH_SWBIT)
do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX);
do_input(alias, sizeof_alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX);
module_alias_printf(mod, false, "input:%s", alias);
}
@ -895,12 +915,16 @@ static const struct dmifield {
{ NULL, DMI_NONE }
};
static void dmi_ascii_filter(char *d, const char *s)
static void dmi_ascii_filter(char *d, size_t avail, const char *s)
{
/* Filter out characters we don't want to see in the modalias string */
for (; *s; s++)
if (*s > ' ' && *s < 127 && *s != ':')
if (*s > ' ' && *s < 127 && *s != ':') {
if (avail <= 1)
fatal("%s: alias buffer overflow\n", __func__);
*(d++) = *s;
avail--;
}
*d = 0;
}
@ -909,6 +933,8 @@ static void dmi_ascii_filter(char *d, const char *s)
static void do_dmi_entry(struct module *mod, void *symval)
{
char alias[256] = {};
const size_t sizeof_alias = sizeof(alias);
size_t len;
int i, j;
DEF_FIELD_ADDR(symval, dmi_system_id, matches);
@ -916,11 +942,12 @@ static void do_dmi_entry(struct module *mod, void *symval)
for (j = 0; j < 4; j++) {
if ((*matches)[j].slot &&
(*matches)[j].slot == dmi_fields[i].field) {
sprintf(alias + strlen(alias), ":%s*",
dmi_fields[i].prefix);
dmi_ascii_filter(alias + strlen(alias),
alias_append(alias, sizeof_alias, ":%s*",
dmi_fields[i].prefix);
len = strlen(alias);
dmi_ascii_filter(alias + len, sizeof_alias - len,
(*matches)[j].substr);
strcat(alias, "*");
alias_append(alias, sizeof_alias, "*");
}
}
}

View File

@ -10,7 +10,7 @@ for pkg in $_extrapackages; do
pkgname+=("${pkgbase}-${pkg}")
done
pkgver="${KERNELRELEASE//-/_}"
pkgver="$(echo "${KERNELRELEASE}" | sed 's/-\(rc[0-9]\+\)/\1/;s/-/_/g')"
# The PKGBUILD is evaluated multiple times.
# Running scripts/build-version from here would introduce inconsistencies.
pkgrel="${KBUILD_REVISION}"