From patchwork Wed Jan 25 16:05:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: lilydjwg--- via Elfutils-devel X-Patchwork-Id: 63680 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A67F13858C2C for ; Wed, 25 Jan 2023 16:05:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A67F13858C2C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1674662748; bh=3YQ3FIzbork+fwU5UZfPTdn09O1yvqEd4xX3aVBozIE=; h=Date:Subject:To:Cc:List-Id:List-Unsubscribe:List-Archive: List-Help:List-Subscribe:From:Reply-To:From; b=THP9aFsqn4MBqGdgFLorfJ4z6uoijdtotqUjIgd/dAb9YI3BZ5rqnkbIKvSNeYJsE i/yPeGUKDshI9xUVte48/frq9gNnMygq+NHxXyllUOdiCXSE2mZv+fE211VI1+88dh Rifta1RAzmSA9GuKtGUQg852r9op/uFsdL0ArnPA= X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from mail-wm1-x349.google.com (mail-wm1-x349.google.com [IPv6:2a00:1450:4864:20::349]) by sourceware.org (Postfix) with ESMTPS id 8D49D3858D28 for ; Wed, 25 Jan 2023 16:05:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8D49D3858D28 Received: by mail-wm1-x349.google.com with SMTP id m10-20020a05600c3b0a00b003dafe7451deso11144501wms.4 for ; Wed, 25 Jan 2023 08:05:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=3YQ3FIzbork+fwU5UZfPTdn09O1yvqEd4xX3aVBozIE=; b=6ifhjd/uVzj/1dUBIe6FcuG1Ou4Xw371NDzlZbpnw42zMlpHMdSNFZvHBxeFhHqECi f1hmkGqNwuPQxFM0nWalwfdNZmA0RgvPGmMBV49j8PMx9jPxmQOcC9oxLrkw28tlZw4P F1EY8MoQn/i74H3Bzu8gynkUr4/Op/OznFz9BB/wmAsgcyZ5ARpwQuyDcumJp+HLUsZq lVS6U5yL0Nua77/KzQK6rmrOoNfszk6qvM4DAhkj9EVPj77xBdao/KQzMhuILZhpSpzl T9rTyXfzNmBAK4vNJLajofupsRRlisWftQuFKyD0+o6VCGUNjw58XbIruMhbcztmNwZd +cgA== X-Gm-Message-State: AFqh2ko/6ISO1pZ+me423BTqQugNEH+ojRZ52qz8iqmMHUms0E2d7IL1 4BxB8Eo2eWb7u0TRcYBo4XkZD9PmVp9SPaHmT7gJUUQF5cbopXGAb9mIlQC2SH8cJIVMzuzHQy/ XjdjhoIXbsJIh9Ha8R/EpQt24Bm6R71Fu+XImD/D097e3290u/YzRIK7dkSbiyRwhaLkPyRQ= X-Google-Smtp-Source: AMrXdXvSfNXNQEPuS57lHcHe74SpRsWkunnvltspwbpw2wpkT7qfImEF0CeD5jyEJUi1/EpQ4S4Bb5Dcp9k= X-Received: from vvvvvv-dev.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:472]) (user=vvvvvv job=sendgmr) by 2002:a1c:7404:0:b0:3da:b40f:c734 with SMTP id p4-20020a1c7404000000b003dab40fc734mr2702472wmc.115.1674662735775; Wed, 25 Jan 2023 08:05:35 -0800 (PST) Date: Wed, 25 Jan 2023 16:05:30 +0000 Mime-Version: 1.0 X-Mailer: git-send-email 2.39.1.405.gd4c25cc71f-goog Message-ID: <20230125160530.949622-1-vvvvvv@google.com> Subject: [PATCH] libdw: check memory access in get_(u|s)leb128 To: elfutils-devel@sourceware.org Cc: kernel-team@android.com, maennich@google.com, vvvvvv@google.com X-Spam-Status: No, score=-20.6 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, HK_RANDOM_FROM, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aleksei Vetrov via Elfutils-devel From: lilydjwg--- via Elfutils-devel Reply-To: vvvvvv@google.com Errors-To: elfutils-devel-bounces+patchwork=sourceware.org@sourceware.org Sender: "Elfutils-devel" From: Aleksei Vetrov __libdw_get_uleb128 and __libdw_get_sleb128 should check if addrp has already reached the end before unrolling the first step. It is done by moving __libdw_max_len to the beginning of the function, which already has all the checks. Signed-off-by: Aleksei Vetrov --- libdw/memory-access.h | 10 ++++++---- tests/leb128.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/libdw/memory-access.h b/libdw/memory-access.h index fca4129a..1cac6af3 100644 --- a/libdw/memory-access.h +++ b/libdw/memory-access.h @@ -72,13 +72,14 @@ __libdw_max_len_sleb128 (const unsigned char *addr, const unsigned char *end) static inline uint64_t __libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end) { + const size_t max = __libdw_max_len_uleb128 (*addrp, end); uint64_t acc = 0; /* Unroll the first step to help the compiler optimize for the common single-byte case. */ - get_uleb128_step (acc, *addrp, 0); + if (likely (max > 0)) + get_uleb128_step (acc, *addrp, 0); - const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end); for (size_t i = 1; i < max; ++i) get_uleb128_step (acc, *addrp, i); /* Other implementations set VALUE to UINT_MAX in this @@ -124,6 +125,7 @@ __libdw_get_uleb128_unchecked (const unsigned char **addrp) static inline int64_t __libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end) { + const size_t max = __libdw_max_len_sleb128 (*addrp, end); /* Do the work in an unsigned type, but use implementation-defined behavior to cast to signed on return. This avoids some undefined behavior when shifting. */ @@ -131,9 +133,9 @@ __libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end) /* Unroll the first step to help the compiler optimize for the common single-byte case. */ - get_sleb128_step (acc, *addrp, 0); + if (likely (max > 0)) + get_sleb128_step (acc, *addrp, 0); - const size_t max = __libdw_max_len_sleb128 (*addrp - 1, end); for (size_t i = 1; i < max; ++i) get_sleb128_step (acc, *addrp, i); if (*addrp == end) diff --git a/tests/leb128.c b/tests/leb128.c index 47b57c0d..03090d80 100644 --- a/tests/leb128.c +++ b/tests/leb128.c @@ -117,6 +117,19 @@ test_sleb (void) return OK; } +static int +test_sleb_safety (void) +{ + const int64_t expected_error = INT64_MAX; + int64_t value; + const unsigned char *test = NULL; + get_sleb128 (value, test, test); + if (value != expected_error) + return FAIL; + + return OK; +} + static int test_one_uleb (const unsigned char *data, size_t len, uint64_t expect) { @@ -166,8 +179,22 @@ test_uleb (void) return OK; } +static int +test_uleb_safety (void) +{ + const uint64_t expected_error = UINT64_MAX; + uint64_t value; + const unsigned char *test = NULL; + get_uleb128 (value, test, test); + if (value != expected_error) + return FAIL; + + return OK; +} + int main (void) { - return test_sleb () || test_uleb (); + return test_sleb () || test_sleb_safety () || test_uleb () + || test_uleb_safety (); }