From patchwork Fri Dec 16 20:15:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 62017 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 139393836793 for ; Fri, 16 Dec 2022 20:16:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 139393836793 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1671221777; bh=0DK0CrT4QQmYEebMAYoNOpHeM+r2NIIu8vkWHMpZoI8=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XsbZQiEV3+ZPgpriwTDi8SgN4TtQrUudnb0B8cl7RMA4yicKOxNfn5Ks+ev2NW9ch fYYXYx+NXLWKC58X6GLSso90NXhN7By+cg35F05uplT+kkdiFvRz+mToBtQTgZxqor 0IPSe81VZe293frDpuJ6qcRFW3FAWmCKQr5tkt4M= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id A684F384F71E for ; Fri, 16 Dec 2022 20:15:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A684F384F71E Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-480-mJzoy38MPzup-C7-pApyRw-1; Fri, 16 Dec 2022 15:15:39 -0500 X-MC-Unique: mJzoy38MPzup-C7-pApyRw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id ED4EA2801E53 for ; Fri, 16 Dec 2022 20:15:38 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.2.16.61]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 20CEE14171C0 for ; Fri, 16 Dec 2022 20:15:38 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH v6 07/11] libio: Convert __vsprintf_internal to buffers In-Reply-To: References: X-From-Line: e6733845da90c1608edbe715049f62317782832f Mon Sep 17 00:00:00 2001 Message-Id: Date: Fri, 16 Dec 2022 21:15:36 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.1 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Reviewed-by: Adhemerval Zanella --- elf/Makefile | 1 - include/printf_buffer.h | 2 + libio/iovsprintf.c | 70 ++++++++---------------------- stdio-common/printf_buffer_flush.c | 4 ++ 4 files changed, 24 insertions(+), 53 deletions(-) diff --git a/elf/Makefile b/elf/Makefile index ea64d8a470..6d566a4ff4 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -603,7 +603,6 @@ $(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \ --required=_IO_obstack_jumps \ --required=_IO_printf_buffer_as_file_jumps \ --required=_IO_proc_jumps \ - --required=_IO_str_chk_jumps \ --required=_IO_str_jumps \ --required=_IO_wfile_jumps \ --required=_IO_wfile_jumps_maybe_mmap \ diff --git a/include/printf_buffer.h b/include/printf_buffer.h index 39ef232587..cc9f8e5346 100644 --- a/include/printf_buffer.h +++ b/include/printf_buffer.h @@ -45,7 +45,9 @@ enum __printf_buffer_mode { __printf_buffer_mode_failed, + __printf_buffer_mode_sprintf, __printf_buffer_mode_snprintf, + __printf_buffer_mode_sprintf_chk, __printf_buffer_mode_to_file, __printf_buffer_mode_strfmon, __printf_buffer_mode_fp, /* For __printf_fp_l_buffer. */ diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index 72c67bf27b..7305d8e247 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -25,58 +25,18 @@ in files containing the exception. */ #include "libioP.h" -#include "strfile.h" -static int __THROW -_IO_str_chk_overflow (FILE *fp, int c) -{ - /* If we get here, the user-supplied buffer would be overrun by - further output. */ - __chk_fail (); -} - -static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable = -{ - JUMP_INIT_DUMMY, - JUMP_INIT(finish, _IO_str_finish), - JUMP_INIT(overflow, _IO_str_chk_overflow), - JUMP_INIT(underflow, _IO_str_underflow), - JUMP_INIT(uflow, _IO_default_uflow), - JUMP_INIT(pbackfail, _IO_str_pbackfail), - JUMP_INIT(xsputn, _IO_default_xsputn), - JUMP_INIT(xsgetn, _IO_default_xsgetn), - JUMP_INIT(seekoff, _IO_str_seekoff), - JUMP_INIT(seekpos, _IO_default_seekpos), - JUMP_INIT(setbuf, _IO_default_setbuf), - JUMP_INIT(sync, _IO_default_sync), - JUMP_INIT(doallocate, _IO_default_doallocate), - JUMP_INIT(read, _IO_default_read), - JUMP_INIT(write, _IO_default_write), - JUMP_INIT(seek, _IO_default_seek), - JUMP_INIT(close, _IO_default_close), - JUMP_INIT(stat, _IO_default_stat), - JUMP_INIT(showmanyc, _IO_default_showmanyc), - JUMP_INIT(imbue, _IO_default_imbue) -}; - -/* This function is called by regular vsprintf with maxlen set to -1, - and by vsprintf_chk with maxlen set to the size of the output - string. In the former case, _IO_str_chk_overflow will never be - called; in the latter case it will crash the program if the buffer - overflows. */ +#include +#include +#include int __vsprintf_internal (char *string, size_t maxlen, const char *format, va_list args, unsigned int mode_flags) { - _IO_strfile sf; - int ret; + struct __printf_buffer buf; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); /* When called from fortified sprintf/vsprintf, erase the destination buffer and try to detect overflows. When called from regular sprintf/vsprintf, do not erase the destination buffer, because @@ -84,19 +44,25 @@ __vsprintf_internal (char *string, size_t maxlen, by ISO C), nor try to detect overflows. */ if ((mode_flags & PRINTF_CHK) != 0) { - _IO_JUMPS (&sf._sbf) = &_IO_str_chk_jumps; string[0] = '\0'; + __printf_buffer_init (&buf, string, maxlen, + __printf_buffer_mode_sprintf_chk); } else - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, string, - (maxlen == -1) ? -1 : maxlen - 1, - string); + { + __printf_buffer_init (&buf, string, 0, __printf_buffer_mode_sprintf); + buf.write_end = (char *) ~(uintptr_t) 0; /* End of address space. */ + } + + __printf_buffer (&buf, format, args, mode_flags); - ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags); + /* Write the NUL terminator if there is room. Do not use the putc + operation to avoid overflowing the character write count. */ + if ((mode_flags & PRINTF_CHK) != 0 && buf.write_ptr == buf.write_end) + __chk_fail (); + *buf.write_ptr = '\0'; - *sf._sbf._f._IO_write_ptr = '\0'; - return ret; + return __printf_buffer_done (&buf); } int diff --git a/stdio-common/printf_buffer_flush.c b/stdio-common/printf_buffer_flush.c index bfd1f9d733..f44c8b887f 100644 --- a/stdio-common/printf_buffer_flush.c +++ b/stdio-common/printf_buffer_flush.c @@ -38,10 +38,14 @@ __printf_buffer_do_flush (struct __printf_buffer *buf) switch (buf->mode) { case __printf_buffer_mode_failed: + case __printf_buffer_mode_sprintf: return; case __printf_buffer_mode_snprintf: __printf_buffer_flush_snprintf ((struct __printf_buffer_snprintf *) buf); return; + case __printf_buffer_mode_sprintf_chk: + __chk_fail (); + break; case __printf_buffer_mode_to_file: __printf_buffer_flush_to_file ((struct __printf_buffer_to_file *) buf); return;