From owner-svn-src-head@freebsd.org Sun Jan 7 13:21:03 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4D559E6CFF4; Sun, 7 Jan 2018 13:21:03 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 288653099; Sun, 7 Jan 2018 13:21:03 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7C49421BA5; Sun, 7 Jan 2018 13:21:02 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w07DL2JZ064477; Sun, 7 Jan 2018 13:21:02 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w07DL2hN064072; Sun, 7 Jan 2018 13:21:02 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201801071321.w07DL2hN064072@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Sun, 7 Jan 2018 13:21:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r327674 - in head: share/man/man9 sys/kern sys/sys X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: in head: share/man/man9 sys/kern sys/sys X-SVN-Commit-Revision: 327674 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Jan 2018 13:21:03 -0000 Author: kp Date: Sun Jan 7 13:21:01 2018 New Revision: 327674 URL: https://svnweb.freebsd.org/changeset/base/327674 Log: Introduce mallocarray() in the kernel Similar to calloc() the mallocarray() function checks for integer overflows before allocating memory. It does not zero memory, unless the M_ZERO flag is set. Reviewed by: pfg, vangyzen (previous version), imp (previous version) Obtained from: OpenBSD Differential Revision: https://reviews.freebsd.org/D13766 Modified: head/share/man/man9/malloc.9 head/sys/kern/kern_malloc.c head/sys/sys/malloc.h Modified: head/share/man/man9/malloc.9 ============================================================================== --- head/share/man/man9/malloc.9 Sun Jan 7 10:29:15 2018 (r327673) +++ head/share/man/man9/malloc.9 Sun Jan 7 13:21:01 2018 (r327674) @@ -45,6 +45,8 @@ .In sys/malloc.h .Ft void * .Fn malloc "unsigned long size" "struct malloc_type *type" "int flags" +.Ft void * +.Fn mallocarray "size_t nmemb" "size_t size" "struct malloc_type *type" "int flags" .Ft void .Fn free "void *addr" "struct malloc_type *type" .Ft void * @@ -64,6 +66,14 @@ object whose size is specified by .Fa size . .Pp The +.Fn mallocarray +function allocates uninitialized memory in kernel address space for an +array of +.Fa nmemb +entries whose size is specified by +.Fa size . +.Pp +The .Fn free function releases memory at address .Fa addr @@ -152,6 +162,15 @@ functions cannot return if .Dv M_WAITOK is specified. +The +.Fn mallocarray +function can return +.Dv NULL +if the multiplication of +.Fa nmemb +and +.Fa size +would cause an integer overflow. .It Dv M_USE_RESERVE Indicates that the system can use its reserve of memory to satisfy the request. Modified: head/sys/kern/kern_malloc.c ============================================================================== --- head/sys/kern/kern_malloc.c Sun Jan 7 10:29:15 2018 (r327673) +++ head/sys/kern/kern_malloc.c Sun Jan 7 13:21:01 2018 (r327674) @@ -4,6 +4,7 @@ * Copyright (c) 1987, 1991, 1993 * The Regents of the University of California. * Copyright (c) 2005-2009 Robert N. M. Watson + * Copyright (c) 2008 Otto Moerbeek (mallocarray) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -532,6 +533,22 @@ malloc(unsigned long size, struct malloc_type *mtp, in va = redzone_setup(va, osize); #endif return ((void *) va); +} + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 8 / 2)) +void * +mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags) +{ + + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) + return (NULL); + + return (malloc(size * nmemb, type, flags)); } /* Modified: head/sys/sys/malloc.h ============================================================================== --- head/sys/sys/malloc.h Sun Jan 7 10:29:15 2018 (r327673) +++ head/sys/sys/malloc.h Sun Jan 7 13:21:01 2018 (r327674) @@ -177,6 +177,9 @@ void *contigmalloc(unsigned long size, struct malloc_t void free(void *addr, struct malloc_type *type); void *malloc(unsigned long size, struct malloc_type *type, int flags) __malloc_like __result_use_check __alloc_size(1); +void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type, + int flags) __malloc_like __result_use_check + __alloc_size(1) __alloc_size(2); void malloc_init(void *); int malloc_last_fail(void); void malloc_type_allocated(struct malloc_type *type, unsigned long size);