From: Linus Torvalds Date: Mon, 23 Dec 2024 19:34:32 +0000 (-0800) Subject: vsprintf: don't make the 'binary' version pack small integer arguments X-Git-Tag: v6.14-rc1~221^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4c538044ee2d11299cc57ac1e92d343e1e83b847;p=thirdparty%2Fkernel%2Flinux.git vsprintf: don't make the 'binary' version pack small integer arguments The strange vbin_printf / bstr_printf interface used to save one- and two-byte printf numerical arguments into their packed format. That's more than a bit strange since the argument buffer is supposed to be an array of 'u32' words, and it's also very different from how the source of the data (varargs) work - which always do the normal integer type conversions, so 'char' and 'short' are always passed as int-sized anyway. This odd packing causes extra code complexity, and it really isn't worth it, since the space savings are simply not there: it only happens for formats like '%hd' (short) and '%hhd' (char), which are very rare indeed. In fact, the only other user of this interface seems to be the bpf helper code (bpf_bprintf_prepare()), and Alexei points out that that case doesn't support those truncated integer formatting options at all in the first place. As a result, bpf_bprintf_prepare() doesn't need any changes for this, and TRACE_BPRINT uses 'vbin_printf()' -> 'bstr_printf()' for the formatting and hopefully doesn't expose the odd packing any other way (knock wood). Link: https://lore.kernel.org/all/CAADnVQJy65oOubjxM-378O3wDfhuwg8TGa9hc-cTv6NmmUSykQ@mail.gmail.com/ Signed-off-by: Linus Torvalds --- diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7a40c8ae2d190..a49bb6eb24350 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -3137,17 +3137,9 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt_str, va_list args) break; case FORMAT_STATE_NUM: - switch (fmt.size) { - case 8: + if (fmt.size > sizeof(int)) { save_arg(long long); - break; - case 1: - save_arg(char); - break; - case 2: - save_arg(short); - break; - default: + } else { save_arg(int); } } @@ -3318,23 +3310,14 @@ int bstr_printf(char *buf, size_t size, const char *fmt_str, const u32 *bin_buf) goto out; case FORMAT_STATE_NUM: - switch (fmt.size) { - case 8: + if (fmt.size > sizeof(int)) { num = get_arg(long long); - break; - case 1: - num = convert_num_spec(get_arg(char), fmt.size, spec); - break; - case 2: - num = convert_num_spec(get_arg(short), fmt.size, spec); - break; - default: + } else { num = convert_num_spec(get_arg(int), fmt.size, spec); - break; } + str = number(str, end, num, spec); + continue; } - - str = number(str, end, num, spec); } /* while(*fmt.str) */ out: