From: David Laight <david.laight.linux@gmail.com>
To: "Thomas Weißschuh" <linux@weissschuh.net>
Cc: Willy Tarreau <w@1wt.eu>,
linux-kernel@vger.kernel.org, Cheng Li <lechain@gmail.com>
Subject: Re: [PATCH v3 next 07/17] tools/nolibc/printf: Move snprintf length check to callback
Date: Wed, 25 Feb 2026 23:12:21 +0000 [thread overview]
Message-ID: <20260225231221.70b0531f@pumpkin> (raw)
In-Reply-To: <bcc3b413-e209-4d1c-ab3f-d33b467fe4c8@t-8ch.de>
On Wed, 25 Feb 2026 23:37:42 +0100
Thomas Weißschuh <linux@weissschuh.net> wrote:
> On 2026-02-23 10:17:25+0000, david.laight.linux@gmail.com wrote:
>
> (...)
>
> > @@ -425,18 +430,25 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
> >
> > /* literal char, just queue it */
> > }
> > +
> > + /* Request a final '\0' be added to the snprintf() output.
> > + * This may be the only call of the cb() function.
> > + */
> > + if (cb(state, NULL, 0) != 0)
> > + return -1;
> > +
> > return written;
> > }
>
> (...)
>
> > +static int __nolibc_sprintf_cb(void *v_state, const char *buf, size_t size)
> > {
> > - char **state = (char **)_state;
> > + struct __nolibc_sprintf_cb_state *state = v_state;
> > + size_t space = state->space;
> > + char *tgt;
> > +
> > + /* Truncate the request to fit in the output buffer space.
> > + * The last byte is reserved for the terminating '\0'.
> > + * state->space can only be zero for snprintf(NULL, 0, fmt, args)
> > + * so this normally lets through calls with 'size == 0'.
> > + */
> > + if (size >= space) {
> > + if (space <= 1)
> > + return 0;
> > + size = space - 1;
> > + }
> > + tgt = state->buf;
> > +
> > + /* __nolibc_printf() ends with cb(state, NULL, 0) to request the output
> > + * buffer be '\0' terminated.
> > + * That will be the only cb() call for, eg, snprintf(buf, sz, "").
> > + * Zero lengths can occur at other times (eg "%s" for an empty string).
> > + * Unconditionally write the '\0' byte to reduce code size, it is
> > + * normally overwritten by the data being output.
> > + * There is no point adding a '\0' after copied data - there is always
> > + * another call.
> > + */
> > + *tgt = '\0';
> > + state->space = space - size;
> > + state->buf = tgt + size;
> > + memcpy(tgt, buf, size);
>
> This trips UBSAN for me when 'buf == NULL'.
>
> if (cb(state, NULL, 0) != 0)
> return -1;
>
> It can be fixed by adding a NULL check around memcpy(),
> but I'd rather not do this as a random fixup.
Blame Willy, he made me remove the 'if (size)' check to reduce
the code size.
The '*tgt = 0' line is (only) needed when size is zero, the other lines
are clearly pointless.
So the 'random fixup' is adding 'if (size)' rather than a NULL
pointer check
printf("%s", "") will give a zero size with non-NULL buf.
IIRC the C standard make memcpy(tgt, NULL, 0) UB because some old system
no one has used for 40+ years would trap when NULL was loaded into an
'address register' and they wanted it to be compliant.
David
>
> >
> > - memcpy(*state, buf, size);
> > - *state += size;
> > return 0;
> > }
>
> (...)
next prev parent reply other threads:[~2026-02-25 23:12 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-23 10:17 [PATCH v3 next 00/17] Enhance printf() david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 01/17] tools/nolibc: Add _NOLIBC_OPTIMIZER_HIDE_VAR() to compiler.h david.laight.linux
2026-02-25 21:25 ` Thomas Weißschuh
2026-02-25 22:17 ` David Laight
2026-02-25 22:24 ` Thomas Weißschuh
2026-02-23 10:17 ` [PATCH v3 next 02/17] tools/nolibc: Optimise and common up the number to ascii functions david.laight.linux
2026-02-25 21:40 ` Thomas Weißschuh
2026-02-25 22:09 ` David Laight
2026-02-23 10:17 ` [PATCH v3 next 03/17] selftests/nolibc: Fix build with host headers and libc david.laight.linux
2026-02-25 21:24 ` Thomas Weißschuh
2026-02-23 10:17 ` [PATCH v3 next 04/17] selftests/nolibc: Improve reporting of vfprintf() errors david.laight.linux
2026-02-25 21:56 ` Thomas Weißschuh
2026-02-26 10:12 ` David Laight
2026-02-26 21:39 ` Thomas Weißschuh
2026-02-23 10:17 ` [PATCH v3 next 05/17] tools/nolibc: Implement strerror() in terms of strerror_r() david.laight.linux
2026-02-25 22:09 ` Thomas Weißschuh
2026-02-25 22:58 ` David Laight
2026-02-23 10:17 ` [PATCH v3 next 06/17] tools/nolibc/printf: Change variables 'c' to 'ch' and 'tmpbuf[]' to 'outbuf[]' david.laight.linux
2026-02-25 22:23 ` Thomas Weißschuh
2026-02-23 10:17 ` [PATCH v3 next 07/17] tools/nolibc/printf: Move snprintf length check to callback david.laight.linux
2026-02-25 22:37 ` Thomas Weißschuh
2026-02-25 23:12 ` David Laight [this message]
2026-02-26 21:29 ` Thomas Weißschuh
2026-02-26 22:11 ` David Laight
2026-02-23 10:17 ` [PATCH v3 next 08/17] tools/nolibc/printf: Output pad characters in 16 byte chunks david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 09/17] tools/nolibc/printf: Simplify __nolibc_printf() david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 10/17] tools/nolibc/printf: Use goto and reduce indentation david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 11/17] tools/nolibc/printf: Use bit-masks to hold requested flag, length and conversion chars david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 12/17] tools/nolibc/printf: Handle "%s" with the numeric formats david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 13/17] tools/nolibc/printf: Add support for conversion flags david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 14/17] tools/nolibc/printf: Add support for left aligning fields david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 15/17] tools/nolibc/printf: Add support for zero padding and field precision david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 16/17] tools/nolibc/printf: Add support for octal output david.laight.linux
2026-02-23 10:17 ` [PATCH v3 next 17/17] selftests/nolibc: Use printf variable field widths and precisions david.laight.linux
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260225231221.70b0531f@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=lechain@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@weissschuh.net \
--cc=w@1wt.eu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox