From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6C1BC83F1A for ; Thu, 10 Jul 2025 23:24:54 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 793126B009D; Thu, 10 Jul 2025 19:24:54 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 7433A6B009E; Thu, 10 Jul 2025 19:24:54 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 680436B00A0; Thu, 10 Jul 2025 19:24:54 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 58DB96B009D for ; Thu, 10 Jul 2025 19:24:54 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id E12091A0965 for ; Thu, 10 Jul 2025 23:24:53 +0000 (UTC) X-FDA: 83649937266.16.BA21D7D Received: from nyc.source.kernel.org (nyc.source.kernel.org [147.75.193.91]) by imf30.hostedemail.com (Postfix) with ESMTP id 2FDFA80002 for ; Thu, 10 Jul 2025 23:24:52 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oEw4YreP; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf30.hostedemail.com: domain of alx@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=alx@kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1752189892; a=rsa-sha256; cv=none; b=vCO41g1S7YRNKIwMWXl5JCaZU6fpFICjJ1Pv16S4p9jQp1+p8Hiwwv4rRESXDTR3Gka6Zr r5jIQ9i8LEENyqyUvAMt1Hw+0CVF69W5duB0hSyGt2Cy12KMBw9yVfzkgbQI86OT9uC1oQ 0G+eKSeA2oIxmDqI4ppvz6JnTXZlQG8= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oEw4YreP; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf30.hostedemail.com: domain of alx@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=alx@kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1752189892; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=8Tm3ntCa/cpDFLceDFpG/gbGsJihNni0whe6V+msW3M=; b=eX3I3Ryoz1x79Ptx8ec+Ygf6Sqajq0Bw+s2/q6+mrCmeI2w5kJrdz9dTYMnHxEyrxutd62 hJJpeky0JFXRbRgxKHdMy0WpKZ06vpcXHFWpfCk69Fi3MnyXMHCV+8AiScSyRVvmaYuINS T0khbN0zC6TJhMS+rZpyGl2LjTwM0NA= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 7B0D5A53812; Thu, 10 Jul 2025 23:24:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id AD578C4CEE3; Thu, 10 Jul 2025 23:24:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1752189891; bh=yBhJ7jmYA0boZs71t+Q02sJpnvcmoh4aCEatyyAlf5o=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=oEw4YrePhrzELF6Pbe1r3IR3JZKbRp9kpd275ZM81ATAPD9FK+QPu7dzyUDcsmuth 5vwMlR07emlBd5TJYUa+Qbcq7NyDE4PekGUH8kYVY6d2+WBHOPaN2/UfeD3LHfog4a SCYoXz9dMA7OxWpmGhqGfA2yhN2KX9kSRQ3JfvF7A1eVdqTcAX5bDPnk+LyiYzkglw xTZH6gClj3GarPQHaRdWBGS1Rk+lizFbpQekWzKSWRRs75nI4WwX5HNU39bLIBjGkr CA3ZyBlcvBjuIfdgLspir3NumhiMsjGHaG2g9fVP7lTSFwP/hRgZKwpH9tHNA6E2mz tjxN179EdSgiA== Date: Fri, 11 Jul 2025 01:24:44 +0200 From: Alejandro Colomar To: Linus Torvalds Cc: linux-mm@kvack.org, linux-hardening@vger.kernel.org, Kees Cook , Christopher Bazley , shadow <~hallyn/shadow@lists.sr.ht>, linux-kernel@vger.kernel.org, Andrew Morton , kasan-dev@googlegroups.com, Dmitry Vyukov , Alexander Potapenko , Marco Elver , Christoph Lameter , David Rientjes , Vlastimil Babka , Roman Gushchin , Harry Yoo , Andrew Clayton , Rasmus Villemoes , Michal Hocko , Al Viro , Martin Uecker , Sam James , Andrew Pinski Subject: Re: [RFC v5 6/7] sprintf: Add [v]sprintf_array() Message-ID: References: <04c1e026a67f1609167e834471d0f2fe977d9cb0.1752182685.git.alx@kernel.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="6edp5zcpae764526" Content-Disposition: inline In-Reply-To: X-Rspam-User: X-Rspamd-Server: rspam01 X-Rspamd-Queue-Id: 2FDFA80002 X-Stat-Signature: eyaj34xdmc4b8sdko1bwywemzyth1t7b X-HE-Tag: 1752189892-120398 X-HE-Meta: U2FsdGVkX1/1V9n8XkFQ3yo2AsUg4d8gr9KL7Er8nTIBgBkzAkljpa2wayyusdtkokpIZndQOa326iWp2k8LF5/X2i3rtmwRlpmrjVHCsUDmMhCrvekb3tjiF3wq4/tBUABrsnQshFsDKpDoimRd1+sKH59mY5T5TSBmzLRej+xywpQKIA7r5EMH/8t8pVZrkzJhAsIKdFdXddRHyRSFzINrXkIW2tTelRcbLejCG0Z746jKh98IlrHJF5pXAWkn2EanL04XlR260FW2hYQRSjdgwz3oO8MLpvWti+7b66W3njbaDMq89fpgVe/bTjF+Bsh8fhssT2w64EmZmJJkH+u1dgs2U8m4yYccY84ss/jxooJlF/jADIlOi7Lscr94XUXo1vLltuynNxtYHXtz3yedOR3HHiLLe8E3suJgKWpaLtRdW/3fPn1JyGVgoFze5HgMiBDVAox4XcQcTjquJBG0J0rq/JXfCkS02IaJGY966bwNkOp2KKVTLibTj/h1v8BUg4oXsJFGdQOMqfqWUx+kwqQ9X7uu0BNkD2Y9CCX2EDbZJ8i9QVCd7BLNVI7tqsIP3fvrbXCu46taMiRctk4/qdSVqdp0VeYJ4NA3DDK8j+58Eq8Onw/9bmfla7VWSWIL112OY8UW5dZ1olces8ByE06pkd83fMJRFMPDPgJcFht3ZM0FyD7ImW6/1oVfbaxcUoKbItM6Vnn8lXn5WgfTDP0Og4RkK26YUELX/S3llk0DS9ll1T5UgGIynl5hgFarropZiRwO/jMJwN0dCQV0pUbYco6Q7d1jNEHfoeyh+wjiqqkcwnUPJsFLdSSij1/lq1OGVOKbRYnpHfwvmF59IsAyTThk3SzJlbjxxCDIihYjMbuN2jm0P7pfOI5Nsr+o4u+gyI9DqX01TeUTyQFPPQ8qdGDzeKMx2Xoa0RwbP94h9WOWv4WOocFB8p390mosnB0Zqql7rFay4t5 glZ3C/it IP3nHx86cmg2Z4nmUP5cdw3yUxdgFjaYX+w24UU/F422aVihdPQqhNB/rarSEaOTCAuOAKfDBl7GJQAkVVUmN6tFvPdoX8pZ+NSneVGs8rU8AfkN3+8bW5mgrkv9gPH7nR+HBZkBm5MQrzFQQY1UysfYYYwldeKlrqMxaWNrbXwNcDlUpm/mNba3w9NBVf6t6kHBUlod9XNdKlFKDqoNi1fg99zWA0nN2Mh0l/KFv/Us7eyaYd/c6cmjhKG3btDqZ3Diy9RP+shl/6FtFv17jwR38O/J0nxlTeC1P4VCc37h4YyHPBefSHKPyYOTt77BHAcd1yMhNWHLlrP+OvXn/b06hg9xJdZdFCB9b+eTFFwPEd0bXc8eNBPC1zoP/nXRUbdX/tBiB3/nnR1tIv6I6ztM6zULolTKNTXW7ppMaFjxoTCAKmAQcbL9AcbdRA0Akhzmbm1yvrVizg4ls0ja/Kny3lJyLTRtCEIPAnHEm1dAhqbRqryJjia4IeniQpreI1C8ZjzHtERqVHADltSfm9wXbAg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: --6edp5zcpae764526 Content-Type: text/plain; protected-headers=v1; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable From: Alejandro Colomar To: Linus Torvalds Cc: linux-mm@kvack.org, linux-hardening@vger.kernel.org, Kees Cook , Christopher Bazley , shadow <~hallyn/shadow@lists.sr.ht>, linux-kernel@vger.kernel.org, Andrew Morton , kasan-dev@googlegroups.com, Dmitry Vyukov , Alexander Potapenko , Marco Elver , Christoph Lameter , David Rientjes , Vlastimil Babka , Roman Gushchin , Harry Yoo , Andrew Clayton , Rasmus Villemoes , Michal Hocko , Al Viro , Martin Uecker , Sam James , Andrew Pinski Subject: Re: [RFC v5 6/7] sprintf: Add [v]sprintf_array() References: <04c1e026a67f1609167e834471d0f2fe977d9cb0.1752182685.git.alx@kernel.org> MIME-Version: 1.0 In-Reply-To: On Fri, Jul 11, 2025 at 01:23:56AM +0200, Alejandro Colomar wrote: > Hi Linus, >=20 > [I'll reply to both of your emails at once] >=20 > On Thu, Jul 10, 2025 at 02:58:24PM -0700, Linus Torvalds wrote: > > You took my suggestion, and then you messed it up. > >=20 > > Your version of sprintf_array() is broken. It evaluates 'a' twice. > > Because unlike ARRAY_SIZE(), your broken ENDOF() macro evaluates the > > argument. >=20 > An array has no issue being evaluated twice (unless it's a VLA). On the > other hand, I agree it's better to not do that in the first place. > My bad for forgetting about it. Sorry. >=20 > On Thu, Jul 10, 2025 at 03:08:29PM -0700, Linus Torvalds wrote: > > If you want to return an error on truncation, do it right. Not by > > returning NULL, but by actually returning an error. >=20 > Okay. >=20 > > For example, in the kernel, we finally fixed 'strcpy()'. After about a > > million different versions of 'copy a string' where every single > > version was complete garbage, we ended up with 'strscpy()'. Yeah, the > > name isn't lovely, but the *use* of it is: >=20 > I have implemented the same thing in shadow, called strtcpy() (T for > truncation). (With the difference that we read the string twice, since > we don't care about threads.) >=20 > I also plan to propose standardization of that one in ISO C. >=20 > > - it returns the length of the result for people who want it - which > > is by far the most common thing people want >=20 > Agree. >=20 > > - it returns an actual honest-to-goodness error code if something > > overflowed, instead of the absoilutely horrible "source length" of the > > string that strlcpy() does and which is fundamentally broken (because > > it requires that you walk *past* the end of the source, > > Christ-on-a-stick what a broken interface) >=20 > Agree. >=20 > > - it can take an array as an argument (without the need for another > > name - see my earlier argument about not making up new names by just > > having generics) >=20 > We can't make the same thing with sprintf() variants because they're > variadic, so you can't count the number of arguments. And since the > 'end' argument is of the same type as the formatted string, we can't > do it with _Generic reliably either. >=20 > > Now, it has nasty naming (exactly the kind of 'add random character' > > naming that I was arguing against), and that comes from so many > > different broken versions until we hit on something that works. > >=20 > > strncpy is horrible garbage. strlcpy is even worse. strscpy actually > > works and so far hasn't caused issues (there's a 'pad' version for the > > very rare situation where you want 'strncpy-like' padding, but it > > still guarantees NUL-termination, and still has a good return value). >=20 > Agree. >=20 > > Let's agree to *not* make horrible garbage when making up new versions > > of sprintf. >=20 > Agree. I indeed introduced the mistake accidentally in v4, after you > complained of having too many functions, as I was introducing not one > but two APIs: seprintf() and stprintf(), where seprintf() is what now > we're calling sprintf_end(), and stprintf() we could call it > sprintf_trunc(). So I did the mistake by trying to reduce the number of > functions to just one, which is wrong. >=20 > So, maybe I should go back to those functions, and just give them good > names. >=20 > What do you think of the following? >=20 > #define sprintf_array(a, ...) sprintf_trunc(a, ARRAY_SIZE(a), __VA_ARGS= __) > #define vsprintf_array(a, ap) vsprintf_trunc(a, ARRAY_SIZE(a), ap) >=20 > char *sprintf_end(char *p, const char end[0], const char *fmt, ...); > char *vsprintf_end(char *p, const char end[0], const char *fmt, va_list = args); > int sprintf_trunc(char *buf, size_t size, const char *fmt, ...); > int vsprintf_trunc(char *buf, size_t size, const char *fmt, va_list args= ); >=20 > char *sprintf_end(char *p, const char end[0], const char *fmt, ...) > { > va_list args; >=20 > va_start(args, fmt); > p =3D vseprintf(p, end, fmt, args); Typo here. It's vsprintf_end(). > va_end(args); >=20 > return p; > } >=20 > char *vsprintf_end(char *p, const char end[0], const char *fmt, va_list = args) > { > int len; >=20 > if (unlikely(p =3D=3D NULL)) > return NULL; >=20 > len =3D vsprintf_trunc(p, end - p, fmt, args); > if (unlikely(len < 0)) > return NULL; >=20 > return p + len; > } >=20 > int sprintf_trunc(char *buf, size_t size, const char *fmt, ...) > { > va_list args; > int len; >=20 > va_start(args, fmt); > len =3D vstprintf(buf, size, fmt, args); Typo here. It's vsprintf_trunc(). > va_end(args); >=20 > return len; > } >=20 > int vsprintf_trunc(char *buf, size_t size, const char *fmt, va_list args) > { > int len; >=20 > if (WARN_ON_ONCE(size =3D=3D 0 || size > INT_MAX)) > return -EOVERFLOW; >=20 > len =3D vsnprintf(buf, size, fmt, args); > if (unlikely(len >=3D size)) > return -E2BIG; >=20 > return len; > } >=20 > sprintf_trunc() is like strscpy(), but with a formatted string. It > could replace uses of s[c]nprintf() where there's a single call (no > chained calls). >=20 > sprintf_array() is like the 2-argument version of strscpy(). It could > replace s[c]nprintf() calls where there's no chained calls, where the > input is an array. >=20 > sprintf_end() would replace the chained calls. >=20 > Does this sound good to you? >=20 >=20 > Cheers, > Alex >=20 > --=20 > --=20 --6edp5zcpae764526 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmhwS7wACgkQ64mZXMKQ wqlOQxAAqQqG5Z7+Xh1jkMiJqhKKnJ4dTK0nc7NVJNqdOHZBJCjt7CCvZulq+QO5 TAKjjj5aaK3ZA+XB42UNR6cya6aL88fDOr4d6srebkLTkGoEXnjBN/VWardd8z2d Iq8z4UsaxfDDA8OQVz2lbcnFxA2KSszs9SwsP0mZZXjCZSdrIKqguPaexaJ1ZSkC IML9PzRqUqm9KbJn9qroGTx5DWRg2hf/q+T6PxCjzU+DDQL7mh1+XHgL3EXL1s4Y 9+DnXRe+s9VJ8A/TcAwlbdZO99Cp4YpnNJP+m8y0wOJpOgIwlk51hbGGZ2U+jIU9 nISZk+EZTERJLqU06PVPp3wVyWhxTqVIcbxhQTGKGumltTWaHu2i2yI/RkoMLL/c FRm8AnuO4X874TUc9JJTCq9ycz0BAv8YRmbNDmZoVcm8XhBzKVPo03h1LOm/kTnq +seYP9mJz6BiFwSXok60CZrsflPlaob3z3tFnMgwG/7qXwMnS6gW3FDRMFMuPVCf 7vmiDiXMOf0sjwYzM0AYDqqWaGDloWBxU0KwUH0e9+Tp/mDxJbaCxr/1G7fyX3QL QtRd6yUURufITU56DsxEJYx9PkDdheYm9JI91ZFHEajSrR0FzQd+SwcNivSk6q8p fYtGfPwriq8GxHRzTxeYlCWcy2YKIhb63RLIRNuIgcDyDZ+EKhc= =icSd -----END PGP SIGNATURE----- --6edp5zcpae764526--