Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp1225139imm; Fri, 12 Oct 2018 14:08:31 -0700 (PDT) X-Google-Smtp-Source: ACcGV62IHLCKWEmM2m1hwr6iKWdm0kFf+iAgUvV8CDISGeWzAJ5oZrUwpPSR491sdtuhBIFlv0XQ X-Received: by 2002:a63:d52:: with SMTP id 18-v6mr7038975pgn.107.1539378511191; Fri, 12 Oct 2018 14:08:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539378511; cv=none; d=google.com; s=arc-20160816; b=nAgrwG6N82u8+Q3/T0bVSwRUtBnU8t/ydSvTP98sXHyTZy+D2pRArk1dE+/WmAeczb 2ccvQrtkPIvyCeIwTtrZzBzlMfMUjlf4Xvit4sDOhTDMpmSF7h+4ehX21d+u0dlc3f1+ LT1n7BdW4IVJAOP1/e/q2b4R0IeV6epiw46v9BsqhHSupZLlDWVuS4lBbl1RhBjhJJMU 6Q7YfcbvSILvPsNE+OOE2SFIrT9K+w+MifAbFmn0WtMFJrn51jgvlIySvflIFnCFku8o 86lxHlgpVhDjjMOG8ots7x/v6Rj7iO6hINriXwc1YtaKXWKIXu61zsRHIIk/QckmBRzv zmWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature; bh=2tZ/rXRJfNEeNIYYYIX2Mv2wSyX9a2Yft5L5dqUeX9g=; b=J2IX8fYh+PS9n3jAb2Bl7JQFZs/ud/63zdSe0p6h6AlB9qDTE187eiDzWxaE1rJDic v0ZrCnIChbSrmNs79j0d5q0XLDRPPBxpaMDJciwSZ1Aza+tTZ1ajKm9V9U9JKDRLk6MD 4wwOWcy47OygtdbwrJzy4OdfxKCO69Q6geWlHF6vSTN8Nakw0eo2T5xduU62JiFfVi85 kWabmVpLaObh1DE2RdPHoaGvzegEH9FgVSYjVdftgQjN7uFOkRNTJ/wBCLGmEiR5NdT6 Bt4flVQ2C0oql0kv3qxk8TAzJZDbEsny5/KUInV/RwQYzm92RtNWqwwsDHZaiZ6rQk21 syLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Q0aWrDg/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v5-v6si2225716plo.417.2018.10.12.14.08.13; Fri, 12 Oct 2018 14:08:31 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Q0aWrDg/"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726059AbeJMEmM (ORCPT + 99 others); Sat, 13 Oct 2018 00:42:12 -0400 Received: from mail-it1-f196.google.com ([209.85.166.196]:35209 "EHLO mail-it1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725978AbeJMEmL (ORCPT ); Sat, 13 Oct 2018 00:42:11 -0400 Received: by mail-it1-f196.google.com with SMTP id p64-v6so20105770itp.0 for ; Fri, 12 Oct 2018 14:07:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=2tZ/rXRJfNEeNIYYYIX2Mv2wSyX9a2Yft5L5dqUeX9g=; b=Q0aWrDg/8UXpmvXja/gjmAIwmhUUB0rK3geMmswVGOGje3Z29KJ9KyxvC9z77JkpUx QQ/cogmzUPUAVHFY8dx4+Id9TwDB2B46IXLuYMtuPepFPvSSunjcko6VmrrCRrB1HHOf 0cj5r4VfX0eXZC+hPUSUgoGJzsWsJ1WRFjJOw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=2tZ/rXRJfNEeNIYYYIX2Mv2wSyX9a2Yft5L5dqUeX9g=; b=Knmf+5DWQC/0W6ss+PmkTGOcu4r6Y+XcDw9z2SMdkTeqclSm8dFWCanDEvMdDogxX/ 18NgUiU4CJ6eKQaZifgmSSExcM8nvBtIOtRuKMPeWjcMli3o+BI0X//Yg1MBQ+ptFeyL 2KG8kc42WcpMbO1jYIfvpXkIyrdhD7IhoH5qwVX7twlsgIzlkk0RXWyUKP7j9gVNEm5l pQP1L4c1fzbQGvdH/uRs2mI72km12md+9jH5MiznXpf9SCTGfkmigMjoJlvKqntw5Kxa nti6JxnWFtnbGT0ItozeXXmvLaOwsCO4SM3sQTPMOh6LaSPXahKdAFlxCsJOQ/3JsnVM HFFA== X-Gm-Message-State: ABuFfoja8ukUor8ESZz8O8z6wUa/Mer8VjeC/LhGOBiAfDeZq2yh4N6e yuUz0fX/GHkVRGA11KBbB78OFIrLeN8QAgsVjTEShw== X-Received: by 2002:a24:4ac5:: with SMTP id k188-v6mr6649506itb.158.1539378470307; Fri, 12 Oct 2018 14:07:50 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a6b:5910:0:0:0:0:0 with HTTP; Fri, 12 Oct 2018 14:07:49 -0700 (PDT) In-Reply-To: <20181012200523.23731-1-mathieu.desnoyers@efficios.com> References: <20181012200523.23731-1-mathieu.desnoyers@efficios.com> From: Ard Biesheuvel Date: Fri, 12 Oct 2018 23:07:49 +0200 Message-ID: Subject: Re: [PATCH for 4.19] tracepoint: Fix: out-of-bound tracepoint array iteration To: Mathieu Desnoyers Cc: Steven Rostedt , Linux Kernel Mailing List , Michael Ellerman , Ingo Molnar , Arnd Bergmann , Benjamin Herrenschmidt , Bjorn Helgaas , Catalin Marinas , James Morris , James Morris , Jessica Yu , Josh Poimboeuf , Kees Cook , Nicolas Pitre , Paul Mackerras , Petr Mladek , Russell King , "Serge E. Hallyn" , Sergey Senozhatsky , Thomas Garnier , Thomas Gleixner , Will Deacon , Andrew Morton , Linus Torvalds , Greg Kroah-Hartman Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Mathieu, On 12 October 2018 at 22:05, Mathieu Desnoyers wrote: > commit 46e0c9be206f ("kernel: tracepoints: add support for relative > references") changes the layout of the __tracepoint_ptrs section on > architectures supporting relative references. However, it does so > without turning struct tracepoint * const into const int * elsewhere in > the tracepoint code, which has the following side-effect: > > tracepoint_module_{coming,going} invoke > tp_module_going_check_quiescent() with mod->tracepoints_ptrs > as first argument, and computes the end address of the array > for the second argument with: > > mod->tracepoints_ptrs + mod->num_tracepoints > > However, because the type of mod->tracepoint_ptrs in module.h > has not been changed from pointer to int, it passes an end > pointer which is twice larger than the array, causing out-of-bound > array accesses. > > Fix this by introducing a new typedef: tracepoint_ptr_t, which > is either "const int" on architectures that have PREL32 relocations, > or "struct tracepoint * const" on architectures that does not have > this feature. > > Also provide a new tracepoint_ptr_defer() static inline to > encapsulate deferencing this type rather than duplicate code and > ugly idefs within the for_each_tracepoint_range() implementation. > Apologies for the breakage. FWIW, this looks like the correct approach to me (and mirrors what I did for initcalls in the same series) > This issue appears in 4.19-rc kernels, and should ideally be fixed > before the end of the rc cycle. > +1 > Signed-off-by: Mathieu Desnoyers > Link: http://lkml.kernel.org/r/20180704083651.24360-7-ard.biesheuvel@linaro.org > Cc: Michael Ellerman > Cc: Ingo Molnar > Cc: Steven Rostedt (VMware) > Cc: Ard Biesheuvel > Cc: Arnd Bergmann > Cc: Benjamin Herrenschmidt > Cc: Bjorn Helgaas > Cc: Catalin Marinas > Cc: James Morris > Cc: James Morris > Cc: Jessica Yu > Cc: Josh Poimboeuf > Cc: Kees Cook > Cc: Nicolas Pitre > Cc: Paul Mackerras > Cc: Petr Mladek > Cc: Russell King > Cc: "Serge E. Hallyn" > Cc: Sergey Senozhatsky > Cc: Thomas Garnier > Cc: Thomas Gleixner > Cc: Will Deacon > Cc: Andrew Morton > Cc: Linus Torvalds > Cc: Greg Kroah-Hartman Acked-by: Ard Biesheuvel > --- > include/linux/module.h | 2 +- > include/linux/tracepoint-defs.h | 6 ++++++ > include/linux/tracepoint.h | 36 +++++++++++++++++++++------------ > kernel/tracepoint.c | 24 ++++++++-------------- > 4 files changed, 38 insertions(+), 30 deletions(-) > > diff --git a/include/linux/module.h b/include/linux/module.h > index f807f15bebbe..cdab2451d6be 100644 > --- a/include/linux/module.h > +++ b/include/linux/module.h > @@ -430,7 +430,7 @@ struct module { > > #ifdef CONFIG_TRACEPOINTS > unsigned int num_tracepoints; > - struct tracepoint * const *tracepoints_ptrs; > + tracepoint_ptr_t *tracepoints_ptrs; > #endif > #ifdef HAVE_JUMP_LABEL > struct jump_entry *jump_entries; > diff --git a/include/linux/tracepoint-defs.h b/include/linux/tracepoint-defs.h > index 22c5a46e9693..49ba9cde7e4b 100644 > --- a/include/linux/tracepoint-defs.h > +++ b/include/linux/tracepoint-defs.h > @@ -35,6 +35,12 @@ struct tracepoint { > struct tracepoint_func __rcu *funcs; > }; > > +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS > +typedef const int tracepoint_ptr_t; > +#else > +typedef struct tracepoint * const tracepoint_ptr_t; > +#endif > + > struct bpf_raw_event_map { > struct tracepoint *tp; > void *bpf_func; > diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h > index 041f7e56a289..538ba1a58f5b 100644 > --- a/include/linux/tracepoint.h > +++ b/include/linux/tracepoint.h > @@ -99,6 +99,29 @@ extern void syscall_unregfunc(void); > #define TRACE_DEFINE_ENUM(x) > #define TRACE_DEFINE_SIZEOF(x) > > +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS > +static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) > +{ > + return offset_to_ptr(p); > +} > + > +#define __TRACEPOINT_ENTRY(name) \ > + asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \ > + " .balign 4 \n" \ > + " .long __tracepoint_" #name " - . \n" \ > + " .previous \n") > +#else > +static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) > +{ > + return *p; > +} > + > +#define __TRACEPOINT_ENTRY(name) \ > + static tracepoint_ptr_t __tracepoint_ptr_##name __used \ > + __attribute__((section("__tracepoints_ptrs"))) = \ > + &__tracepoint_##name > +#endif > + > #endif /* _LINUX_TRACEPOINT_H */ > > /* > @@ -253,19 +276,6 @@ extern void syscall_unregfunc(void); > return static_key_false(&__tracepoint_##name.key); \ > } > > -#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS > -#define __TRACEPOINT_ENTRY(name) \ > - asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \ > - " .balign 4 \n" \ > - " .long __tracepoint_" #name " - . \n" \ > - " .previous \n") > -#else > -#define __TRACEPOINT_ENTRY(name) \ > - static struct tracepoint * const __tracepoint_ptr_##name __used \ > - __attribute__((section("__tracepoints_ptrs"))) = \ > - &__tracepoint_##name > -#endif > - > /* > * We have no guarantee that gcc and the linker won't up-align the tracepoint > * structures, so we create an array of pointers that will be used for iteration > diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c > index bf2c06ef9afc..a3be42304485 100644 > --- a/kernel/tracepoint.c > +++ b/kernel/tracepoint.c > @@ -28,8 +28,8 @@ > #include > #include > > -extern struct tracepoint * const __start___tracepoints_ptrs[]; > -extern struct tracepoint * const __stop___tracepoints_ptrs[]; > +extern tracepoint_ptr_t __start___tracepoints_ptrs[]; > +extern tracepoint_ptr_t __stop___tracepoints_ptrs[]; > > DEFINE_SRCU(tracepoint_srcu); > EXPORT_SYMBOL_GPL(tracepoint_srcu); > @@ -371,25 +371,17 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data) > } > EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); > > -static void for_each_tracepoint_range(struct tracepoint * const *begin, > - struct tracepoint * const *end, > +static void for_each_tracepoint_range( > + tracepoint_ptr_t *begin, tracepoint_ptr_t *end, > void (*fct)(struct tracepoint *tp, void *priv), > void *priv) > { > + tracepoint_ptr_t *iter; > + > if (!begin) > return; > - > - if (IS_ENABLED(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)) { > - const int *iter; > - > - for (iter = (const int *)begin; iter < (const int *)end; iter++) > - fct(offset_to_ptr(iter), priv); > - } else { > - struct tracepoint * const *iter; > - > - for (iter = begin; iter < end; iter++) > - fct(*iter, priv); > - } > + for (iter = begin; iter < end; iter++) > + fct(tracepoint_ptr_deref(iter), priv); > } > > #ifdef CONFIG_MODULES > -- > 2.17.1 >