From patchwork Thu Feb 12 19:15:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 130046 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 305244BA23FD for ; Thu, 12 Feb 2026 19:15:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 305244BA23FD Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RWzmKQ/o 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 ESMTP id 4A6C74BA2E12 for ; Thu, 12 Feb 2026 19:15:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4A6C74BA2E12 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4A6C74BA2E12 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770923707; cv=none; b=J4cv6DV2dhRrwonKVr1Jum/tjYWFkn6cagWVfvtxFyh5NpA+MdFAF7VAXggqvCWKK3mLow50LsihSN+dOaBVtacG1UV2CXmoQY+O0+iaSWJfRSWeuo5IrS5fryXu0KuDp0BXnYzEHv33jb0lI+B6W3Yy3+wOY+JUiy8MjprS7eQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770923707; c=relaxed/simple; bh=jHEuYDW/DgLc5SA3RWdCfajaqsbbfGto4RSJu/cukn4=; h=DKIM-Signature:Date:Message-Id:From:To:Subject; b=jycQ2GfmTUBFUWB7KQ7LSGltCJp4S9lF5fmpyGe9lerlCDs7vWVEDiSsAYYyf1EK0gY3BNsB1oNNbeWJupifOw3KlNSXhYSmLFLcyZW8sF0FtvclUOUs0+bKQC0Jxj4uVHBp57rCf/MPu4LbboqD9dnzOgQEdWv2zHRC1YtSEcE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4A6C74BA2E12 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770923706; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type; bh=p7GS7Mv/JLEQrXS49H/EQ9wGahmkQFGQ7Z8clQNg1S8=; b=RWzmKQ/o8oQMUf1nk3JzGMCHiW1FV26h4Ayomd2Se9PxfdqHgDaDSkC60wSlXoGR2bQr40 TXxPpF+MJ8mxw97JkPBqxlUuB5bwHNNacI6SSDoiinAY88wOfkbdnouBwcbR7X2IVRFKrT EMxFhRQC01tbzCRm+KzhG2rbNsGReno= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-284--TKKhDkdOTGsB5WarRgsNw-1; Thu, 12 Feb 2026 14:15:05 -0500 X-MC-Unique: -TKKhDkdOTGsB5WarRgsNw-1 X-Mimecast-MFC-AGG-ID: -TKKhDkdOTGsB5WarRgsNw_1770923704 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CB0AE1955D8F for ; Thu, 12 Feb 2026 19:15:04 +0000 (UTC) Received: from greed.delorie.com (unknown [10.22.89.244]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7BFDF19560B9 for ; Thu, 12 Feb 2026 19:15:04 +0000 (UTC) Received: from greed.delorie.com.redhat.com (localhost [127.0.0.1]) by greed.delorie.com (8.16.1/8.16.1) with ESMTP id 61CJF2EA1175552 for ; Thu, 12 Feb 2026 14:15:02 -0500 Date: Thu, 12 Feb 2026 14:15:02 -0500 Message-Id: From: DJ Delorie To: libc-alpha@sourceware.org Subject: [patch v1] malloc: add malloc_zero_aborts tunable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Q2vS0wI0pN6CTBzWSO30TCR3KFXp1MeQLt7kEpmuM2I_1770923704 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-10.5 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_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Given the recent discussions on this topic, I thought it would be useful (and/or fun) to give users a way to turn "implementation defined" into "will crash immediately." I included realloc but could make that separate. I'll do manual updates and figure out tail recursion if we decide we even want this ;-) malloc: add malloc_zero_aborts tunable If set (ex: GLIBC_TUNABLES=glibc.malloc.malloc_zero_aborts=1) then any call of malloc(0) or realloc(ptr,0) will immediately abort. diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 040a544c0e..20c0659ad0 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -79,6 +79,10 @@ glibc { type: SIZE_T minval: 0 } + malloc_zero_aborts { + type: SIZE_T + minval: 0 + } } rtld { diff --git a/malloc/arena.c b/malloc/arena.c index cabeb0d8ce..cddc0951ec 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -240,6 +240,7 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t) TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t) #endif TUNABLE_CALLBACK_FNDECL (set_hugetlb, size_t) +TUNABLE_CALLBACK_FNDECL (set_malloc_zero_aborts, size_t) #if USE_TCACHE static void tcache_key_initialize (void); @@ -291,6 +292,7 @@ __ptmalloc_init (void) TUNABLE_GET (tcache_count, size_t, TUNABLE_CALLBACK (set_tcache_count)); # endif TUNABLE_GET (hugetlb, size_t, TUNABLE_CALLBACK (set_hugetlb)); + TUNABLE_GET (malloc_zero_aborts, size_t, TUNABLE_CALLBACK (set_malloc_zero_aborts)); if (mp_.hp_pagesize > 0 && mp_.hp_pagesize <= heap_max_size ()) { diff --git a/malloc/malloc.c b/malloc/malloc.c index 0ff016e549..431c770325 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1798,6 +1798,8 @@ struct malloc_par /* Maximum number of chunks in each bucket. */ size_t tcache_count; #endif + + size_t malloc_zero_aborts; }; /* There are several instances of this struct ("arenas") in this @@ -1823,6 +1825,7 @@ static struct malloc_par mp_ = .trim_threshold = DEFAULT_TRIM_THRESHOLD, #define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8)) .arena_test = NARENAS_FROM_NCORES (1), + .malloc_zero_aborts = 0, .thp_mode = malloc_thp_mode_not_supported #if USE_TCACHE , @@ -3295,6 +3298,9 @@ __libc_malloc2 (size_t bytes) void * __libc_malloc (size_t bytes) { + if (bytes == 0 && mp_.malloc_zero_aborts) + abort(); + #if USE_TCACHE size_t nb = checked_request2size (bytes); @@ -3401,6 +3407,9 @@ __libc_realloc (void *oldmem, size_t bytes) if (oldmem == NULL) return __libc_malloc (bytes); + if (bytes == 0 && mp_.malloc_zero_aborts) + abort(); + #if REALLOC_ZERO_BYTES_FREES if (bytes == 0) { @@ -5078,6 +5087,13 @@ do_set_hugetlb (size_t value) return 0; } +static __always_inline int +do_set_malloc_zero_aborts (size_t value) +{ + mp_.malloc_zero_aborts = value; + return 0; +} + int __libc_mallopt (int param_number, int value) {