X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 492FJI84027713 Authentication-Results: delorie.com; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=XYsl/Q+5 X-Recipient: djgpp AT delorie DOT com X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727882356; x=1728487156; darn=delorie.com; h=content-transfer-encoding:in-reply-to:content-language:references :to:from:subject:user-agent:mime-version:date:message-id:from:to:cc :subject:date:message-id:reply-to; bh=zicKv3JWxIVEL1TFmW54NEqbHr2ivQpQ7e5+O1euun0=; b=XYsl/Q+5dD+YZZOBNRRLIMxUlYYkRMTawnnovt/G4K5Jx6M9ZVmS3k99sKh4nVu3qS GCwxazqzXbSWryXDszAr6AXPD6V55OOT5Lb9UGTg/01rhjNzO3/j4B7K9lC8SL7OJrDx hRpNtleA54wsj97MKNAvjHaAAPXIfroy+Js8TD6CXlkBClExBrI5QliZKNx61Gw750yu eli7upGdxto5OhqW1dyHEOlY40UJoLqRG625hN1OtqO0n2+EMkVQiZI+VNnOVISxbebi mLlQuuY0XaACZYWLws+c7tPdEbUcbJSC0YWbzJu5s+L8T7WHkO7bsXPZQcDZUDoqMHLT /Img== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727882356; x=1728487156; h=content-transfer-encoding:in-reply-to:content-language:references :to:from:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zicKv3JWxIVEL1TFmW54NEqbHr2ivQpQ7e5+O1euun0=; b=tyARgjcLOu9i2FMIPenxOVCZxD1/TGfjxLVw0DlFwsp1FVz94G7HdIksuEgmGWgJGm Pof7Ea+UhnzlqsFNVKZnVKgelukwu6Pd4JPko2amoC8yLQc6nwbLPAw5f/U1aXGw+seK 0cdHU2qKC53zSGNT1stslkGPVqSInL92DXAM/GAmNvEyzHEmt0iPKomtRZI0/ozeojR1 gARMKZfr0JmFKKONEbmRFQy5/nuvCkZp7zbaTpC8k5XY7Hey8g7cX34svXfSR7o8hg8i F1KIQnB0Qdl8TvZJ6ZMo1A0FNiH4MlOQYHSixzf1xeElTkspV+7Vygn9i2m4MtdtKM33 6l/g== X-Gm-Message-State: AOJu0Yx+hQzKI8/4u2LxmUIX7DbjLdzLfUEdpk8+kgGSYSTiYiCLeSWs +ujrln4LQ9/UHph1ubv3AzZjIfW90REiSZM4DVecI1c4cXsjp4WHG2d4uA== X-Google-Smtp-Source: AGHT+IFId1oEg7K2kOGdMBTv+Y8cIGc+PH/NGq6wYNuKpcSOGs3b4coD9Jnq8KnC12roTwfiBuAerA== X-Received: by 2002:a17:907:98c:b0:a93:d181:b7fc with SMTP id a640c23a62f3a-a98f836eeaamr332323266b.51.1727882356257; Wed, 02 Oct 2024 08:19:16 -0700 (PDT) Message-ID: Date: Wed, 2 Oct 2024 17:19:15 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: malloc clobbers sbrk'd memory From: "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" To: djgpp AT delorie DOT com References: <7d97575b-24ac-4d55-be14-266ade57b992 AT gmail DOT com> Content-Language: en-US In-Reply-To: <7d97575b-24ac-4d55-be14-266ade57b992@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On 2024-10-01 22:57, J.W. Jagersma wrote: > I believe I found a bug where malloc sporadically writes past the end > of a memory chunk. > > I ran into this while working on mcount, which allocates the histogram > and call graph via sbrk. When my test program was invoked with some > specific number of arguments, the first histogram entry was clobbered, > which in gprof appeared as if the program had spent a lot of time in > 'start'. Turns out: the clobber value is the same as the special 'NONE' > pointer used in nmalloc.c. > > What I believe is happening: the minimum chunk size created by > __nmalloc_split is DATAOFFSET (which is sizeof(memblock)-4; does *not* > include prevfree). But when the high half is then passed to > mv2freelist, it writes prevfree=NONE, which is now past the end of the > chunk. > > Solution is probably to define MINSAVE as (ALIGN + sizeof (memblock)), > regardless of SAVEMEMORY tricks. It might be worth adding another 16 > bytes or so, since minimum-size chunks are useless and only add clutter > to the freelist. Some further analysis: MINSAVE includes room for alignment, and headers don't require re-alignment after split, so there *should* be enough space for 'prevfree' (and ALIGN is then also the minimum allocation size). There is one point where nmalloc can split off a too-small block, which is when allocating directly from 'lastsbrk' (at nmalloc.c:570). Here DATAOFFSET is the minimum size. The bug then occurs on the next extendsbrk. Because the other sbrk call left a gap, the new block is not merged with 'lastsbrk', but instead it calls mv2freelist(lastsbrk). And at that point, 'prevfree' can overlap with the sbrk'd memory.