From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1D3C7F for ; Mon, 12 Sep 2022 09:45:52 +0000 (UTC) Received: by mail-ed1-f73.google.com with SMTP id q18-20020a056402519200b0043dd2ff50feso5702629edd.9 for ; Mon, 12 Sep 2022 02:45:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date; bh=jBoH9dZtU8u1abW3Qj3aDrAs7nz5caMLzMPJv+JY2CE=; b=MR5DigsBS0/ITOnUWHz7rgazRDEBSqjosdzYJAXuVO6gDRUXtNg9chMfS+KizD1tgT 9NaYvF1m/6aPRfa8q0xlZJcT7MFNTWJt/SK7OV5dCQEJyRr1taZhhd3hLeVb7dRd+rHb UGUKoKbJFmxiV2W/B6LtSwf4iwULzTbONwflcqTnChdS03U+IxEJ/yFcZ7dVJ7NnN4Gd d1pPqhxUY0oWLOmM1K3C76rAD19FozAhJvuGY7E4b0idk28B42yT/GrEy+1W15xnFWdW 0uwCqdrVJ2BrFjX0Gypno+SDEw850aI/+OeTLYWq/BCXtDetEIgN54LDioLlIM3kfgpT MfYg== 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; bh=jBoH9dZtU8u1abW3Qj3aDrAs7nz5caMLzMPJv+JY2CE=; b=4nWh6Rme/QeLfvnhPoICCQfQEFbnhAo2rTIp7wJV4ktC8A60MVIJv3oH6owLa9edEO FOqHL/4YFGPm88kGvOWbAM6eFgR0hxSjKlaF/bDnFSvY+dIuzLq8POJBBXPo9LikloM7 +6HEInJoKamrTcQeYFsV3DX/tZSIxid96E/yUCHOlEzYJ3Mp1xXY0OrOrUdOH3ndeEh1 fq6UaGsGoSOWSpAuhijg1g+frZNaTlO/YhgOLEQcjwAkXxxMwV0y5mb6xIPJWGWghgmE 8UWV/18blo6/cQEx33/gVy0VarDmP7dOUGIEXl9B/35Z7eyUGU404bzDfNNjTl4EtkzD W9Cw== X-Gm-Message-State: ACgBeo0w8RikK3NasW36QAmvJgicFwvi7396y+MXitx4jBmTlmT8aNO0 hrzO8nv5C/mj/EJASTdugIxKnKoF8g== X-Google-Smtp-Source: AA6agR5+oeruIkBj1HE2zrvAygBUxfE3HyDxczIWzvFPZx3yXg43HU2XyG1ItaJyA72oGU8vzG5byHrq1g== X-Received: from elver.muc.corp.google.com ([2a00:79e0:9c:201:f693:9fff:fef4:2449]) (user=elver job=sendgmr) by 2002:a05:6402:5002:b0:444:26fd:d341 with SMTP id p2-20020a056402500200b0044426fdd341mr21825632eda.351.1662975950998; Mon, 12 Sep 2022 02:45:50 -0700 (PDT) Date: Mon, 12 Sep 2022 11:45:40 +0200 Precedence: bulk X-Mailing-List: llvm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.37.2.789.g6183377224-goog Message-ID: <20220912094541.929856-1-elver@google.com> Subject: [PATCH v3 1/2] kcsan: Instrument memcpy/memset/memmove with newer Clang From: Marco Elver To: elver@google.com, "Paul E. McKenney" Cc: Mark Rutland , Dmitry Vyukov , Alexander Potapenko , Boqun Feng , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, Nathan Chancellor , Nick Desaulniers , llvm@lists.linux.dev, Josh Poimboeuf , Peter Zijlstra , stable@vger.kernel.org Content-Type: text/plain; charset="UTF-8" With Clang version 16+, -fsanitize=thread will turn memcpy/memset/memmove calls in instrumented functions into __tsan_memcpy/__tsan_memset/__tsan_memmove calls respectively. Add these functions to the core KCSAN runtime, so that we (a) catch data races with mem* functions, and (b) won't run into linker errors with such newer compilers. Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Marco Elver --- v3: * Truncate sizes larger than MAX_ENCODABLE_SIZE, so we still set up watchpoints on them. Iterating through MAX_ENCODABLE_SIZE blocks may result in pathological cases where performance would seriously suffer. So let's avoid that for now. * Just use memcpy/memset/memmove instead of __mem*() functions. Many architectures that already support KCSAN don't define them (mips, s390), and having both __mem* and mem versions of the functions provides little benefit elsewhere; and backporting would become more difficult, too. The compiler should not inline them given all parameters are non-constants here. v2: * Fix for architectures which do not provide their own memcpy/memset/memmove and instead use the generic versions in lib/string. In this case we'll just alias the __tsan_ variants. --- kernel/kcsan/core.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index fe12dfe254ec..54d077e1a2dc 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -14,10 +14,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "encoding.h" @@ -1308,3 +1310,51 @@ noinline void __tsan_atomic_signal_fence(int memorder) } } EXPORT_SYMBOL(__tsan_atomic_signal_fence); + +#ifdef __HAVE_ARCH_MEMSET +void *__tsan_memset(void *s, int c, size_t count); +noinline void *__tsan_memset(void *s, int c, size_t count) +{ + /* + * Instead of not setting up watchpoints where accessed size is greater + * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE. + */ + size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE); + + check_access(s, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); + return memset(s, c, count); +} +#else +void *__tsan_memset(void *s, int c, size_t count) __alias(memset); +#endif +EXPORT_SYMBOL(__tsan_memset); + +#ifdef __HAVE_ARCH_MEMMOVE +void *__tsan_memmove(void *dst, const void *src, size_t len); +noinline void *__tsan_memmove(void *dst, const void *src, size_t len) +{ + size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE); + + check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); + check_access(src, check_len, 0, _RET_IP_); + return memmove(dst, src, len); +} +#else +void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove); +#endif +EXPORT_SYMBOL(__tsan_memmove); + +#ifdef __HAVE_ARCH_MEMCPY +void *__tsan_memcpy(void *dst, const void *src, size_t len); +noinline void *__tsan_memcpy(void *dst, const void *src, size_t len) +{ + size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE); + + check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); + check_access(src, check_len, 0, _RET_IP_); + return memcpy(dst, src, len); +} +#else +void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy); +#endif +EXPORT_SYMBOL(__tsan_memcpy); -- 2.37.2.789.g6183377224-goog