From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53ED2223DFF for ; Sat, 20 Dec 2025 14:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766239850; cv=none; b=f4FTDEcYDi+4OIicO2TGSrnnCPdrRcf5lZmJ03kFNf5xx/4EjzM8FJ3P5HeV23CouOSuMDqnBnNuPQ7HYgnMCTfCbEmi/5tY1NCXsXi/rEfwZyz1JtRjut1Wf0dcejJOQ9HmsesKi4pEAyCsiRiBFPtjgwdSRuCe+8PXymYswvU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766239850; c=relaxed/simple; bh=g4Mpdj8M/9nkmvR9QIQZWnLNqFGEQ4jOsYsNIoNtuC4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=DfY0rNJXDmGA8NREwFhnsvOF1A4ZQa8+4XrGMgFS1TNoUkL6wTW5W0RW3HNPG5e36sEaPjI1H7T9fKeZgcbTmuEvZYJJ5qrI6ELVxox63a/O1OnhDHQZgtgTC0pc//Lk/NEEdgyAeO+ajF+45Xa+UvsRnFTqQqazqQ6bJ5HsXdU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=JqdbWh1p; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="JqdbWh1p" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=In-Reply-To:Content-Transfer-Encoding: Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date: Sender:Reply-To:Content-ID:Content-Description; bh=T5s+N8DvLqqnsti1B3ZafSst/tUyv7uKX/kKMNorHTo=; b=JqdbWh1pl4dXhfIVZBfBh6hCjr zrcJxhswntgAOAf0opF31uiDcp9+rlG33f7DWdXiTwg2U4jluXGbXv3lxBKlwJ08CN2TPy2aVd8nY YpgXruvOmbL1KMPCb37+LH6XODX8Pyn0Lq4M8ZXNE+aZWKlN3H2KvVVfXMXstv6JjtUjrs8OotGx5 ixcJmGkWdIKvywitR0+UFqkZbPM+zXfGBZrgrb4ZOIr9Htg6gEUIrYkZAvXXqZv/IoSTVnAuPxTu0 aHb07XQhBHrvrzrGi7Hatp7OnjwMMAPxUtutvExfB1BcglFmirJqR65bdukeOIJwMLIYR9Pi4wS2B WOVZ6BCg==; Received: from 2001-1c00-8d85-5700-266e-96ff-fe07-7dcc.cable.dynamic.v6.ziggo.nl ([2001:1c00:8d85:5700:266e:96ff:fe07:7dcc] helo=noisy.programming.kicks-ass.net) by desiato.infradead.org with esmtpsa (Exim 4.98.2 #2 (Red Hat Linux)) id 1vWwns-0000000CUSG-3GjD; Sat, 20 Dec 2025 13:15:25 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id 96F9430057E; Sat, 20 Dec 2025 15:10:37 +0100 (CET) Date: Sat, 20 Dec 2025 15:10:37 +0100 From: Peter Zijlstra To: Brian Gerst Cc: ellyndra , linux-kernel@vger.kernel.org, luto@kernel.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com Subject: Re: [PATCH v2] x86/syscall: make sys_call helpers static Message-ID: <20251220141037.GT3707891@noisy.programming.kicks-ass.net> References: <20251218145714.70220-1-ellyesparza8@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: On Sat, Dec 20, 2025 at 08:50:31AM -0500, Brian Gerst wrote: > On Thu, Dec 18, 2025 at 10:01 AM ellyndra wrote: > > > > Make 'x64_sys_call()' 'x32_sys_call()' and 'ia32_sys_call()' static to > > prevent them from being resolved via kallsyms and by extension kprobes. > > > > These functions contain the final calls to the syscall handlers, having > > access to their address can be used to hook this calls altering their > > behavior. Preventing symbol visibility limits the area of such attacks. > > > > Suggested-by: Peter Zijlstra > > Signed-off-by: Elly I Esparza > > --- > > arch/x86/entry/syscall_32.c | 6 ++++-- > > arch/x86/entry/syscall_64.c | 12 ++++++++---- > > arch/x86/include/asm/syscall.h | 8 -------- > > 3 files changed, 12 insertions(+), 14 deletions(-) > > > > diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c > > index 2b15ea17bb7c..28c9a99fb2de 100644 > > --- a/arch/x86/entry/syscall_32.c > > +++ b/arch/x86/entry/syscall_32.c > > @@ -41,7 +41,7 @@ const sys_call_ptr_t sys_call_table[] = { > > #endif > > > > #define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs); > > -long ia32_sys_call(const struct pt_regs *regs, unsigned int nr) > > +static __always_inline long ia32_sys_call(const struct pt_regs *regs, unsigned int nr) > > { > > switch (nr) { > > #include > > @@ -70,7 +70,7 @@ early_param("ia32_emulation", ia32_emulation_override_cmdline); > > /* > > * Invoke a 32-bit syscall. Called with IRQs on in CT_STATE_KERNEL. > > */ > > -static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) > > +static noinstr void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) > > { > > /* > > * Convert negative numbers to very high and thus out of range > > @@ -78,12 +78,14 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) > > */ > > unsigned int unr = nr; > > > > + instrumentation_begin(); > > if (likely(unr < IA32_NR_syscalls)) { > > unr = array_index_nospec(unr, IA32_NR_syscalls); > > regs->ax = ia32_sys_call(regs, unr); > > } else if (nr != -1) { > > regs->ax = __ia32_sys_ni_syscall(regs); > > } > > + instrumentation_end(); > > } > > > > #ifdef CONFIG_IA32_EMULATION > > diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c > > index b6e68ea98b83..55ad274f57f5 100644 > > --- a/arch/x86/entry/syscall_64.c > > +++ b/arch/x86/entry/syscall_64.c > > @@ -32,7 +32,7 @@ const sys_call_ptr_t sys_call_table[] = { > > #undef __SYSCALL > > > > #define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); > > -long x64_sys_call(const struct pt_regs *regs, unsigned int nr) > > +static __always_inline long x64_sys_call(const struct pt_regs *regs, unsigned int nr) > > { > > switch (nr) { > > #include > > @@ -40,15 +40,17 @@ long x64_sys_call(const struct pt_regs *regs, unsigned int nr) > > } > > } > > > > -#ifdef CONFIG_X86_X32_ABI > > -long x32_sys_call(const struct pt_regs *regs, unsigned int nr) > > +static __always_inline long x32_sys_call(const struct pt_regs *regs, unsigned int nr) > > { > > +#ifdef CONFIG_X86_X32_ABI > > switch (nr) { > > #include > > default: return __x64_sys_ni_syscall(regs); > > } > > -} > > +#else > > + return __x64_sys_ni_syscall(regs); > > #endif > > +} > > > > static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr) > > { > > @@ -58,11 +60,13 @@ static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr) > > */ > > unsigned int unr = nr; > > > > + instrumentation_begin(); > > if (likely(unr < NR_syscalls)) { > > unr = array_index_nospec(unr, NR_syscalls); > > regs->ax = x64_sys_call(regs, unr); > > return true; > > } > > + instrumentation_end(); > > return false; > > } > > > > diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h > > index c10dbb74cd00..59a406074dc0 100644 > > --- a/arch/x86/include/asm/syscall.h > > +++ b/arch/x86/include/asm/syscall.h > > @@ -20,14 +20,6 @@ > > typedef long (*sys_call_ptr_t)(const struct pt_regs *); > > extern const sys_call_ptr_t sys_call_table[]; > > > > -/* > > - * These may not exist, but still put the prototypes in so we > > - * can use IS_ENABLED(). > > - */ > > -extern long ia32_sys_call(const struct pt_regs *, unsigned int nr); > > -extern long x32_sys_call(const struct pt_regs *, unsigned int nr); > > -extern long x64_sys_call(const struct pt_regs *, unsigned int nr); > > - > > /* > > * Only the low 32 bits of orig_ax are meaningful, so we return int. > > * This importantly ignores the high bits on 64-bit, so comparisons > > -- > > 2.43.0 > > > > > > The main benefit of having the switch in a discrete function is that > it allows the compiler to do tail-call optimizations, reducing text > size. Isn't it possible to blacklist functions from kprobes? Ofcourse. But I'm not sure I understand your concern. Both x{64,32}_sys_call() only have a single caller, inlining them avoids the whole call, tail or otherwise, how is that a bad thing?