From patchwork Thu Oct 10 12:26:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Newton X-Patchwork-Id: 20935 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f199.google.com (mail-ie0-f199.google.com [209.85.223.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5E29C25C9D for ; Thu, 10 Oct 2013 12:26:27 +0000 (UTC) Received: by mail-ie0-f199.google.com with SMTP id ar20sf9123534iec.10 for ; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:message-id:date:from:user-agent :mime-version:to:cc:subject:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=O9yCKGNe/IqLOMBQpRPziXL174iiSi6/8W9pY0bSEKI=; b=VbvqQoGwR5iCXCAaam6eShcczj4Ew56UFvHhqxd/Xr2d8ytRxMDJODxy/RUxN6LMJU TaB/WTGaiyNQJfd6MfZdHklRKIZ2uJ9yGkg8ksiD5fsk0gxyEdIrm+hz9lL2ln4YLsAd kFonCbUOYScqKvhFlRPGcsO6OmKylW1IMALeDjOsJV/OvUlhgate0QdVjamqiUPD3+/u iArgyGZTzLbnPWwU8TJsS+1S/TDM65w8xBKByCZslyo5M13/guaqh0BL+J7TgGFfTEdS gnppeJ08t9VLWm5nP2sVYufjFKLZj2blm5yC1inZ14+swPsJawAICNI/MzAZe3NLcgPd pckw== X-Received: by 10.182.220.170 with SMTP id px10mr3750956obc.35.1381407986531; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.94.68 with SMTP id da4ls1042122qeb.24.gmail; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) X-Received: by 10.220.6.8 with SMTP id 8mr6397470vcx.82.1381407986396; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by mx.google.com with ESMTPS id b5si14128249vcf.129.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 10 Oct 2013 05:26:26 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.169; Received: by mail-vc0-f169.google.com with SMTP id ib11so1588912vcb.28 for ; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) X-Gm-Message-State: ALoCoQnqCbAXavabMo+7GXz9zMi49d6KTZbl+xJ7+ZfsKmBfFqGZbuUOS/ypd0hJM9PqFK3jTVen X-Received: by 10.220.178.200 with SMTP id bn8mr6278107vcb.95.1381407986261; Thu, 10 Oct 2013 05:26:26 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp371292vcz; Thu, 10 Oct 2013 05:26:25 -0700 (PDT) X-Received: by 10.15.99.72 with SMTP id bk48mr20412332eeb.22.1381407984784; Thu, 10 Oct 2013 05:26:24 -0700 (PDT) Received: from mail-ee0-f44.google.com (mail-ee0-f44.google.com [74.125.83.44]) by mx.google.com with ESMTPS id h5si36395790eeg.20.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 10 Oct 2013 05:26:24 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.83.44 is neither permitted nor denied by best guess record for domain of will.newton@linaro.org) client-ip=74.125.83.44; Received: by mail-ee0-f44.google.com with SMTP id b47so1115646eek.17 for ; Thu, 10 Oct 2013 05:26:24 -0700 (PDT) X-Received: by 10.14.218.197 with SMTP id k45mr20283883eep.32.1381407984076; Thu, 10 Oct 2013 05:26:24 -0700 (PDT) Received: from localhost.localdomain (cpc6-seac21-2-0-cust453.7-2.cable.virginmedia.com. [82.1.113.198]) by mx.google.com with ESMTPSA id a1sm101011919eem.1.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 10 Oct 2013 05:26:23 -0700 (PDT) Message-ID: <52569CED.3060700@linaro.org> Date: Thu, 10 Oct 2013 13:26:21 +0100 From: Will Newton User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130805 Thunderbird/17.0.8 MIME-Version: 1.0 To: libc-alpha@sourceware.org CC: Patch Tracking Subject: [PATCH] malloc: Fix for infinite loop in memalign/posix_memalign. X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: will.newton@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.169 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , A very large alignment argument passed to mealign/posix_memalign causes _int_memalign to enter an infinite loop. Limit the maximum alignment value to the maximum representable power of two to prevent this from happening. Changelog: 2013-10-10 Will Newton [BZ #16038] * malloc/hooks.c (memalign_check): Limit alignment to the maximum representable power of two. * malloc/malloc.c (__libc_memalign): Likewise. * malloc/tst-memalign.c (do_test): Add test for very large alignment values. * malloc/tst-posix_memalign.c (do_test): Likewise. --- malloc/hooks.c | 8 ++++++++ malloc/malloc.c | 8 ++++++++ malloc/tst-memalign.c | 15 +++++++++++++++ malloc/tst-posix_memalign.c | 10 ++++++++++ 4 files changed, 41 insertions(+) diff --git a/malloc/hooks.c b/malloc/hooks.c index 3f663bb..1dbe93f 100644 --- a/malloc/hooks.c +++ b/malloc/hooks.c @@ -361,6 +361,14 @@ memalign_check(size_t alignment, size_t bytes, const void *caller) if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL); if (alignment < MINSIZE) alignment = MINSIZE; + /* If the alignment is greater than SIZE_MAX / 2 + 1 it cannot be a + power of 2 and will cause overflow in the check below. */ + if (alignment > SIZE_MAX / 2 + 1) + { + __set_errno (EINVAL); + return 0; + } + /* Check for overflow. */ if (bytes > SIZE_MAX - alignment - MINSIZE) { diff --git a/malloc/malloc.c b/malloc/malloc.c index 2938234..f1949f0 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -3026,6 +3026,14 @@ __libc_memalign(size_t alignment, size_t bytes) /* Otherwise, ensure that it is at least a minimum chunk size */ if (alignment < MINSIZE) alignment = MINSIZE; + /* If the alignment is greater than SIZE_MAX / 2 + 1 it cannot be a + power of 2 and will cause overflow in the check below. */ + if (alignment > SIZE_MAX / 2 + 1) + { + __set_errno (EINVAL); + return 0; + } + /* Check for overflow. */ if (bytes > SIZE_MAX - alignment - MINSIZE) { diff --git a/malloc/tst-memalign.c b/malloc/tst-memalign.c index 1c59752..b8eec9e 100644 --- a/malloc/tst-memalign.c +++ b/malloc/tst-memalign.c @@ -70,6 +70,21 @@ do_test (void) free (p); + errno = 0; + + /* Test to expose integer overflow in malloc internals from BZ #16038. */ + p = memalign (-1, pagesize); + + save = errno; + + if (p != NULL) + merror ("memalign (-1, pagesize) succeeded."); + + if (p == NULL && save != EINVAL) + merror ("memalign (-1, -pagesize) errno is not set correctly"); + + free (p); + /* A zero-sized allocation should succeed with glibc, returning a non-NULL value. */ p = memalign (sizeof (void *), 0); diff --git a/malloc/tst-posix_memalign.c b/malloc/tst-posix_memalign.c index 27c0dd2..7f34e37 100644 --- a/malloc/tst-posix_memalign.c +++ b/malloc/tst-posix_memalign.c @@ -65,6 +65,16 @@ do_test (void) p = NULL; + /* Test to expose integer overflow in malloc internals from BZ #16038. */ + ret = posix_memalign (&p, -1, pagesize); + + if (ret != EINVAL) + merror ("posix_memalign (&p, -1, pagesize) succeeded."); + + free (p); + + p = NULL; + /* A zero-sized allocation should succeed with glibc, returning zero and setting p to a non-NULL value. */ ret = posix_memalign (&p, sizeof (void *), 0);