From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52212318B86 for ; Wed, 25 Feb 2026 22:37:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772059065; cv=none; b=SwPbj2tVn8BLtx6vAC+U1Y61ON3SGrOtSda5bYQe4w0SumIyu0WGTzI7uUvtm00hnT3KM5KjM07hcHjNfgrdAFEeHe/Kf8nwDE2ZG+Hn7mRJ5tRQQ8/RQQvfRHkdJ5ghDqzF1oYFX/1znPwEpZd9wJgSpcCc1Okp3+OFayGMxi8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772059065; c=relaxed/simple; bh=nxjoctDUeNJ9qeyRtQCWjRq9I7qZub4t3uqsrAoAl8Y=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=rQSn9YD/qmosJ28RapsfRxM5UzNnyqGhbBXHNNKqFpfPI1hfbQuAgKFIPe/2jHt+Z/fX0QaHOtt4DsdrFmin8Cgb59YA64v0jq6uAGHYEsS/1kah2eYPIVPJxXiV6IHZbmLaPgxLQoo+MKNTEDcTFEgDOADbf8fTgNWq55nawFc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=lE1FVs+T; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="lE1FVs+T" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1772059062; bh=nxjoctDUeNJ9qeyRtQCWjRq9I7qZub4t3uqsrAoAl8Y=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=lE1FVs+TVBTon6pXklZSL8yx7dwg86hJXm917E337J88fbFStfvoQGtZnuVNcRCCf sbInXLT6odS23tFJB1swVq1JcD1N5EoFB5oJDJHU6UIf53oWPUAnVgiepQO2ejzS9r gxkvhgqXYsY45foVwOCkrePmr7Gzy27GOSd5DA1U= Date: Wed, 25 Feb 2026 23:37:42 +0100 From: Thomas =?utf-8?Q?Wei=C3=9Fschuh?= To: david.laight.linux@gmail.com Cc: Willy Tarreau , linux-kernel@vger.kernel.org, Cheng Li Subject: Re: [PATCH v3 next 07/17] tools/nolibc/printf: Move snprintf length check to callback Message-ID: References: <20260223101735.2922-1-david.laight.linux@gmail.com> <20260223101735.2922-8-david.laight.linux@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260223101735.2922-8-david.laight.linux@gmail.com> 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. > > - memcpy(*state, buf, size); > - *state += size; > return 0; > } (...)