* Re: The business loan-
From: David Song @ 2025-02-08 22:01 UTC (permalink / raw)
To: linux-api
Hello,
My name is David Song, at AA4 FS, we are a consultancy and
brokerage Firm specializing in Growth Financial Loan and joint
partnership venture. We specialize in investments in all Private
and public sectors in a broad range of areas within our Financial
Investment Services.
We are experts in financial and operational management, due
diligence and capital planning in all markets and industries. Our
Investors wish to invest in any viable Project presented by your
Management after reviews on your Business Project Presentation
Plan.
We look forward to your Swift response. We also offer commission
to consultants and brokers for any partnership referrals.
Regards,
David Song
Senior Broker
AA4 Financial Services
13 Wonersh Way, Cheam,
Sutton, Surrey, SM2 7LX
Email: dsong@aa4financialservice.com
^ permalink raw reply
* [PATCH bpf-next] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-09 22:05 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko
Cc: Kees Cook, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
Jann reported [1] possible issue when trampoline_check_ip returns
address near the bottom of the address space that is allowed to
call into the syscall if uretprobes are not set up.
Though the mmap minimum address restrictions will typically prevent
creating mappings there, let's make sure uretprobe syscall checks
for that.
[1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
Cc: Kees Cook <kees@kernel.org>
Cc: Eyal Birger <eyal.birger@gmail.com>
Cc: stable@vger.kernel.org
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
arch/x86/kernel/uprobes.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5a952c5ea66b..109d6641a1b3 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
return &insn;
}
-static unsigned long trampoline_check_ip(void)
+static unsigned long trampoline_check_ip(unsigned long tramp)
{
- unsigned long tramp = uprobe_get_trampoline_vaddr();
-
return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
}
SYSCALL_DEFINE0(uretprobe)
{
struct pt_regs *regs = task_pt_regs(current);
- unsigned long err, ip, sp, r11_cx_ax[3];
+ unsigned long err, ip, sp, r11_cx_ax[3], tramp;
+
+ /* If there's no trampoline, we are called from wrong place. */
+ tramp = uprobe_get_trampoline_vaddr();
+ if (tramp == -1)
+ goto sigill;
- if (regs->ip != trampoline_check_ip())
+ /* Make sure the ip matches the only allowed sys_uretprobe caller. */
+ if (regs->ip != trampoline_check_ip(tramp))
goto sigill;
err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
--
2.48.1
^ permalink raw reply related
* [PATCH v5 0/7] ptrace: introduce PTRACE_SET_SYSCALL_INFO API
From: Dmitry V. Levin @ 2025-02-10 11:33 UTC (permalink / raw)
To: Andrew Morton
Cc: Oleg Nesterov, Alexey Gladkov, Eugene Syromyatnikov,
Charlie Jenkins, Mike Frysinger, Renzo Davoli, Davide Berardi,
Vineet Gupta, Russell King, Will Deacon, Guo Ren, Brian Cain,
Huacai Chen, WANG Xuerui, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, Dinh Nguyen, Jonas Bonn, Stefan Kristiansson,
Stafford Horne, James E.J. Bottomley, Helge Deller,
Michael Ellerman, Nicholas Piggin, Christophe Leroy, Naveen N Rao,
Madhavan Srinivasan, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Christian Borntraeger, Sven Schnelle, Yoshinori Sato, Rich Felker,
John Paul Adrian Glaubitz, David S. Miller, Andreas Larsson,
Richard Weinberger, Anton Ivanov, Johannes Berg, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Chris Zankel, Max Filippov, Arnd Bergmann, Shuah Khan,
strace-devel, linux-snps-arc, linux-kernel, linux-arm-kernel,
linux-csky, linux-hexagon, loongarch, linux-m68k, linux-mips,
linux-openrisc, linux-parisc, linuxppc-dev, linux-riscv,
linux-s390, linux-sh, sparclinux, linux-um, linux-arch,
linux-kselftest, linux-api
PTRACE_SET_SYSCALL_INFO is a generic ptrace API that complements
PTRACE_GET_SYSCALL_INFO by letting the ptracer modify details of
system calls the tracee is blocked in.
This API allows ptracers to obtain and modify system call details in a
straightforward and architecture-agnostic way, providing a consistent way
of manipulating the system call number and arguments across architectures.
As in case of PTRACE_GET_SYSCALL_INFO, PTRACE_SET_SYSCALL_INFO also
does not aim to address numerous architecture-specific system call ABI
peculiarities, like differences in the number of system call arguments
for such system calls as pread64 and preadv.
The current implementation supports changing only those bits of system call
information that are used by strace system call tampering, namely, syscall
number, syscall arguments, and syscall return value.
Support of changing additional details returned by PTRACE_GET_SYSCALL_INFO,
such as instruction pointer and stack pointer, could be added later if
needed, by using struct ptrace_syscall_info.flags to specify the additional
details that should be set. Currently, "flags" and "reserved" fields of
struct ptrace_syscall_info must be initialized with zeroes; "arch",
"instruction_pointer", and "stack_pointer" fields are currently ignored.
PTRACE_SET_SYSCALL_INFO currently supports only PTRACE_SYSCALL_INFO_ENTRY,
PTRACE_SYSCALL_INFO_EXIT, and PTRACE_SYSCALL_INFO_SECCOMP operations.
Other operations could be added later if needed.
Ideally, PTRACE_SET_SYSCALL_INFO should have been introduced along with
PTRACE_GET_SYSCALL_INFO, but it didn't happen. The last straw that
convinced me to implement PTRACE_SET_SYSCALL_INFO was apparent failure
to provide an API of changing the first system call argument on riscv
architecture [1].
ptrace(2) man page:
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
...
PTRACE_SET_SYSCALL_INFO
Modify information about the system call that caused the stop.
The "data" argument is a pointer to struct ptrace_syscall_info
that specifies the system call information to be set.
The "addr" argument should be set to sizeof(struct ptrace_syscall_info)).
[1] https://lore.kernel.org/all/59505464-c84a-403d-972f-d4b2055eeaac@gmail.com/
Notes:
v5:
* ptrace: Extend the commit message to say that the new API does not aim
to address numerous architecture-specific syscall ABI peculiarities
* selftests: Add a workaround for s390 16-bit syscall numbers
* Add more Acked-by
* v4: https://lore.kernel.org/all/20250203065849.GA14120@strace.io/
v4:
* Split out syscall_set_return_value() for hexagon into a separate patch
* s390: Change the style of syscall_set_arguments() implementation as
requested
* Add more Reviewed-by
* v3: https://lore.kernel.org/all/20250128091445.GA8257@strace.io/
v3:
* powerpc: Submit syscall_set_return_value() fix for "sc" case separately
* mips: Do not introduce erroneous argument truncation on mips n32,
add a detailed description to the commit message of the
mips_get_syscall_arg() change
* ptrace: Add explicit padding to the end of struct ptrace_syscall_info,
simplify obtaining of user ptrace_syscall_info,
do not introduce PTRACE_SYSCALL_INFO_SIZE_VER0
* ptrace: Change the return type of ptrace_set_syscall_info_* functions
from "unsigned long" to "int"
* ptrace: Add -ERANGE check to ptrace_set_syscall_info_exit(),
add comments to -ERANGE checks
* ptrace: Update comments about supported syscall stops
* selftests: Extend set_syscall_info test, fix for mips n32
* Add Tested-by and Reviewed-by
v2:
* Add patch to fix syscall_set_return_value() on powerpc
* Add patch to fix mips_get_syscall_arg() on mips
* Add syscall_set_return_value() implementation on hexagon
* Add syscall_set_return_value() invocation to syscall_set_nr()
on arm and arm64.
* Fix syscall_set_nr() and mips_set_syscall_arg() on mips
* Add a comment to syscall_set_nr() on arc, powerpc, s390, sh,
and sparc
* Remove redundant ptrace_syscall_info.op assignments in
ptrace_get_syscall_info_*
* Minor style tweaks in ptrace_get_syscall_info_op()
* Remove syscall_set_return_value() invocation from
ptrace_set_syscall_info_entry()
* Skip syscall_set_arguments() invocation in case of syscall number -1
in ptrace_set_syscall_info_entry()
* Split ptrace_syscall_info.reserved into ptrace_syscall_info.reserved
and ptrace_syscall_info.flags
* Use __kernel_ulong_t instead of unsigned long in set_syscall_info test
Dmitry V. Levin (7):
mips: fix mips_get_syscall_arg() for o32
hexagon: add syscall_set_return_value()
syscall.h: add syscall_set_arguments()
syscall.h: introduce syscall_set_nr()
ptrace_get_syscall_info: factor out ptrace_get_syscall_info_op
ptrace: introduce PTRACE_SET_SYSCALL_INFO request
selftests/ptrace: add a test case for PTRACE_SET_SYSCALL_INFO
arch/arc/include/asm/syscall.h | 25 +
arch/arm/include/asm/syscall.h | 37 ++
arch/arm64/include/asm/syscall.h | 29 +
arch/csky/include/asm/syscall.h | 13 +
arch/hexagon/include/asm/syscall.h | 21 +
arch/loongarch/include/asm/syscall.h | 15 +
arch/m68k/include/asm/syscall.h | 7 +
arch/microblaze/include/asm/syscall.h | 7 +
arch/mips/include/asm/syscall.h | 70 ++-
arch/nios2/include/asm/syscall.h | 16 +
arch/openrisc/include/asm/syscall.h | 13 +
arch/parisc/include/asm/syscall.h | 19 +
arch/powerpc/include/asm/syscall.h | 20 +
arch/riscv/include/asm/syscall.h | 16 +
arch/s390/include/asm/syscall.h | 21 +
arch/sh/include/asm/syscall_32.h | 24 +
arch/sparc/include/asm/syscall.h | 22 +
arch/um/include/asm/syscall-generic.h | 19 +
arch/x86/include/asm/syscall.h | 43 ++
arch/xtensa/include/asm/syscall.h | 18 +
include/asm-generic/syscall.h | 30 +
include/uapi/linux/ptrace.h | 7 +-
kernel/ptrace.c | 179 +++++-
tools/testing/selftests/ptrace/Makefile | 2 +-
.../selftests/ptrace/set_syscall_info.c | 519 ++++++++++++++++++
25 files changed, 1145 insertions(+), 47 deletions(-)
create mode 100644 tools/testing/selftests/ptrace/set_syscall_info.c
--
ldv
^ permalink raw reply
* [PATCH v5 6/7] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: Dmitry V. Levin @ 2025-02-10 11:35 UTC (permalink / raw)
To: Andrew Morton
Cc: Oleg Nesterov, Alexey Gladkov, Eugene Syromyatnikov,
Charlie Jenkins, Mike Frysinger, Renzo Davoli, Davide Berardi,
strace-devel, linux-kernel, linux-api
In-Reply-To: <20250210113336.GA887@strace.io>
PTRACE_SET_SYSCALL_INFO is a generic ptrace API that complements
PTRACE_GET_SYSCALL_INFO by letting the ptracer modify details of
system calls the tracee is blocked in.
This API allows ptracers to obtain and modify system call details in a
straightforward and architecture-agnostic way, providing a consistent way
of manipulating the system call number and arguments across architectures.
As in case of PTRACE_GET_SYSCALL_INFO, PTRACE_SET_SYSCALL_INFO also
does not aim to address numerous architecture-specific system call ABI
peculiarities, like differences in the number of system call arguments
for such system calls as pread64 and preadv.
The current implementation supports changing only those bits of system call
information that are used by strace system call tampering, namely, syscall
number, syscall arguments, and syscall return value.
Support of changing additional details returned by PTRACE_GET_SYSCALL_INFO,
such as instruction pointer and stack pointer, could be added later if
needed, by using struct ptrace_syscall_info.flags to specify the additional
details that should be set. Currently, "flags" and "reserved" fields of
struct ptrace_syscall_info must be initialized with zeroes; "arch",
"instruction_pointer", and "stack_pointer" fields are currently ignored.
PTRACE_SET_SYSCALL_INFO currently supports only PTRACE_SYSCALL_INFO_ENTRY,
PTRACE_SYSCALL_INFO_EXIT, and PTRACE_SYSCALL_INFO_SECCOMP operations.
Other operations could be added later if needed.
Ideally, PTRACE_SET_SYSCALL_INFO should have been introduced along with
PTRACE_GET_SYSCALL_INFO, but it didn't happen. The last straw that
convinced me to implement PTRACE_SET_SYSCALL_INFO was apparent failure
to provide an API of changing the first system call argument on riscv
architecture.
ptrace(2) man page:
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
...
PTRACE_SET_SYSCALL_INFO
Modify information about the system call that caused the stop.
The "data" argument is a pointer to struct ptrace_syscall_info
that specifies the system call information to be set.
The "addr" argument should be set to sizeof(struct ptrace_syscall_info)).
Link: https://lore.kernel.org/all/59505464-c84a-403d-972f-d4b2055eeaac@gmail.com/
Signed-off-by: Dmitry V. Levin <ldv@strace.io>
Reviewed-by: Alexey Gladkov <legion@kernel.org>
Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
Tested-by: Charlie Jenkins <charlie@rivosinc.com>
Reviewed-by: Eugene Syromiatnikov <esyr@redhat.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
---
include/uapi/linux/ptrace.h | 7 ++-
kernel/ptrace.c | 121 +++++++++++++++++++++++++++++++++++-
2 files changed, 126 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h
index 72c038fc71d0..5f8ef6156752 100644
--- a/include/uapi/linux/ptrace.h
+++ b/include/uapi/linux/ptrace.h
@@ -74,6 +74,7 @@ struct seccomp_metadata {
};
#define PTRACE_GET_SYSCALL_INFO 0x420e
+#define PTRACE_SET_SYSCALL_INFO 0x4212
#define PTRACE_SYSCALL_INFO_NONE 0
#define PTRACE_SYSCALL_INFO_ENTRY 1
#define PTRACE_SYSCALL_INFO_EXIT 2
@@ -81,7 +82,8 @@ struct seccomp_metadata {
struct ptrace_syscall_info {
__u8 op; /* PTRACE_SYSCALL_INFO_* */
- __u8 pad[3];
+ __u8 reserved;
+ __u16 flags;
__u32 arch;
__u64 instruction_pointer;
__u64 stack_pointer;
@@ -98,6 +100,7 @@ struct ptrace_syscall_info {
__u64 nr;
__u64 args[6];
__u32 ret_data;
+ __u32 reserved2;
} seccomp;
};
};
@@ -142,6 +145,8 @@ struct ptrace_sud_config {
__u64 len;
};
+/* 0x4212 is PTRACE_SET_SYSCALL_INFO */
+
/*
* These values are stored in task->ptrace_message
* by ptrace_stop to describe the current syscall-stop.
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 22e7d74cf4cd..75a84efad40f 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -944,7 +944,10 @@ ptrace_get_syscall_info_seccomp(struct task_struct *child, struct pt_regs *regs,
ptrace_get_syscall_info_entry(child, regs, info);
info->seccomp.ret_data = child->ptrace_message;
- /* ret_data is the last field in struct ptrace_syscall_info.seccomp */
+ /*
+ * ret_data is the last non-reserved field
+ * in struct ptrace_syscall_info.seccomp
+ */
return offsetofend(struct ptrace_syscall_info, seccomp.ret_data);
}
@@ -1016,6 +1019,118 @@ ptrace_get_syscall_info(struct task_struct *child, unsigned long user_size,
write_size = min(actual_size, user_size);
return copy_to_user(datavp, &info, write_size) ? -EFAULT : actual_size;
}
+
+static int
+ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs,
+ struct ptrace_syscall_info *info)
+{
+ unsigned long args[ARRAY_SIZE(info->entry.args)];
+ int nr = info->entry.nr;
+ int i;
+
+ /*
+ * Check that the syscall number specified in info->entry.nr
+ * is either a value of type "int" or a sign-extended value
+ * of type "int".
+ */
+ if (nr != info->entry.nr)
+ return -ERANGE;
+
+ for (i = 0; i < ARRAY_SIZE(args); i++) {
+ args[i] = info->entry.args[i];
+ /*
+ * Check that the syscall argument specified in
+ * info->entry.args[i] is either a value of type
+ * "unsigned long" or a sign-extended value of type "long".
+ */
+ if (args[i] != info->entry.args[i])
+ return -ERANGE;
+ }
+
+ syscall_set_nr(child, regs, nr);
+ /*
+ * If the syscall number is set to -1, setting syscall arguments is not
+ * just pointless, it would also clobber the syscall return value on
+ * those architectures that share the same register both for the first
+ * argument of syscall and its return value.
+ */
+ if (nr != -1)
+ syscall_set_arguments(child, regs, args);
+
+ return 0;
+}
+
+static int
+ptrace_set_syscall_info_seccomp(struct task_struct *child, struct pt_regs *regs,
+ struct ptrace_syscall_info *info)
+{
+ /*
+ * info->entry is currently a subset of info->seccomp,
+ * info->seccomp.ret_data is currently ignored.
+ */
+ return ptrace_set_syscall_info_entry(child, regs, info);
+}
+
+static int
+ptrace_set_syscall_info_exit(struct task_struct *child, struct pt_regs *regs,
+ struct ptrace_syscall_info *info)
+{
+ long rval = info->exit.rval;
+
+ /*
+ * Check that the return value specified in info->exit.rval
+ * is either a value of type "long" or a sign-extended value
+ * of type "long".
+ */
+ if (rval != info->exit.rval)
+ return -ERANGE;
+
+ if (info->exit.is_error)
+ syscall_set_return_value(child, regs, rval, 0);
+ else
+ syscall_set_return_value(child, regs, 0, rval);
+
+ return 0;
+}
+
+static int
+ptrace_set_syscall_info(struct task_struct *child, unsigned long user_size,
+ const void __user *datavp)
+{
+ struct pt_regs *regs = task_pt_regs(child);
+ struct ptrace_syscall_info info;
+
+ if (user_size < sizeof(info))
+ return -EINVAL;
+
+ /*
+ * The compatibility is tracked by info.op and info.flags: if user-space
+ * does not instruct us to use unknown extra bits from future versions
+ * of ptrace_syscall_info, we are not going to read them either.
+ */
+ if (copy_from_user(&info, datavp, sizeof(info)))
+ return -EFAULT;
+
+ /* Reserved for future use. */
+ if (info.flags || info.reserved)
+ return -EINVAL;
+
+ /* Changing the type of the system call stop is not supported yet. */
+ if (ptrace_get_syscall_info_op(child) != info.op)
+ return -EINVAL;
+
+ switch (info.op) {
+ case PTRACE_SYSCALL_INFO_ENTRY:
+ return ptrace_set_syscall_info_entry(child, regs, &info);
+ case PTRACE_SYSCALL_INFO_EXIT:
+ return ptrace_set_syscall_info_exit(child, regs, &info);
+ case PTRACE_SYSCALL_INFO_SECCOMP:
+ return ptrace_set_syscall_info_seccomp(child, regs, &info);
+ default:
+ /* Other types of system call stops are not supported yet. */
+ return -EINVAL;
+ }
+}
#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */
int ptrace_request(struct task_struct *child, long request,
@@ -1234,6 +1349,10 @@ int ptrace_request(struct task_struct *child, long request,
case PTRACE_GET_SYSCALL_INFO:
ret = ptrace_get_syscall_info(child, addr, datavp);
break;
+
+ case PTRACE_SET_SYSCALL_INFO:
+ ret = ptrace_set_syscall_info(child, addr, datavp);
+ break;
#endif
case PTRACE_SECCOMP_GET_FILTER:
--
ldv
^ permalink raw reply related
* Re: [PATCH bpf-next] uprobes: Harden uretprobe syscall trampoline check
From: Oleg Nesterov @ 2025-02-10 12:07 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Peter Zijlstra, Andrii Nakryiko,
Kees Cook, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
In-Reply-To: <20250209220515.2554058-1-jolsa@kernel.org>
On 02/09, Jiri Olsa wrote:
>
> [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> Cc: Kees Cook <kees@kernel.org>
> Cc: Eyal Birger <eyal.birger@gmail.com>
> Cc: stable@vger.kernel.org
> Reported-by: Jann Horn <jannh@google.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> arch/x86/kernel/uprobes.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
^ permalink raw reply
* Re: [PATCH bpf-next] uprobes: Harden uretprobe syscall trampoline check
From: Andrii Nakryiko @ 2025-02-10 17:26 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Kees Cook, Eyal Birger, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <20250209220515.2554058-1-jolsa@kernel.org>
On Sun, Feb 9, 2025 at 2:05 PM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Jann reported [1] possible issue when trampoline_check_ip returns
> address near the bottom of the address space that is allowed to
> call into the syscall if uretprobes are not set up.
>
> Though the mmap minimum address restrictions will typically prevent
> creating mappings there, let's make sure uretprobe syscall checks
> for that.
>
> [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> Cc: Kees Cook <kees@kernel.org>
> Cc: Eyal Birger <eyal.birger@gmail.com>
> Cc: stable@vger.kernel.org
> Reported-by: Jann Horn <jannh@google.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> arch/x86/kernel/uprobes.c | 14 +++++++++-----
> 1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 5a952c5ea66b..109d6641a1b3 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
> return &insn;
> }
>
> -static unsigned long trampoline_check_ip(void)
> +static unsigned long trampoline_check_ip(unsigned long tramp)
> {
> - unsigned long tramp = uprobe_get_trampoline_vaddr();
> -
> return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
> }
>
> SYSCALL_DEFINE0(uretprobe)
> {
> struct pt_regs *regs = task_pt_regs(current);
> - unsigned long err, ip, sp, r11_cx_ax[3];
> + unsigned long err, ip, sp, r11_cx_ax[3], tramp;
> +
> + /* If there's no trampoline, we are called from wrong place. */
> + tramp = uprobe_get_trampoline_vaddr();
> + if (tramp == -1)
slight nit: mixing -1 and unsigned long looks sloppy. Maybe let's add
something like
#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
and return that from uprobe_get_trampoline_vaddr()?
> + goto sigill;
>
> - if (regs->ip != trampoline_check_ip())
> + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> + if (regs->ip != trampoline_check_ip(tramp))
> goto sigill;
>
> err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
> --
> 2.48.1
>
^ permalink raw reply
* Re: [PATCH bpf-next] uprobes: Harden uretprobe syscall trampoline check
From: Kees Cook @ 2025-02-10 23:00 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
In-Reply-To: <20250209220515.2554058-1-jolsa@kernel.org>
On Sun, Feb 09, 2025 at 11:05:15PM +0100, Jiri Olsa wrote:
> Jann reported [1] possible issue when trampoline_check_ip returns
> address near the bottom of the address space that is allowed to
> call into the syscall if uretprobes are not set up.
>
> Though the mmap minimum address restrictions will typically prevent
> creating mappings there, let's make sure uretprobe syscall checks
> for that.
>
> [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> Cc: Kees Cook <kees@kernel.org>
> Cc: Eyal Birger <eyal.birger@gmail.com>
> Cc: stable@vger.kernel.org
> Reported-by: Jann Horn <jannh@google.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Thanks for this!
Reviewed-by: Kees Cook <kees@kernel.org>
--
Kees Cook
^ permalink raw reply
* Re: [PATCH bpf-next] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-11 8:35 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Kees Cook, Eyal Birger, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <CAEf4BzbpKReuNhdH6RnwYOyYxFwgJjjgUB_2xwU=dGkC--K=Kg@mail.gmail.com>
On Mon, Feb 10, 2025 at 09:26:53AM -0800, Andrii Nakryiko wrote:
> On Sun, Feb 9, 2025 at 2:05 PM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Jann reported [1] possible issue when trampoline_check_ip returns
> > address near the bottom of the address space that is allowed to
> > call into the syscall if uretprobes are not set up.
> >
> > Though the mmap minimum address restrictions will typically prevent
> > creating mappings there, let's make sure uretprobe syscall checks
> > for that.
> >
> > [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> > Cc: Kees Cook <kees@kernel.org>
> > Cc: Eyal Birger <eyal.birger@gmail.com>
> > Cc: stable@vger.kernel.org
> > Reported-by: Jann Horn <jannh@google.com>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > arch/x86/kernel/uprobes.c | 14 +++++++++-----
> > 1 file changed, 9 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> > index 5a952c5ea66b..109d6641a1b3 100644
> > --- a/arch/x86/kernel/uprobes.c
> > +++ b/arch/x86/kernel/uprobes.c
> > @@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
> > return &insn;
> > }
> >
> > -static unsigned long trampoline_check_ip(void)
> > +static unsigned long trampoline_check_ip(unsigned long tramp)
> > {
> > - unsigned long tramp = uprobe_get_trampoline_vaddr();
> > -
> > return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
> > }
> >
> > SYSCALL_DEFINE0(uretprobe)
> > {
> > struct pt_regs *regs = task_pt_regs(current);
> > - unsigned long err, ip, sp, r11_cx_ax[3];
> > + unsigned long err, ip, sp, r11_cx_ax[3], tramp;
> > +
> > + /* If there's no trampoline, we are called from wrong place. */
> > + tramp = uprobe_get_trampoline_vaddr();
> > + if (tramp == -1)
>
> slight nit: mixing -1 and unsigned long looks sloppy. Maybe let's add
> something like
>
> #define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
>
> and return that from uprobe_get_trampoline_vaddr()?
ok, will add that
thanks,
jirka
>
> > + goto sigill;
> >
> > - if (regs->ip != trampoline_check_ip())
> > + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> > + if (regs->ip != trampoline_check_ip(tramp))
> > goto sigill;
> >
> > err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
> > --
> > 2.48.1
> >
^ permalink raw reply
* [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-11 11:15 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko
Cc: Kees Cook, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
Jann reported [1] possible issue when trampoline_check_ip returns
address near the bottom of the address space that is allowed to
call into the syscall if uretprobes are not set up.
Though the mmap minimum address restrictions will typically prevent
creating mappings there, let's make sure uretprobe syscall checks
for that.
[1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
Cc: Kees Cook <kees@kernel.org>
Cc: Eyal Birger <eyal.birger@gmail.com>
Cc: stable@vger.kernel.org
Fixes: ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
Reported-by: Jann Horn <jannh@google.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
v2 changes:
- adding UPROBE_NO_TRAMPOLINE_VADDR macro (Andrii)
- rebased on top of perf/core
arch/x86/kernel/uprobes.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5a952c5ea66b..e8d3c59aa9f7 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -357,19 +357,25 @@ void *arch_uprobe_trampoline(unsigned long *psize)
return &insn;
}
-static unsigned long trampoline_check_ip(void)
+static unsigned long trampoline_check_ip(unsigned long tramp)
{
- unsigned long tramp = uprobe_get_trampoline_vaddr();
-
return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
}
+#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
+
SYSCALL_DEFINE0(uretprobe)
{
struct pt_regs *regs = task_pt_regs(current);
- unsigned long err, ip, sp, r11_cx_ax[3];
+ unsigned long err, ip, sp, r11_cx_ax[3], tramp;
+
+ /* If there's no trampoline, we are called from wrong place. */
+ tramp = uprobe_get_trampoline_vaddr();
+ if (tramp == UPROBE_NO_TRAMPOLINE_VADDR)
+ goto sigill;
- if (regs->ip != trampoline_check_ip())
+ /* Make sure the ip matches the only allowed sys_uretprobe caller. */
+ if (regs->ip != trampoline_check_ip(tramp))
goto sigill;
err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
--
2.48.1
^ permalink raw reply related
* Re: [PATCH v7 1/6] pidfd: add PIDFD_SELF* sentinels to refer to own thread/process
From: Michal Koutný @ 2025-02-11 15:24 UTC (permalink / raw)
To: Lorenzo Stoakes
Cc: Christian Brauner, Shuah Khan, Liam R . Howlett,
Suren Baghdasaryan, Vlastimil Babka, pedro.falcato,
linux-kselftest, linux-mm, linux-fsdevel, linux-api, linux-kernel,
Oliver Sang, John Hubbard, Tejun Heo, Johannes Weiner,
Andrew Morton, Shakeel Butt
In-Reply-To: <24315a16a3d01a548dd45c7515f7d51c767e954e.1738268370.git.lorenzo.stoakes@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 653 bytes --]
On Thu, Jan 30, 2025 at 08:40:26PM +0000, Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
> include/uapi/linux/pidfd.h | 24 +++++++++
> kernel/pid.c | 24 +++++++--
> kernel/signal.c | 106 ++++++++++++++++++++++---------------
> 3 files changed, 107 insertions(+), 47 deletions(-)
Practical idea, thanks.
> diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h
> + * To cut the Gideon knot, for internal kernel usage, we refer to
A nit
https://en.wikipedia.org/wiki/Gordian_Knot
(if still applicable)
Michal
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v7 1/6] pidfd: add PIDFD_SELF* sentinels to refer to own thread/process
From: Lorenzo Stoakes @ 2025-02-11 15:45 UTC (permalink / raw)
To: Michal Koutný
Cc: Christian Brauner, Shuah Khan, Liam R . Howlett,
Suren Baghdasaryan, Vlastimil Babka, pedro.falcato,
linux-kselftest, linux-mm, linux-fsdevel, linux-api, linux-kernel,
Oliver Sang, John Hubbard, Tejun Heo, Johannes Weiner,
Andrew Morton, Shakeel Butt
In-Reply-To: <gij5nh63s73dj5u33uvzl5lbmsvoh6zr5xnqpnfltwi6aamy7j@47iop2wgtdac>
On Tue, Feb 11, 2025 at 04:24:07PM +0100, Michal Koutný wrote:
> On Thu, Jan 30, 2025 at 08:40:26PM +0000, Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
> >
> > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> > ---
> > include/uapi/linux/pidfd.h | 24 +++++++++
> > kernel/pid.c | 24 +++++++--
> > kernel/signal.c | 106 ++++++++++++++++++++++---------------
> > 3 files changed, 107 insertions(+), 47 deletions(-)
>
> Practical idea, thanks.
Thanks!
>
> > diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h
> > + * To cut the Gideon knot, for internal kernel usage, we refer to
>
> A nit
> https://en.wikipedia.org/wiki/Gordian_Knot
>
> (if still applicable)
MY GOD. Hahaha. How embarrassing. God knows how 'Gideon' ended up
there. Apologies to all, I appear to have had a senior moment there...
Feel free to correct Christian, unless we want to leave this as an Easter
Egg? :P
>
> Michal
^ permalink raw reply
* Re: [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Andrii Nakryiko @ 2025-02-11 16:47 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Kees Cook, Eyal Birger, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <20250211111559.2984778-1-jolsa@kernel.org>
On Tue, Feb 11, 2025 at 3:16 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Jann reported [1] possible issue when trampoline_check_ip returns
> address near the bottom of the address space that is allowed to
> call into the syscall if uretprobes are not set up.
>
> Though the mmap minimum address restrictions will typically prevent
> creating mappings there, let's make sure uretprobe syscall checks
> for that.
>
> [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> Cc: Kees Cook <kees@kernel.org>
> Cc: Eyal Birger <eyal.birger@gmail.com>
> Cc: stable@vger.kernel.org
> Fixes: ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> Reported-by: Jann Horn <jannh@google.com>
> Reviewed-by: Oleg Nesterov <oleg@redhat.com>
> Reviewed-by: Kees Cook <kees@kernel.org>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> v2 changes:
> - adding UPROBE_NO_TRAMPOLINE_VADDR macro (Andrii)
> - rebased on top of perf/core
>
> arch/x86/kernel/uprobes.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 5a952c5ea66b..e8d3c59aa9f7 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -357,19 +357,25 @@ void *arch_uprobe_trampoline(unsigned long *psize)
> return &insn;
> }
>
> -static unsigned long trampoline_check_ip(void)
> +static unsigned long trampoline_check_ip(unsigned long tramp)
> {
> - unsigned long tramp = uprobe_get_trampoline_vaddr();
> -
> return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
> }
>
> +#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
> +
> SYSCALL_DEFINE0(uretprobe)
> {
> struct pt_regs *regs = task_pt_regs(current);
> - unsigned long err, ip, sp, r11_cx_ax[3];
> + unsigned long err, ip, sp, r11_cx_ax[3], tramp;
> +
> + /* If there's no trampoline, we are called from wrong place. */
> + tramp = uprobe_get_trampoline_vaddr();
> + if (tramp == UPROBE_NO_TRAMPOLINE_VADDR)
> + goto sigill;
>
> - if (regs->ip != trampoline_check_ip())
> + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> + if (regs->ip != trampoline_check_ip(tramp))
> goto sigill;
>
LGTM. I don't know if that would make any difference, but I'd sprinkle
unlikely() around these two conditions to make sure they don't
interfere with instruction flow much
Acked-by: Andrii Nakryiko <andrii@kernel.org>
> err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
> --
> 2.48.1
>
^ permalink raw reply
* Re: [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Alexei Starovoitov @ 2025-02-11 16:52 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Jiri Olsa, Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Peter Zijlstra, Andrii Nakryiko, Kees Cook, Eyal Birger, stable,
Jann Horn, LKML, linux-trace-kernel, Linux API, X86 ML, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <CAEf4BzYPmtUirnO3Bp+3F3d4++4ttL_MZAG+yGcTTKTRK2X2vw@mail.gmail.com>
On Tue, Feb 11, 2025 at 8:48 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Tue, Feb 11, 2025 at 3:16 AM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Jann reported [1] possible issue when trampoline_check_ip returns
> > address near the bottom of the address space that is allowed to
> > call into the syscall if uretprobes are not set up.
> >
> > Though the mmap minimum address restrictions will typically prevent
> > creating mappings there, let's make sure uretprobe syscall checks
> > for that.
> >
> > [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> > Cc: Kees Cook <kees@kernel.org>
> > Cc: Eyal Birger <eyal.birger@gmail.com>
> > Cc: stable@vger.kernel.org
> > Fixes: ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> > Reported-by: Jann Horn <jannh@google.com>
> > Reviewed-by: Oleg Nesterov <oleg@redhat.com>
> > Reviewed-by: Kees Cook <kees@kernel.org>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> > v2 changes:
> > - adding UPROBE_NO_TRAMPOLINE_VADDR macro (Andrii)
> > - rebased on top of perf/core
> >
> > arch/x86/kernel/uprobes.c | 16 +++++++++++-----
> > 1 file changed, 11 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> > index 5a952c5ea66b..e8d3c59aa9f7 100644
> > --- a/arch/x86/kernel/uprobes.c
> > +++ b/arch/x86/kernel/uprobes.c
> > @@ -357,19 +357,25 @@ void *arch_uprobe_trampoline(unsigned long *psize)
> > return &insn;
> > }
> >
> > -static unsigned long trampoline_check_ip(void)
> > +static unsigned long trampoline_check_ip(unsigned long tramp)
> > {
> > - unsigned long tramp = uprobe_get_trampoline_vaddr();
> > -
> > return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
> > }
> >
> > +#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
If you respin anyway maybe use ~0UL instead?
In the above and in
uprobe_get_trampoline_vaddr(),
since
unsigned long trampoline_vaddr = -1;
looks odd too.
^ permalink raw reply
* Re: [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Oleg Nesterov @ 2025-02-11 16:59 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Andrii Nakryiko, Jiri Olsa, Steven Rostedt, Masami Hiramatsu,
Peter Zijlstra, Andrii Nakryiko, Kees Cook, Eyal Birger, stable,
Jann Horn, LKML, linux-trace-kernel, Linux API, X86 ML, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <CAADnVQJ05xkXw+c_T1qB+ECUqO5sJxDVJ3bypjS3KSQCTJb-1g@mail.gmail.com>
On 02/11, Alexei Starovoitov wrote:
>
> > > +#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
>
> If you respin anyway maybe use ~0UL instead?
> In the above and in
> uprobe_get_trampoline_vaddr(),
> since
>
> unsigned long trampoline_vaddr = -1;
... or -1ul in both cases.
I agree, UPROBE_NO_TRAMPOLINE_VADDR has a single user, looks
a bit strange...
Oleg.
^ permalink raw reply
* [PATCH v3] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Andrey Albershteyn @ 2025-02-11 17:22 UTC (permalink / raw)
To: Richard Henderson, Matt Turner, Russell King, Catalin Marinas,
Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Christian Brauner, Jan Kara, Mickaël Salaün,
Günther Noack, Arnd Bergmann
Cc: linux-alpha, linux-kernel, linux-arm-kernel, linux-m68k,
linux-mips, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-fsdevel, linux-security-module, linux-api,
linux-arch, Andrey Albershteyn, linux-xfs
From: Andrey Albershteyn <aalbersh@redhat.com>
Introduce getfsxattrat and setfsxattrat syscalls to manipulate inode
extended attributes/flags. The syscalls take parent directory fd and
path to the child together with struct fsxattr.
This is an alternative to FS_IOC_FSSETXATTR ioctl with a difference
that file don't need to be open as we can reference it with a path
instead of fd. By having this we can manipulated inode extended
attributes not only on regular files but also on special ones. This
is not possible with FS_IOC_FSSETXATTR ioctl as with special files
we can not call ioctl() directly on the filesystem inode using fd.
This patch adds two new syscalls which allows userspace to get/set
extended inode attributes on special files by using parent directory
and a path - *at() like syscall.
Also, as vfs_fileattr_set() is now will be called on special files
too, let's forbid any other attributes except projid and nextents
(symlink can have an extent).
CC: linux-api@vger.kernel.org
CC: linux-fsdevel@vger.kernel.org
CC: linux-xfs@vger.kernel.org
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
v1:
https://lore.kernel.org/linuxppc-dev/20250109174540.893098-1-aalbersh@kernel.org/
Previous discussion:
https://lore.kernel.org/linux-xfs/20240520164624.665269-2-aalbersh@redhat.com/
XFS has project quotas which could be attached to a directory. All
new inodes in these directories inherit project ID set on parent
directory.
The project is created from userspace by opening and calling
FS_IOC_FSSETXATTR on each inode. This is not possible for special
files such as FIFO, SOCK, BLK etc. Therefore, some inodes are left
with empty project ID. Those inodes then are not shown in the quota
accounting but still exist in the directory. Moreover, in the case
when special files are created in the directory with already
existing project quota, these inode inherit extended attributes.
This than leaves them with these attributes without the possibility
to clear them out. This, in turn, prevents userspace from
re-creating quota project on these existing files.
---
Changes in v3:
- Remove unnecessary "dfd is dir" check as it checked in user_path_at()
- Remove unnecessary "same filesystem" check
- Use CLASS() instead of directly calling fdget/fdput
- Link to v2: https://lore.kernel.org/r/20250122-xattrat-syscall-v2-1-5b360d4fbcb2@kernel.org
---
arch/alpha/kernel/syscalls/syscall.tbl | 2 +
arch/arm/tools/syscall.tbl | 2 +
arch/arm64/tools/syscall_32.tbl | 2 +
arch/m68k/kernel/syscalls/syscall.tbl | 2 +
arch/microblaze/kernel/syscalls/syscall.tbl | 2 +
arch/mips/kernel/syscalls/syscall_n32.tbl | 2 +
arch/mips/kernel/syscalls/syscall_n64.tbl | 2 +
arch/mips/kernel/syscalls/syscall_o32.tbl | 2 +
arch/parisc/kernel/syscalls/syscall.tbl | 2 +
arch/powerpc/kernel/syscalls/syscall.tbl | 2 +
arch/s390/kernel/syscalls/syscall.tbl | 2 +
arch/sh/kernel/syscalls/syscall.tbl | 2 +
arch/sparc/kernel/syscalls/syscall.tbl | 2 +
arch/x86/entry/syscalls/syscall_32.tbl | 2 +
arch/x86/entry/syscalls/syscall_64.tbl | 2 +
arch/xtensa/kernel/syscalls/syscall.tbl | 2 +
fs/inode.c | 75 +++++++++++++++++++++++++++++
fs/ioctl.c | 16 +++++-
include/linux/fileattr.h | 1 +
include/linux/syscalls.h | 4 ++
include/uapi/asm-generic/unistd.h | 8 ++-
21 files changed, 133 insertions(+), 3 deletions(-)
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index c59d53d6d3f3490f976ca179ddfe02e69265ae4d..4b9e687494c16b60c6fd6ca1dc4d6564706a7e25 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -506,3 +506,5 @@
574 common getxattrat sys_getxattrat
575 common listxattrat sys_listxattrat
576 common removexattrat sys_removexattrat
+577 common getfsxattrat sys_getfsxattrat
+578 common setfsxattrat sys_setfsxattrat
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 49eeb2ad8dbd8e074c6240417693f23fb328afa8..66466257f3c2debb3e2299f0b608c6740c98cab2 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -481,3 +481,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/arm64/tools/syscall_32.tbl b/arch/arm64/tools/syscall_32.tbl
index 69a829912a05eb8a3e21ed701d1030e31c0148bc..9c516118b154811d8d11d5696f32817430320dbf 100644
--- a/arch/arm64/tools/syscall_32.tbl
+++ b/arch/arm64/tools/syscall_32.tbl
@@ -478,3 +478,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index f5ed71f1910d09769c845c2d062d99ee0449437c..159476387f394a92ee5e29db89b118c630372db2 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -466,3 +466,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index 680f568b77f2cbefc3eacb2517f276041f229b1e..a6d59ee740b58cacf823702003cf9bad17c0d3b7 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -472,3 +472,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 0b9b7e25b69ad592642f8533bee9ccfe95ce9626..cfe38fcebe1a0279e11751378d3e71c5ec6b6569 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -405,3 +405,5 @@
464 n32 getxattrat sys_getxattrat
465 n32 listxattrat sys_listxattrat
466 n32 removexattrat sys_removexattrat
+467 n32 getfsxattrat sys_getfsxattrat
+468 n32 setfsxattrat sys_setfsxattrat
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index c844cd5cda620b2809a397cdd6f4315ab6a1bfe2..29a0c5974d1aa2f01e33edc0252d75fb97abe230 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -381,3 +381,5 @@
464 n64 getxattrat sys_getxattrat
465 n64 listxattrat sys_listxattrat
466 n64 removexattrat sys_removexattrat
+467 n64 getfsxattrat sys_getfsxattrat
+468 n64 setfsxattrat sys_setfsxattrat
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 349b8aad1159f404103bd2057a1e64e9bf309f18..6c00436807c57c492ba957fcd59af1202231cf80 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -454,3 +454,5 @@
464 o32 getxattrat sys_getxattrat
465 o32 listxattrat sys_listxattrat
466 o32 removexattrat sys_removexattrat
+467 o32 getfsxattrat sys_getfsxattrat
+468 o32 setfsxattrat sys_setfsxattrat
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index d9fc94c869657fcfbd7aca1d5f5abc9fae2fb9d8..b3578fac43d6b65167787fcc97d2d09f5a9828e7 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -465,3 +465,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index d8b4ab78bef076bd50d49b87dea5060fd8c1686a..808045d82c9465c3bfa96b15947546efe5851e9a 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -557,3 +557,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index e9115b4d8b635b846e5c9ad6ce229605323723a5..78dfc2c184d4815baf8a9e61c546c9936d58a47c 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -469,3 +469,5 @@
464 common getxattrat sys_getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat sys_setfsxattrat
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index c8cad33bf250ea110de37bd1407f5a43ec5e38f2..d5a5c8339f0ed25ea07c4aba90351d352033c8a0 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -470,3 +470,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 727f99d333b304b3db0711953a3d91ece18a28eb..817dcd8603bcbffc47f3f59aa3b74b16486453d0 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -512,3 +512,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 4d0fb2fba7e208ae9455459afe11e277321d9f74..b4842c027c5d00c0236b2ba89387c5e2267447bd 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -472,3 +472,5 @@
464 i386 getxattrat sys_getxattrat
465 i386 listxattrat sys_listxattrat
466 i386 removexattrat sys_removexattrat
+467 i386 getfsxattrat sys_getfsxattrat
+468 i386 setfsxattrat sys_setfsxattrat
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 5eb708bff1c791debd6cfc5322583b2ae53f6437..b6f0a7236aaee624cf9b484239a1068085a8ffe1 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -390,6 +390,8 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
#
# Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 37effc1b134eea061f2c350c1d68b4436b65a4dd..425d56be337d1de22f205ac503df61ff86224fee 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -437,3 +437,5 @@
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
+467 common getfsxattrat sys_getfsxattrat
+468 common setfsxattrat sys_setfsxattrat
diff --git a/fs/inode.c b/fs/inode.c
index 6b4c77268fc0ecace4ac78a9ca777fbffc277f4a..b2dddd9db4fabaf67a6cbf541a86978b290411ec 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -23,6 +23,9 @@
#include <linux/rw_hint.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/syscalls.h>
+#include <linux/fileattr.h>
+#include <linux/namei.h>
#include <trace/events/writeback.h>
#define CREATE_TRACE_POINTS
#include <trace/events/timestamp.h>
@@ -2953,3 +2956,75 @@ umode_t mode_strip_sgid(struct mnt_idmap *idmap,
return mode & ~S_ISGID;
}
EXPORT_SYMBOL(mode_strip_sgid);
+
+SYSCALL_DEFINE4(getfsxattrat, int, dfd, const char __user *, filename,
+ struct fsxattr __user *, fsx, unsigned int, at_flags)
+{
+ CLASS(fd, dir)(dfd);
+ struct fileattr fa;
+ struct path filepath;
+ int error;
+ unsigned int lookup_flags = 0;
+
+ if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ if (at_flags & AT_SYMLINK_FOLLOW)
+ lookup_flags |= LOOKUP_FOLLOW;
+
+ if (at_flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
+
+ if (fd_empty(dir))
+ return -EBADF;
+
+ error = user_path_at(dfd, filename, lookup_flags, &filepath);
+ if (error)
+ return error;
+
+ error = vfs_fileattr_get(filepath.dentry, &fa);
+ if (!error)
+ error = copy_fsxattr_to_user(&fa, fsx);
+
+ path_put(&filepath);
+ return error;
+}
+
+SYSCALL_DEFINE4(setfsxattrat, int, dfd, const char __user *, filename,
+ struct fsxattr __user *, fsx, unsigned int, at_flags)
+{
+ CLASS(fd, dir)(dfd);
+ struct fileattr fa;
+ struct path filepath;
+ int error;
+ unsigned int lookup_flags = 0;
+
+ if ((at_flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
+ return -EINVAL;
+
+ if (at_flags & AT_SYMLINK_FOLLOW)
+ lookup_flags |= LOOKUP_FOLLOW;
+
+ if (at_flags & AT_EMPTY_PATH)
+ lookup_flags |= LOOKUP_EMPTY;
+
+ if (fd_empty(dir))
+ return -EBADF;
+
+ if (copy_fsxattr_from_user(&fa, fsx))
+ return -EFAULT;
+
+ error = user_path_at(dfd, filename, lookup_flags, &filepath);
+ if (error)
+ return error;
+
+ error = mnt_want_write(filepath.mnt);
+ if (!error) {
+ error = vfs_fileattr_set(file_mnt_idmap(fd_file(dir)),
+ filepath.dentry, &fa);
+ mnt_drop_write(filepath.mnt);
+ }
+
+ path_put(&filepath);
+ return error;
+}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 638a36be31c14afc66a7fd6eb237d9545e8ad997..dc160c2ef145e4931d625f1f93c2a8ae7f87abf3 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -558,8 +558,7 @@ int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
}
EXPORT_SYMBOL(copy_fsxattr_to_user);
-static int copy_fsxattr_from_user(struct fileattr *fa,
- struct fsxattr __user *ufa)
+int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa)
{
struct fsxattr xfa;
@@ -646,6 +645,19 @@ static int fileattr_set_prepare(struct inode *inode,
if (fa->fsx_cowextsize == 0)
fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
+ /*
+ * The only use case for special files is to set project ID, forbid any
+ * other attributes
+ */
+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+ if (fa->fsx_xflags & ~FS_XFLAG_PROJINHERIT)
+ return -EINVAL;
+ if (!S_ISLNK(inode->i_mode) && fa->fsx_nextents)
+ return -EINVAL;
+ if (fa->fsx_extsize || fa->fsx_cowextsize)
+ return -EINVAL;
+ }
+
return 0;
}
diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
index 47c05a9851d0600964b644c9c7218faacfd865f8..8598e94b530b8b280a2697eaf918dd60f573d6ee 100644
--- a/include/linux/fileattr.h
+++ b/include/linux/fileattr.h
@@ -34,6 +34,7 @@ struct fileattr {
};
int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa);
+int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa);
void fileattr_fill_xflags(struct fileattr *fa, u32 xflags);
void fileattr_fill_flags(struct fileattr *fa, u32 flags);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index c6333204d45130eb022f6db460eea34a1f6e91db..3134d463d9af64c6e78adb37bff4b91f77b5305f 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -371,6 +371,10 @@ asmlinkage long sys_removexattrat(int dfd, const char __user *path,
asmlinkage long sys_lremovexattr(const char __user *path,
const char __user *name);
asmlinkage long sys_fremovexattr(int fd, const char __user *name);
+asmlinkage long sys_getfsxattrat(int dfd, const char __user *filename,
+ struct fsxattr *fsx, unsigned int at_flags);
+asmlinkage long sys_setfsxattrat(int dfd, const char __user *filename,
+ struct fsxattr *fsx, unsigned int at_flags);
asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
asmlinkage long sys_eventfd2(unsigned int count, int flags);
asmlinkage long sys_epoll_create1(int flags);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 88dc393c2bca38c0fa1b3fae579f7cfe4931223c..50be2e1007bc2779120d05c6e9512a689f86779c 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -850,8 +850,14 @@ __SYSCALL(__NR_listxattrat, sys_listxattrat)
#define __NR_removexattrat 466
__SYSCALL(__NR_removexattrat, sys_removexattrat)
+/* fs/inode.c */
+#define __NR_getfsxattrat 467
+__SYSCALL(__NR_getfsxattrat, sys_getfsxattrat)
+#define __NR_setfsxattrat 468
+__SYSCALL(__NR_setfsxattrat, sys_setfsxattrat)
+
#undef __NR_syscalls
-#define __NR_syscalls 467
+#define __NR_syscalls 469
/*
* 32 bit systems traditionally used different
---
base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04
change-id: 20250114-xattrat-syscall-6a1136d2db59
Best regards,
--
Andrey Albershteyn <aalbersh@kernel.org>
^ permalink raw reply related
* Re: [PATCH v3] fs: introduce getfsxattrat and setfsxattrat syscalls
From: H. Peter Anvin @ 2025-02-11 19:09 UTC (permalink / raw)
To: Andrey Albershteyn, Richard Henderson, Matt Turner, Russell King,
Catalin Marinas, Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
Chris Zankel, Max Filippov, Alexander Viro, Christian Brauner,
Jan Kara, Mickaël Salaün, Günther Noack,
Arnd Bergmann
Cc: linux-alpha, linux-kernel, linux-arm-kernel, linux-m68k,
linux-mips, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-fsdevel, linux-security-module, linux-api,
linux-arch, linux-xfs
In-Reply-To: <20250211-xattrat-syscall-v3-1-a07d15f898b2@kernel.org>
On February 11, 2025 9:22:47 AM PST, Andrey Albershteyn <aalbersh@redhat.com> wrote:
>From: Andrey Albershteyn <aalbersh@redhat.com>
>
>Introduce getfsxattrat and setfsxattrat syscalls to manipulate inode
>extended attributes/flags. The syscalls take parent directory fd and
>path to the child together with struct fsxattr.
>
>This is an alternative to FS_IOC_FSSETXATTR ioctl with a difference
>that file don't need to be open as we can reference it with a path
>instead of fd. By having this we can manipulated inode extended
>attributes not only on regular files but also on special ones. This
>is not possible with FS_IOC_FSSETXATTR ioctl as with special files
>we can not call ioctl() directly on the filesystem inode using fd.
>
>This patch adds two new syscalls which allows userspace to get/set
>extended inode attributes on special files by using parent directory
>and a path - *at() like syscall.
>
>Also, as vfs_fileattr_set() is now will be called on special files
>too, let's forbid any other attributes except projid and nextents
>(symlink can have an extent).
>
>CC: linux-api@vger.kernel.org
>CC: linux-fsdevel@vger.kernel.org
>CC: linux-xfs@vger.kernel.org
>Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
>---
>v1:
>https://lore.kernel.org/linuxppc-dev/20250109174540.893098-1-aalbersh@kernel.org/
>
>Previous discussion:
>https://lore.kernel.org/linux-xfs/20240520164624.665269-2-aalbersh@redhat.com/
>
>XFS has project quotas which could be attached to a directory. All
>new inodes in these directories inherit project ID set on parent
>directory.
>
>The project is created from userspace by opening and calling
>FS_IOC_FSSETXATTR on each inode. This is not possible for special
>files such as FIFO, SOCK, BLK etc. Therefore, some inodes are left
>with empty project ID. Those inodes then are not shown in the quota
>accounting but still exist in the directory. Moreover, in the case
>when special files are created in the directory with already
>existing project quota, these inode inherit extended attributes.
>This than leaves them with these attributes without the possibility
>to clear them out. This, in turn, prevents userspace from
>re-creating quota project on these existing files.
>---
>Changes in v3:
>- Remove unnecessary "dfd is dir" check as it checked in user_path_at()
>- Remove unnecessary "same filesystem" check
>- Use CLASS() instead of directly calling fdget/fdput
>- Link to v2: https://lore.kernel.org/r/20250122-xattrat-syscall-v2-1-5b360d4fbcb2@kernel.org
>---
> arch/alpha/kernel/syscalls/syscall.tbl | 2 +
> arch/arm/tools/syscall.tbl | 2 +
> arch/arm64/tools/syscall_32.tbl | 2 +
> arch/m68k/kernel/syscalls/syscall.tbl | 2 +
> arch/microblaze/kernel/syscalls/syscall.tbl | 2 +
> arch/mips/kernel/syscalls/syscall_n32.tbl | 2 +
> arch/mips/kernel/syscalls/syscall_n64.tbl | 2 +
> arch/mips/kernel/syscalls/syscall_o32.tbl | 2 +
> arch/parisc/kernel/syscalls/syscall.tbl | 2 +
> arch/powerpc/kernel/syscalls/syscall.tbl | 2 +
> arch/s390/kernel/syscalls/syscall.tbl | 2 +
> arch/sh/kernel/syscalls/syscall.tbl | 2 +
> arch/sparc/kernel/syscalls/syscall.tbl | 2 +
> arch/x86/entry/syscalls/syscall_32.tbl | 2 +
> arch/x86/entry/syscalls/syscall_64.tbl | 2 +
> arch/xtensa/kernel/syscalls/syscall.tbl | 2 +
> fs/inode.c | 75 +++++++++++++++++++++++++++++
> fs/ioctl.c | 16 +++++-
> include/linux/fileattr.h | 1 +
> include/linux/syscalls.h | 4 ++
> include/uapi/asm-generic/unistd.h | 8 ++-
> 21 files changed, 133 insertions(+), 3 deletions(-)
>
>diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
>index c59d53d6d3f3490f976ca179ddfe02e69265ae4d..4b9e687494c16b60c6fd6ca1dc4d6564706a7e25 100644
>--- a/arch/alpha/kernel/syscalls/syscall.tbl
>+++ b/arch/alpha/kernel/syscalls/syscall.tbl
>@@ -506,3 +506,5 @@
> 574 common getxattrat sys_getxattrat
> 575 common listxattrat sys_listxattrat
> 576 common removexattrat sys_removexattrat
>+577 common getfsxattrat sys_getfsxattrat
>+578 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
>index 49eeb2ad8dbd8e074c6240417693f23fb328afa8..66466257f3c2debb3e2299f0b608c6740c98cab2 100644
>--- a/arch/arm/tools/syscall.tbl
>+++ b/arch/arm/tools/syscall.tbl
>@@ -481,3 +481,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/arm64/tools/syscall_32.tbl b/arch/arm64/tools/syscall_32.tbl
>index 69a829912a05eb8a3e21ed701d1030e31c0148bc..9c516118b154811d8d11d5696f32817430320dbf 100644
>--- a/arch/arm64/tools/syscall_32.tbl
>+++ b/arch/arm64/tools/syscall_32.tbl
>@@ -478,3 +478,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
>index f5ed71f1910d09769c845c2d062d99ee0449437c..159476387f394a92ee5e29db89b118c630372db2 100644
>--- a/arch/m68k/kernel/syscalls/syscall.tbl
>+++ b/arch/m68k/kernel/syscalls/syscall.tbl
>@@ -466,3 +466,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
>index 680f568b77f2cbefc3eacb2517f276041f229b1e..a6d59ee740b58cacf823702003cf9bad17c0d3b7 100644
>--- a/arch/microblaze/kernel/syscalls/syscall.tbl
>+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
>@@ -472,3 +472,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
>index 0b9b7e25b69ad592642f8533bee9ccfe95ce9626..cfe38fcebe1a0279e11751378d3e71c5ec6b6569 100644
>--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
>+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
>@@ -405,3 +405,5 @@
> 464 n32 getxattrat sys_getxattrat
> 465 n32 listxattrat sys_listxattrat
> 466 n32 removexattrat sys_removexattrat
>+467 n32 getfsxattrat sys_getfsxattrat
>+468 n32 setfsxattrat sys_setfsxattrat
>diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
>index c844cd5cda620b2809a397cdd6f4315ab6a1bfe2..29a0c5974d1aa2f01e33edc0252d75fb97abe230 100644
>--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
>+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
>@@ -381,3 +381,5 @@
> 464 n64 getxattrat sys_getxattrat
> 465 n64 listxattrat sys_listxattrat
> 466 n64 removexattrat sys_removexattrat
>+467 n64 getfsxattrat sys_getfsxattrat
>+468 n64 setfsxattrat sys_setfsxattrat
>diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
>index 349b8aad1159f404103bd2057a1e64e9bf309f18..6c00436807c57c492ba957fcd59af1202231cf80 100644
>--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
>+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
>@@ -454,3 +454,5 @@
> 464 o32 getxattrat sys_getxattrat
> 465 o32 listxattrat sys_listxattrat
> 466 o32 removexattrat sys_removexattrat
>+467 o32 getfsxattrat sys_getfsxattrat
>+468 o32 setfsxattrat sys_setfsxattrat
>diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
>index d9fc94c869657fcfbd7aca1d5f5abc9fae2fb9d8..b3578fac43d6b65167787fcc97d2d09f5a9828e7 100644
>--- a/arch/parisc/kernel/syscalls/syscall.tbl
>+++ b/arch/parisc/kernel/syscalls/syscall.tbl
>@@ -465,3 +465,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
>index d8b4ab78bef076bd50d49b87dea5060fd8c1686a..808045d82c9465c3bfa96b15947546efe5851e9a 100644
>--- a/arch/powerpc/kernel/syscalls/syscall.tbl
>+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
>@@ -557,3 +557,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
>index e9115b4d8b635b846e5c9ad6ce229605323723a5..78dfc2c184d4815baf8a9e61c546c9936d58a47c 100644
>--- a/arch/s390/kernel/syscalls/syscall.tbl
>+++ b/arch/s390/kernel/syscalls/syscall.tbl
>@@ -469,3 +469,5 @@
> 464 common getxattrat sys_getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat sys_setfsxattrat
>diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
>index c8cad33bf250ea110de37bd1407f5a43ec5e38f2..d5a5c8339f0ed25ea07c4aba90351d352033c8a0 100644
>--- a/arch/sh/kernel/syscalls/syscall.tbl
>+++ b/arch/sh/kernel/syscalls/syscall.tbl
>@@ -470,3 +470,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
>index 727f99d333b304b3db0711953a3d91ece18a28eb..817dcd8603bcbffc47f3f59aa3b74b16486453d0 100644
>--- a/arch/sparc/kernel/syscalls/syscall.tbl
>+++ b/arch/sparc/kernel/syscalls/syscall.tbl
>@@ -512,3 +512,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
>index 4d0fb2fba7e208ae9455459afe11e277321d9f74..b4842c027c5d00c0236b2ba89387c5e2267447bd 100644
>--- a/arch/x86/entry/syscalls/syscall_32.tbl
>+++ b/arch/x86/entry/syscalls/syscall_32.tbl
>@@ -472,3 +472,5 @@
> 464 i386 getxattrat sys_getxattrat
> 465 i386 listxattrat sys_listxattrat
> 466 i386 removexattrat sys_removexattrat
>+467 i386 getfsxattrat sys_getfsxattrat
>+468 i386 setfsxattrat sys_setfsxattrat
>diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
>index 5eb708bff1c791debd6cfc5322583b2ae53f6437..b6f0a7236aaee624cf9b484239a1068085a8ffe1 100644
>--- a/arch/x86/entry/syscalls/syscall_64.tbl
>+++ b/arch/x86/entry/syscalls/syscall_64.tbl
>@@ -390,6 +390,8 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>
> #
> # Due to a historical design error, certain syscalls are numbered differently
>diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
>index 37effc1b134eea061f2c350c1d68b4436b65a4dd..425d56be337d1de22f205ac503df61ff86224fee 100644
>--- a/arch/xtensa/kernel/syscalls/syscall.tbl
>+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
>@@ -437,3 +437,5 @@
> 464 common getxattrat sys_getxattrat
> 465 common listxattrat sys_listxattrat
> 466 common removexattrat sys_removexattrat
>+467 common getfsxattrat sys_getfsxattrat
>+468 common setfsxattrat sys_setfsxattrat
>diff --git a/fs/inode.c b/fs/inode.c
>index 6b4c77268fc0ecace4ac78a9ca777fbffc277f4a..b2dddd9db4fabaf67a6cbf541a86978b290411ec 100644
>--- a/fs/inode.c
>+++ b/fs/inode.c
>@@ -23,6 +23,9 @@
> #include <linux/rw_hint.h>
> #include <linux/seq_file.h>
> #include <linux/debugfs.h>
>+#include <linux/syscalls.h>
>+#include <linux/fileattr.h>
>+#include <linux/namei.h>
> #include <trace/events/writeback.h>
> #define CREATE_TRACE_POINTS
> #include <trace/events/timestamp.h>
>@@ -2953,3 +2956,75 @@ umode_t mode_strip_sgid(struct mnt_idmap *idmap,
> return mode & ~S_ISGID;
> }
> EXPORT_SYMBOL(mode_strip_sgid);
>+
>+SYSCALL_DEFINE4(getfsxattrat, int, dfd, const char __user *, filename,
>+ struct fsxattr __user *, fsx, unsigned int, at_flags)
>+{
>+ CLASS(fd, dir)(dfd);
>+ struct fileattr fa;
>+ struct path filepath;
>+ int error;
>+ unsigned int lookup_flags = 0;
>+
>+ if ((at_flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
>+ return -EINVAL;
>+
>+ if (at_flags & AT_SYMLINK_FOLLOW)
>+ lookup_flags |= LOOKUP_FOLLOW;
>+
>+ if (at_flags & AT_EMPTY_PATH)
>+ lookup_flags |= LOOKUP_EMPTY;
>+
>+ if (fd_empty(dir))
>+ return -EBADF;
>+
>+ error = user_path_at(dfd, filename, lookup_flags, &filepath);
>+ if (error)
>+ return error;
>+
>+ error = vfs_fileattr_get(filepath.dentry, &fa);
>+ if (!error)
>+ error = copy_fsxattr_to_user(&fa, fsx);
>+
>+ path_put(&filepath);
>+ return error;
>+}
>+
>+SYSCALL_DEFINE4(setfsxattrat, int, dfd, const char __user *, filename,
>+ struct fsxattr __user *, fsx, unsigned int, at_flags)
>+{
>+ CLASS(fd, dir)(dfd);
>+ struct fileattr fa;
>+ struct path filepath;
>+ int error;
>+ unsigned int lookup_flags = 0;
>+
>+ if ((at_flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
>+ return -EINVAL;
>+
>+ if (at_flags & AT_SYMLINK_FOLLOW)
>+ lookup_flags |= LOOKUP_FOLLOW;
>+
>+ if (at_flags & AT_EMPTY_PATH)
>+ lookup_flags |= LOOKUP_EMPTY;
>+
>+ if (fd_empty(dir))
>+ return -EBADF;
>+
>+ if (copy_fsxattr_from_user(&fa, fsx))
>+ return -EFAULT;
>+
>+ error = user_path_at(dfd, filename, lookup_flags, &filepath);
>+ if (error)
>+ return error;
>+
>+ error = mnt_want_write(filepath.mnt);
>+ if (!error) {
>+ error = vfs_fileattr_set(file_mnt_idmap(fd_file(dir)),
>+ filepath.dentry, &fa);
>+ mnt_drop_write(filepath.mnt);
>+ }
>+
>+ path_put(&filepath);
>+ return error;
>+}
>diff --git a/fs/ioctl.c b/fs/ioctl.c
>index 638a36be31c14afc66a7fd6eb237d9545e8ad997..dc160c2ef145e4931d625f1f93c2a8ae7f87abf3 100644
>--- a/fs/ioctl.c
>+++ b/fs/ioctl.c
>@@ -558,8 +558,7 @@ int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
> }
> EXPORT_SYMBOL(copy_fsxattr_to_user);
>
>-static int copy_fsxattr_from_user(struct fileattr *fa,
>- struct fsxattr __user *ufa)
>+int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa)
> {
> struct fsxattr xfa;
>
>@@ -646,6 +645,19 @@ static int fileattr_set_prepare(struct inode *inode,
> if (fa->fsx_cowextsize == 0)
> fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
>
>+ /*
>+ * The only use case for special files is to set project ID, forbid any
>+ * other attributes
>+ */
>+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
>+ if (fa->fsx_xflags & ~FS_XFLAG_PROJINHERIT)
>+ return -EINVAL;
>+ if (!S_ISLNK(inode->i_mode) && fa->fsx_nextents)
>+ return -EINVAL;
>+ if (fa->fsx_extsize || fa->fsx_cowextsize)
>+ return -EINVAL;
>+ }
>+
> return 0;
> }
>
>diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
>index 47c05a9851d0600964b644c9c7218faacfd865f8..8598e94b530b8b280a2697eaf918dd60f573d6ee 100644
>--- a/include/linux/fileattr.h
>+++ b/include/linux/fileattr.h
>@@ -34,6 +34,7 @@ struct fileattr {
> };
>
> int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa);
>+int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa);
>
> void fileattr_fill_xflags(struct fileattr *fa, u32 xflags);
> void fileattr_fill_flags(struct fileattr *fa, u32 flags);
>diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
>index c6333204d45130eb022f6db460eea34a1f6e91db..3134d463d9af64c6e78adb37bff4b91f77b5305f 100644
>--- a/include/linux/syscalls.h
>+++ b/include/linux/syscalls.h
>@@ -371,6 +371,10 @@ asmlinkage long sys_removexattrat(int dfd, const char __user *path,
> asmlinkage long sys_lremovexattr(const char __user *path,
> const char __user *name);
> asmlinkage long sys_fremovexattr(int fd, const char __user *name);
>+asmlinkage long sys_getfsxattrat(int dfd, const char __user *filename,
>+ struct fsxattr *fsx, unsigned int at_flags);
>+asmlinkage long sys_setfsxattrat(int dfd, const char __user *filename,
>+ struct fsxattr *fsx, unsigned int at_flags);
> asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
> asmlinkage long sys_eventfd2(unsigned int count, int flags);
> asmlinkage long sys_epoll_create1(int flags);
>diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
>index 88dc393c2bca38c0fa1b3fae579f7cfe4931223c..50be2e1007bc2779120d05c6e9512a689f86779c 100644
>--- a/include/uapi/asm-generic/unistd.h
>+++ b/include/uapi/asm-generic/unistd.h
>@@ -850,8 +850,14 @@ __SYSCALL(__NR_listxattrat, sys_listxattrat)
> #define __NR_removexattrat 466
> __SYSCALL(__NR_removexattrat, sys_removexattrat)
>
>+/* fs/inode.c */
>+#define __NR_getfsxattrat 467
>+__SYSCALL(__NR_getfsxattrat, sys_getfsxattrat)
>+#define __NR_setfsxattrat 468
>+__SYSCALL(__NR_setfsxattrat, sys_setfsxattrat)
>+
> #undef __NR_syscalls
>-#define __NR_syscalls 467
>+#define __NR_syscalls 469
>
> /*
> * 32 bit systems traditionally used different
>
>---
>base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04
>change-id: 20250114-xattrat-syscall-6a1136d2db59
>
>Best regards,
Could you please give a quick description of the API – even just the prototype – and, for the future, include in the cover letter?
^ permalink raw reply
* Re: [PATCH v3] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Arnd Bergmann @ 2025-02-11 19:24 UTC (permalink / raw)
To: Andrey Albershteyn, Richard Henderson, Matt Turner, Russell King,
Catalin Marinas, Will Deacon, Geert Uytterhoeven, Michal Simek,
Thomas Bogendoerfer, James E . J . Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy, Naveen N Rao, Heiko Carstens, Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S . Miller, Andreas Larsson, Andy Lutomirski,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Chris Zankel, Max Filippov, Alexander Viro,
Christian Brauner, Jan Kara, Mickaël Salaün,
Günther Noack
Cc: linux-alpha, linux-kernel, linux-arm-kernel, linux-m68k,
linux-mips, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
sparclinux, linux-fsdevel, linux-security-module, linux-api,
Linux-Arch, linux-xfs
In-Reply-To: <20250211-xattrat-syscall-v3-1-a07d15f898b2@kernel.org>
On Tue, Feb 11, 2025, at 18:22, Andrey Albershteyn wrote:
> From: Andrey Albershteyn <aalbersh@redhat.com>
>
> Introduce getfsxattrat and setfsxattrat syscalls to manipulate inode
> extended attributes/flags. The syscalls take parent directory fd and
> path to the child together with struct fsxattr.
>
> This is an alternative to FS_IOC_FSSETXATTR ioctl with a difference
> that file don't need to be open as we can reference it with a path
> instead of fd. By having this we can manipulated inode extended
> attributes not only on regular files but also on special ones. This
> is not possible with FS_IOC_FSSETXATTR ioctl as with special files
> we can not call ioctl() directly on the filesystem inode using fd.
>
> This patch adds two new syscalls which allows userspace to get/set
> extended inode attributes on special files by using parent directory
> and a path - *at() like syscall.
>
> Also, as vfs_fileattr_set() is now will be called on special files
> too, let's forbid any other attributes except projid and nextents
> (symlink can have an extent).
>
> CC: linux-api@vger.kernel.org
> CC: linux-fsdevel@vger.kernel.org
> CC: linux-xfs@vger.kernel.org
> Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
I checked the syscall.tbl additions and the ABI to ensure that
it follows the usual guidelines and is portable across
all architectures, this looks good. Thanks for addressing
my v1 comments:
Acked-by: Arnd Bergmann <arnd@arndb.de>
Disclaimer: I have no idea if the new syscalls are a good
idea or if they are fit for the purpose, I trust the
VFS maintainers will take care of reviewing that.
^ permalink raw reply
* Re: [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Masami Hiramatsu @ 2025-02-12 4:05 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Alexei Starovoitov, Andrii Nakryiko, Jiri Olsa, Steven Rostedt,
Masami Hiramatsu, Peter Zijlstra, Andrii Nakryiko, Kees Cook,
Eyal Birger, stable, Jann Horn, LKML, linux-trace-kernel,
Linux API, X86 ML, bpf, Thomas Gleixner, Ingo Molnar,
Andy Lutomirski, Deepak Gupta, Stephen Rothwell
In-Reply-To: <20250211165940.GB9174@redhat.com>
On Tue, 11 Feb 2025 17:59:41 +0100
Oleg Nesterov <oleg@redhat.com> wrote:
> On 02/11, Alexei Starovoitov wrote:
> >
> > > > +#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
> >
> > If you respin anyway maybe use ~0UL instead?
> > In the above and in
> > uprobe_get_trampoline_vaddr(),
> > since
> >
> > unsigned long trampoline_vaddr = -1;
>
> ... or -1ul in both cases.
>
> I agree, UPROBE_NO_TRAMPOLINE_VADDR has a single user, looks
> a bit strange...
I think both this function and uprobe_get_trampoline_vaddr()
should use the same macro as a token.
(and ~0UL is a bit more comfortable for me too :) )
----
unsigned long uprobe_get_trampoline_vaddr(void)
{
struct xol_area *area;
unsigned long trampoline_vaddr = -1;
----
Thank you,
>
> Oleg.
>
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCHv2 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-12 13:51 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Oleg Nesterov, Alexei Starovoitov, Andrii Nakryiko,
Steven Rostedt, Peter Zijlstra, Andrii Nakryiko, Kees Cook,
Eyal Birger, stable, Jann Horn, LKML, linux-trace-kernel,
Linux API, X86 ML, bpf, Thomas Gleixner, Ingo Molnar,
Andy Lutomirski, Deepak Gupta, Stephen Rothwell
In-Reply-To: <20250212130509.ce1987095c6b17b26d3ee40a@kernel.org>
On Wed, Feb 12, 2025 at 01:05:09PM +0900, Masami Hiramatsu wrote:
> On Tue, 11 Feb 2025 17:59:41 +0100
> Oleg Nesterov <oleg@redhat.com> wrote:
>
> > On 02/11, Alexei Starovoitov wrote:
> > >
> > > > > +#define UPROBE_NO_TRAMPOLINE_VADDR ((unsigned long)-1)
> > >
> > > If you respin anyway maybe use ~0UL instead?
> > > In the above and in
> > > uprobe_get_trampoline_vaddr(),
> > > since
> > >
> > > unsigned long trampoline_vaddr = -1;
> >
> > ... or -1ul in both cases.
> >
> > I agree, UPROBE_NO_TRAMPOLINE_VADDR has a single user, looks
> > a bit strange...
>
> I think both this function and uprobe_get_trampoline_vaddr()
> should use the same macro as a token.
> (and ~0UL is a bit more comfortable for me too :) )
>
> ----
> unsigned long uprobe_get_trampoline_vaddr(void)
> {
> struct xol_area *area;
> unsigned long trampoline_vaddr = -1;
> ----
sounds good, I'll send new version with change below if there
are no objections
thanks,
jirka
---
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5a952c5ea66b..015b2a6bac11 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
return &insn;
}
-static unsigned long trampoline_check_ip(void)
+static unsigned long trampoline_check_ip(unsigned long tramp)
{
- unsigned long tramp = uprobe_get_trampoline_vaddr();
-
return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
}
SYSCALL_DEFINE0(uretprobe)
{
struct pt_regs *regs = task_pt_regs(current);
- unsigned long err, ip, sp, r11_cx_ax[3];
+ unsigned long err, ip, sp, r11_cx_ax[3], tramp;
+
+ /* If there's no trampoline, we are called from wrong place. */
+ tramp = uprobe_get_trampoline_vaddr();
+ if (tramp == UPROBE_NO_TRAMPOLINE_VADDR)
+ goto sigill;
- if (regs->ip != trampoline_check_ip())
+ /* Make sure the ip matches the only allowed sys_uretprobe caller. */
+ if (regs->ip != trampoline_check_ip(tramp))
goto sigill;
err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index b1df7d792fa1..a6bec560bdbc 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -39,6 +39,8 @@ struct page;
#define MAX_URETPROBE_DEPTH 64
+#define UPROBE_NO_TRAMPOLINE_VADDR (~0UL)
+
struct uprobe_consumer {
/*
* handler() can return UPROBE_HANDLER_REMOVE to signal the need to
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 2ca797cbe465..e8af2f75b094 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -2160,8 +2160,8 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
*/
unsigned long uprobe_get_trampoline_vaddr(void)
{
+ unsigned long trampoline_vaddr = UPROBE_NO_TRAMPOLINE_VADDR;
struct xol_area *area;
- unsigned long trampoline_vaddr = -1;
/* Pairs with xol_add_vma() smp_store_release() */
area = READ_ONCE(current->mm->uprobes_state.xol_area); /* ^^^ */
^ permalink raw reply related
* [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-12 22:04 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko
Cc: Kees Cook, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
Jann reported [1] possible issue when trampoline_check_ip returns
address near the bottom of the address space that is allowed to
call into the syscall if uretprobes are not set up.
Though the mmap minimum address restrictions will typically prevent
creating mappings there, let's make sure uretprobe syscall checks
for that.
[1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
Cc: Kees Cook <kees@kernel.org>
Cc: Eyal Birger <eyal.birger@gmail.com>
Cc: stable@vger.kernel.org
Fixes: ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Reported-by: Jann Horn <jannh@google.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
v3 changes:
- used ~0UL instead of -1 [Alexei]
- used UPROBE_NO_TRAMPOLINE_VADDR in uprobe_get_trampoline_vaddr [Masami]
- added unlikely [Andrii]
- I kept the review/ack tags, because I think the change is basically
the same, please scream otherwise
arch/x86/kernel/uprobes.c | 14 +++++++++-----
include/linux/uprobes.h | 2 ++
kernel/events/uprobes.c | 2 +-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5a952c5ea66b..9194695662b2 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
return &insn;
}
-static unsigned long trampoline_check_ip(void)
+static unsigned long trampoline_check_ip(unsigned long tramp)
{
- unsigned long tramp = uprobe_get_trampoline_vaddr();
-
return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
}
SYSCALL_DEFINE0(uretprobe)
{
struct pt_regs *regs = task_pt_regs(current);
- unsigned long err, ip, sp, r11_cx_ax[3];
+ unsigned long err, ip, sp, r11_cx_ax[3], tramp;
+
+ /* If there's no trampoline, we are called from wrong place. */
+ tramp = uprobe_get_trampoline_vaddr();
+ if (unlikely(tramp == UPROBE_NO_TRAMPOLINE_VADDR))
+ goto sigill;
- if (regs->ip != trampoline_check_ip())
+ /* Make sure the ip matches the only allowed sys_uretprobe caller. */
+ if (unlikely(regs->ip != trampoline_check_ip(tramp)))
goto sigill;
err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index a40efdda9052..2e46b69ff0a6 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -39,6 +39,8 @@ struct page;
#define MAX_URETPROBE_DEPTH 64
+#define UPROBE_NO_TRAMPOLINE_VADDR (~0UL)
+
struct uprobe_consumer {
/*
* handler() can return UPROBE_HANDLER_REMOVE to signal the need to
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 597b9e036e5f..c5d6307bc5bc 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -2156,8 +2156,8 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
*/
unsigned long uprobe_get_trampoline_vaddr(void)
{
+ unsigned long trampoline_vaddr = UPROBE_NO_TRAMPOLINE_VADDR;
struct xol_area *area;
- unsigned long trampoline_vaddr = -1;
/* Pairs with xol_add_vma() smp_store_release() */
area = READ_ONCE(current->mm->uprobes_state.xol_area); /* ^^^ */
--
2.48.1
^ permalink raw reply related
* Re: [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Masami Hiramatsu @ 2025-02-13 0:10 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Oleg Nesterov, Peter Zijlstra, Andrii Nakryiko,
Kees Cook, Eyal Birger, stable, Jann Horn, linux-kernel,
linux-trace-kernel, linux-api, x86, bpf, Thomas Gleixner,
Ingo Molnar, Andy Lutomirski, Deepak Gupta, Stephen Rothwell
In-Reply-To: <20250212220433.3624297-1-jolsa@kernel.org>
On Wed, 12 Feb 2025 23:04:33 +0100
Jiri Olsa <jolsa@kernel.org> wrote:
> Jann reported [1] possible issue when trampoline_check_ip returns
> address near the bottom of the address space that is allowed to
> call into the syscall if uretprobes are not set up.
>
> Though the mmap minimum address restrictions will typically prevent
> creating mappings there, let's make sure uretprobe syscall checks
> for that.
>
> [1] https://lore.kernel.org/bpf/202502081235.5A6F352985@keescook/T/#m9d416df341b8fbc11737dacbcd29f0054413cbbf
> Cc: Kees Cook <kees@kernel.org>
> Cc: Eyal Birger <eyal.birger@gmail.com>
> Cc: stable@vger.kernel.org
> Fixes: ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> Reported-by: Jann Horn <jannh@google.com>
> Reviewed-by: Oleg Nesterov <oleg@redhat.com>
> Reviewed-by: Kees Cook <kees@kernel.org>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Looks good to me.
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Thank you,
> ---
> v3 changes:
> - used ~0UL instead of -1 [Alexei]
> - used UPROBE_NO_TRAMPOLINE_VADDR in uprobe_get_trampoline_vaddr [Masami]
> - added unlikely [Andrii]
> - I kept the review/ack tags, because I think the change is basically
> the same, please scream otherwise
>
> arch/x86/kernel/uprobes.c | 14 +++++++++-----
> include/linux/uprobes.h | 2 ++
> kernel/events/uprobes.c | 2 +-
> 3 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 5a952c5ea66b..9194695662b2 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -357,19 +357,23 @@ void *arch_uprobe_trampoline(unsigned long *psize)
> return &insn;
> }
>
> -static unsigned long trampoline_check_ip(void)
> +static unsigned long trampoline_check_ip(unsigned long tramp)
> {
> - unsigned long tramp = uprobe_get_trampoline_vaddr();
> -
> return tramp + (uretprobe_syscall_check - uretprobe_trampoline_entry);
> }
>
> SYSCALL_DEFINE0(uretprobe)
> {
> struct pt_regs *regs = task_pt_regs(current);
> - unsigned long err, ip, sp, r11_cx_ax[3];
> + unsigned long err, ip, sp, r11_cx_ax[3], tramp;
> +
> + /* If there's no trampoline, we are called from wrong place. */
> + tramp = uprobe_get_trampoline_vaddr();
> + if (unlikely(tramp == UPROBE_NO_TRAMPOLINE_VADDR))
> + goto sigill;
>
> - if (regs->ip != trampoline_check_ip())
> + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> + if (unlikely(regs->ip != trampoline_check_ip(tramp)))
> goto sigill;
>
> err = copy_from_user(r11_cx_ax, (void __user *)regs->sp, sizeof(r11_cx_ax));
> diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
> index a40efdda9052..2e46b69ff0a6 100644
> --- a/include/linux/uprobes.h
> +++ b/include/linux/uprobes.h
> @@ -39,6 +39,8 @@ struct page;
>
> #define MAX_URETPROBE_DEPTH 64
>
> +#define UPROBE_NO_TRAMPOLINE_VADDR (~0UL)
> +
> struct uprobe_consumer {
> /*
> * handler() can return UPROBE_HANDLER_REMOVE to signal the need to
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index 597b9e036e5f..c5d6307bc5bc 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -2156,8 +2156,8 @@ void uprobe_copy_process(struct task_struct *t, unsigned long flags)
> */
> unsigned long uprobe_get_trampoline_vaddr(void)
> {
> + unsigned long trampoline_vaddr = UPROBE_NO_TRAMPOLINE_VADDR;
> struct xol_area *area;
> - unsigned long trampoline_vaddr = -1;
>
> /* Pairs with xol_add_vma() smp_store_release() */
> area = READ_ONCE(current->mm->uprobes_state.xol_area); /* ^^^ */
> --
> 2.48.1
>
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Andy Lutomirski @ 2025-02-13 1:37 UTC (permalink / raw)
To: Jiri Olsa
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Kees Cook, Eyal Birger, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Andy Lutomirski, Deepak Gupta,
Stephen Rothwell
In-Reply-To: <20250212220433.3624297-1-jolsa@kernel.org>
On Wed, Feb 12, 2025 at 2:04 PM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Jann reported [1] possible issue when trampoline_check_ip returns
> address near the bottom of the address space that is allowed to
> call into the syscall if uretprobes are not set up.
>
> Though the mmap minimum address restrictions will typically prevent
> creating mappings there, let's make sure uretprobe syscall checks
> for that.
It would be a layering violation, but we could perhaps do better here:
> - if (regs->ip != trampoline_check_ip())
> + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> + if (unlikely(regs->ip != trampoline_check_ip(tramp)))
> goto sigill;
Instead of SIGILL, perhaps this should do the seccomp action? So the
logic in seccomp would be (sketchily, with some real mode1 mess):
if (is_a_real_uretprobe())
skip seccomp;
where is_a_real_uretprobe() is only true if the nr and arch match
uretprobe *and* the address is right.
--Andy
^ permalink raw reply
* Re: [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Eyal Birger @ 2025-02-13 2:58 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Jiri Olsa, Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Peter Zijlstra, Andrii Nakryiko, Kees Cook, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Deepak Gupta, Stephen Rothwell
In-Reply-To: <CALCETrVFdAFVinbpPK+q7pSQHo3=JgGxZSPZVz-y7oaG=xP3fA@mail.gmail.com>
(sorry for the HTML spam)
On Wed, Feb 12, 2025 at 5:37 PM Andy Lutomirski <luto@kernel.org> wrote:
>
> On Wed, Feb 12, 2025 at 2:04 PM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Jann reported [1] possible issue when trampoline_check_ip returns
> > address near the bottom of the address space that is allowed to
> > call into the syscall if uretprobes are not set up.
> >
> > Though the mmap minimum address restrictions will typically prevent
> > creating mappings there, let's make sure uretprobe syscall checks
> > for that.
>
> It would be a layering violation, but we could perhaps do better here:
>
> > - if (regs->ip != trampoline_check_ip())
> > + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> > + if (unlikely(regs->ip != trampoline_check_ip(tramp)))
> > goto sigill;
>
> Instead of SIGILL, perhaps this should do the seccomp action? So the
> logic in seccomp would be (sketchily, with some real mode1 mess):
>
> if (is_a_real_uretprobe())
> skip seccomp;
>
> where is_a_real_uretprobe() is only true if the nr and arch match
> uretprobe *and* the address is right.
Why would it make sense to rely on CONFIG_SECCOMP for this check? seems
this check should be done regardless of seccomp.
Or maybe I missed something in the suggestion.
Eyal.
>
>
> --Andy
^ permalink raw reply
* Re: [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Jiri Olsa @ 2025-02-13 9:12 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Steven Rostedt, Masami Hiramatsu, Oleg Nesterov, Peter Zijlstra,
Andrii Nakryiko, Kees Cook, Eyal Birger, stable, Jann Horn,
linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Deepak Gupta, Stephen Rothwell
In-Reply-To: <CALCETrVFdAFVinbpPK+q7pSQHo3=JgGxZSPZVz-y7oaG=xP3fA@mail.gmail.com>
On Wed, Feb 12, 2025 at 05:37:11PM -0800, Andy Lutomirski wrote:
> On Wed, Feb 12, 2025 at 2:04 PM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Jann reported [1] possible issue when trampoline_check_ip returns
> > address near the bottom of the address space that is allowed to
> > call into the syscall if uretprobes are not set up.
> >
> > Though the mmap minimum address restrictions will typically prevent
> > creating mappings there, let's make sure uretprobe syscall checks
> > for that.
>
> It would be a layering violation, but we could perhaps do better here:
>
> > - if (regs->ip != trampoline_check_ip())
> > + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> > + if (unlikely(regs->ip != trampoline_check_ip(tramp)))
> > goto sigill;
>
> Instead of SIGILL, perhaps this should do the seccomp action? So the
> logic in seccomp would be (sketchily, with some real mode1 mess):
>
> if (is_a_real_uretprobe())
> skip seccomp;
IIUC you want to move the address check earlier to the seccomp path..
with the benefit that we would kill not allowed caller sooner?
jirka
>
> where is_a_real_uretprobe() is only true if the nr and arch match
> uretprobe *and* the address is right.
>
> --Andy
^ permalink raw reply
* Re: [PATCHv3 perf/core] uprobes: Harden uretprobe syscall trampoline check
From: Andy Lutomirski @ 2025-02-13 17:58 UTC (permalink / raw)
To: Jiri Olsa
Cc: Andy Lutomirski, Steven Rostedt, Masami Hiramatsu, Oleg Nesterov,
Peter Zijlstra, Andrii Nakryiko, Kees Cook, Eyal Birger, stable,
Jann Horn, linux-kernel, linux-trace-kernel, linux-api, x86, bpf,
Thomas Gleixner, Ingo Molnar, Deepak Gupta, Stephen Rothwell
In-Reply-To: <Z623ZcZj6Wsbnrhs@krava>
On Thu, Feb 13, 2025 at 1:16 AM Jiri Olsa <olsajiri@gmail.com> wrote:
>
> On Wed, Feb 12, 2025 at 05:37:11PM -0800, Andy Lutomirski wrote:
> > On Wed, Feb 12, 2025 at 2:04 PM Jiri Olsa <jolsa@kernel.org> wrote:
> > >
> > > Jann reported [1] possible issue when trampoline_check_ip returns
> > > address near the bottom of the address space that is allowed to
> > > call into the syscall if uretprobes are not set up.
> > >
> > > Though the mmap minimum address restrictions will typically prevent
> > > creating mappings there, let's make sure uretprobe syscall checks
> > > for that.
> >
> > It would be a layering violation, but we could perhaps do better here:
> >
> > > - if (regs->ip != trampoline_check_ip())
> > > + /* Make sure the ip matches the only allowed sys_uretprobe caller. */
> > > + if (unlikely(regs->ip != trampoline_check_ip(tramp)))
> > > goto sigill;
> >
> > Instead of SIGILL, perhaps this should do the seccomp action? So the
> > logic in seccomp would be (sketchily, with some real mode1 mess):
> >
> > if (is_a_real_uretprobe())
> > skip seccomp;
>
> IIUC you want to move the address check earlier to the seccomp path..
> with the benefit that we would kill not allowed caller sooner?
The benefit would be that seccomp users that want to do something
other than killing a process (returning an error code, getting
notified, etc) could retain that functionality without the new
automatic hole being poked for uretprobe() in cases where uprobes
aren't in use or where the calling address doesn't match the uprobe
trampoline. IOW it would reduce the scope to which we're making
seccomp behave unexpectedly.
>
> jirka
>
> >
> > where is_a_real_uretprobe() is only true if the nr and arch match
> > uretprobe *and* the address is right.
> >
> > --Andy
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox