aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>2026-03-26 21:12:10 +0900
committerPetr Mladek <pmladek@suse.com>2026-05-05 10:19:15 +0200
commite56185668dc12983dd0e75e38ed6dea98b01d2d2 (patch)
tree52c5323d0156e16410ec2b3f97661f9166fccaf7 /lib
parent71876dffab295b6e25d4209f0424da8fc5020e12 (diff)
downloadlinux-next-history-e56185668dc12983dd0e75e38ed6dea98b01d2d2.tar.gz
lib/vsprintf: Limit the returning size to INT_MAX
The return value of vsnprintf() and bstr_printf() can overflow INT_MAX and return a minus value. In the @size is checked input overflow, but it does not check the output, which is expected required size. This should never happen but it should be checked and limited. Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Petr Mladek <pmladek@suse.com> Link: https://patch.msgid.link/177452713020.197965.3164174544083829000.stgit@devnote2 Signed-off-by: Petr Mladek <pmladek@suse.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/vsprintf.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 3c76cc5c7f9ce..6b1213d070b4c 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -2856,6 +2856,7 @@ static unsigned long long convert_num_spec(unsigned int val, int size, struct pr
int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
{
char *str, *end;
+ size_t ret_size;
struct printf_spec spec = {0};
struct fmt fmt = {
.str = fmt_str,
@@ -2975,8 +2976,12 @@ out:
}
/* the trailing null byte doesn't count towards the total */
- return str-buf;
+ ret_size = str - buf;
+ /* Make sure the return value is within the positive integer range */
+ if (WARN_ON_ONCE(ret_size > INT_MAX))
+ ret_size = INT_MAX;
+ return ret_size;
}
EXPORT_SYMBOL(vsnprintf);
@@ -3280,6 +3285,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt_str, const u32 *bin_buf)
struct printf_spec spec = {0};
char *str, *end;
const char *args = (const char *)bin_buf;
+ size_t ret_size;
if (WARN_ON_ONCE(size > INT_MAX))
return 0;
@@ -3428,7 +3434,12 @@ out:
#undef get_arg
/* the trailing null byte doesn't count towards the total */
- return str - buf;
+ ret_size = str - buf;
+
+ /* Make sure the return value is within the positive integer range */
+ if (WARN_ON_ONCE(ret_size > INT_MAX))
+ ret_size = INT_MAX;
+ return ret_size;
}
EXPORT_SYMBOL_GPL(bstr_printf);