From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 3600 invoked from network); 1 Aug 2020 17:46:57 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 1 Aug 2020 17:46:57 -0000 Received: (qmail 23687 invoked by uid 550); 1 Aug 2020 17:46:55 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 23669 invoked from network); 1 Aug 2020 17:46:54 -0000 Date: Sat, 1 Aug 2020 13:46:41 -0400 From: Rich Felker To: musl@lists.openwall.com Message-ID: <20200801174640.GX6949@brightrain.aerifal.cx> References: <20200801144658.6634-1-ariadne@dereferenced.org> <20200801155228.GC2076@voyager> <2402240.lMG0q3WddN@petrie> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <2402240.lMG0q3WddN@petrie> User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] [PATCH] implement recallocarray(3) On Sat, Aug 01, 2020 at 10:23:35AM -0600, Ariadne Conill wrote: > On Saturday, 1 August 2020 09:52:28 MDT Markus Wichmann wrote: > > On Sat, Aug 01, 2020 at 08:46:58AM -0600, Ariadne Conill wrote: > > > +void *recallocarray(void *ptr, size_t om, size_t m, size_t n) > > > +{ > > > + void *newptr; > > > + size_t old_size, new_size; > > > + > > > + if (n && m > -1 / n) { > > > + errno = ENOMEM; > > > + return 0; > > > + } > > > + new_size = m * n; > > > + > > > + if (n && om > -1 / n) { > > > + errno = EINVAL; > > > + return 0; > > > + } > > > + old_size = om * n; > > > + > > > + if (new_size <= old_size) { > > > + memset((char *) ptr + new_size, 0, old_size - new_size); > > > + } > > > + > > > + newptr = reallocarray(ptr, m, n); > > > + if (new_size > old_size) { > > > + memset((char *) ptr + old_size, 0, new_size - old_size); > > > + } > > > + > > > + return newptr; > > > +} > > > > Is there a reason for the call to reallocarray? The multiplication m * n > > has already been tested for overflow and executed at that point. Might > > as well just call realloc() there, right? > > Good catch. I decided to use reallocarray() simply for clarity, but I can > change it to a realloc() call. I'm also confused why the old size has to be checked at all. There's inherently a contract that the old size be correct for the existing allocation; if it's not, the wrong number of members will be zeroed. Checking whether om*n overflows does not change this and does not catch the more general case where om is wrong. Is the EINVAL behavior from OpenBSD, and if so, do they have a rationale for it? Rich