Linux userland API discussions
 help / color / mirror / Atom feed
* Re: Crash when attaching uretprobes to processes running in Docker
From: Oleg Nesterov @ 2025-01-14 11:21 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Jiri Olsa, Aleksa Sarai, Eyal Birger, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <20250114190521.0b69a1af64cac41106101154@kernel.org>

On 01/14, Masami Hiramatsu wrote:
>
> On Tue, 14 Jan 2025 10:22:20 +0100
> Jiri Olsa <olsajiri@gmail.com> wrote:
>
> > @@ -418,6 +439,9 @@ SYSCALL_DEFINE0(uretprobe)
> >  	regs->r11 = regs->flags;
> >  	regs->cx  = regs->ip;
> >
> > +	/* zero rbx to signal trampoline that uretprobe syscall was executed */
> > +	regs->bx  = 0;
>
> Can we just return -ENOSYS as like as other syscall instead of
> using rbx as a side channel?
> We can carefully check the return address is not -ERRNO when set up
> and reserve the -ENOSYS for this use case.

Not sure I understand...

But please not that the uretprobed function can return any value
including -ENOSYS, and this is what sys_uretprobe() has to return.

Oleg.


^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Oleg Nesterov @ 2025-01-14 11:01 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Jiri Olsa, Aleksa Sarai, Eyal Birger, mhiramat, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <20250114104215.GD8362@noisy.programming.kicks-ass.net>

On 01/14, Peter Zijlstra wrote:
>
> On Tue, Jan 14, 2025 at 10:22:20AM +0100, Jiri Olsa wrote:
> >
> > hack below seems to fix the issue, it's using rbx to signal that uretprobe
> > syscall got executed, if not, trampoline does int3 and executes uretprobe
> > handler in the old way
> >
> > unfortunately now the uretprobe trampoline size crosses the xol slot limit so
> > will need to come up with some generic/arch code solution for that, code below
> > is neglecting that for now
>
> Can't you detect the filter earlier and simply not install the
> trampoline?

Did you mean detect the filter in prepare_uretprobe() ?

The probed function can install the filter before return...

Oleg.


^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Oleg Nesterov @ 2025-01-14 10:58 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Aleksa Sarai, Eyal Birger, mhiramat, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <Z4YszJfOvFEAaKjF@krava>

On 01/14, Jiri Olsa wrote:
>
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -315,14 +315,25 @@ asm (
>  	".global uretprobe_trampoline_entry\n"
>  	"uretprobe_trampoline_entry:\n"
>  	"pushq %rax\n"
> +	"pushq %rbx\n"
>  	"pushq %rcx\n"
>  	"pushq %r11\n"
> +	"movq $1, %rbx\n"
>  	"movq $" __stringify(__NR_uretprobe) ", %rax\n"
>  	"syscall\n"
>  	".global uretprobe_syscall_check\n"
>  	"uretprobe_syscall_check:\n"
> +	"or %rbx,%rbx\n"
> +	"jz uretprobe_syscall_return\n"
>  	"popq %r11\n"
>  	"popq %rcx\n"
> +	"popq %rbx\n"
> +	"popq %rax\n"
> +	"int3\n"
> +	"uretprobe_syscall_return:\n"
> +	"popq %r11\n"
> +	"popq %rcx\n"
> +	"popq %rbx\n"

But why do we need to abuse %rbx? Can't uretprobe_trampoline_entry do

	syscall

// int3_section, in case sys_uretprobe() doesn't work
	popq %r11
	popq %rcx
	popq %rax
	int3

uretprobe_syscall_return:
	popq %r11
	popq %rcx
	popq %rbx
	retq

and change sys_uretprobe() to do

	- regs->ip = ip;
	+ regs->ip = ip + sizeof(int3_section);

?

Oleg.


^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Peter Zijlstra @ 2025-01-14 10:42 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: oleg, Aleksa Sarai, Eyal Birger, mhiramat, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <Z4YszJfOvFEAaKjF@krava>

On Tue, Jan 14, 2025 at 10:22:20AM +0100, Jiri Olsa wrote:
> On Sat, Jan 11, 2025 at 07:40:15PM +0100, Jiri Olsa wrote:
> > On Sat, Jan 11, 2025 at 02:25:37AM +1100, Aleksa Sarai wrote:
> > > On 2025-01-10, Eyal Birger <eyal.birger@gmail.com> wrote:
> > > > Hi,
> > > > 
> > > > When attaching uretprobes to processes running inside docker, the attached
> > > > process is segfaulted when encountering the retprobe. The offending commit
> > > > is:
> > > > 
> > > > ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> > > > 
> > > > To my understanding, the reason is that now that uretprobe is a system call,
> > > > the default seccomp filters in docker block it as they only allow a specific
> > > > set of known syscalls.
> > > 
> > > FWIW, the default seccomp profile of Docker _should_ return -ENOSYS for
> > > uretprobe (runc has a bunch of ugly logic to try to guarantee this if
> > > Docker hasn't updated their profile to include it). Though I guess that
> > > isn't sufficient for the magic that uretprobe(2) does...
> > > 
> > > > This behavior can be reproduced by the below bash script, which works before
> > > > this commit.
> > > > 
> > > > Reported-by: Rafael Buchbinder <rafi@rbk.io>
> > 
> > hi,
> > nice ;-) thanks for the report, the problem seems to be that uretprobe syscall
> > is blocked and uretprobe trampoline does not expect that
> > 
> > I think we could add code to the uretprobe trampoline to detect this and
> > execute standard int3 as fallback to process uretprobe, I'm checking on that
> 
> hack below seems to fix the issue, it's using rbx to signal that uretprobe
> syscall got executed, if not, trampoline does int3 and executes uretprobe
> handler in the old way
> 
> unfortunately now the uretprobe trampoline size crosses the xol slot limit so
> will need to come up with some generic/arch code solution for that, code below
> is neglecting that for now

Can't you detect the filter earlier and simply not install the
trampoline?

^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Masami Hiramatsu @ 2025-01-14 10:05 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: oleg, Aleksa Sarai, Eyal Birger, mhiramat, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <Z4YszJfOvFEAaKjF@krava>

On Tue, 14 Jan 2025 10:22:20 +0100
Jiri Olsa <olsajiri@gmail.com> wrote:

> On Sat, Jan 11, 2025 at 07:40:15PM +0100, Jiri Olsa wrote:
> > On Sat, Jan 11, 2025 at 02:25:37AM +1100, Aleksa Sarai wrote:
> > > On 2025-01-10, Eyal Birger <eyal.birger@gmail.com> wrote:
> > > > Hi,
> > > > 
> > > > When attaching uretprobes to processes running inside docker, the attached
> > > > process is segfaulted when encountering the retprobe. The offending commit
> > > > is:
> > > > 
> > > > ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> > > > 
> > > > To my understanding, the reason is that now that uretprobe is a system call,
> > > > the default seccomp filters in docker block it as they only allow a specific
> > > > set of known syscalls.
> > > 
> > > FWIW, the default seccomp profile of Docker _should_ return -ENOSYS for
> > > uretprobe (runc has a bunch of ugly logic to try to guarantee this if
> > > Docker hasn't updated their profile to include it). Though I guess that
> > > isn't sufficient for the magic that uretprobe(2) does...
> > > 
> > > > This behavior can be reproduced by the below bash script, which works before
> > > > this commit.
> > > > 
> > > > Reported-by: Rafael Buchbinder <rafi@rbk.io>
> > 
> > hi,
> > nice ;-) thanks for the report, the problem seems to be that uretprobe syscall
> > is blocked and uretprobe trampoline does not expect that
> > 
> > I think we could add code to the uretprobe trampoline to detect this and
> > execute standard int3 as fallback to process uretprobe, I'm checking on that
> 
> hack below seems to fix the issue, it's using rbx to signal that uretprobe
> syscall got executed, if not, trampoline does int3 and executes uretprobe
> handler in the old way
> 
> unfortunately now the uretprobe trampoline size crosses the xol slot limit so
> will need to come up with some generic/arch code solution for that, code below
> is neglecting that for now
> 
> jirka
> 
> 
> ---
>  arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
>  include/linux/uprobes.h   |  1 +
>  kernel/events/uprobes.c   | 10 ++++++++--
>  3 files changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index 5a952c5ea66b..b54863f6fa25 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -315,14 +315,25 @@ asm (
>  	".global uretprobe_trampoline_entry\n"
>  	"uretprobe_trampoline_entry:\n"
>  	"pushq %rax\n"
> +	"pushq %rbx\n"
>  	"pushq %rcx\n"
>  	"pushq %r11\n"
> +	"movq $1, %rbx\n"
>  	"movq $" __stringify(__NR_uretprobe) ", %rax\n"
>  	"syscall\n"
>  	".global uretprobe_syscall_check\n"
>  	"uretprobe_syscall_check:\n"
> +	"or %rbx,%rbx\n"
> +	"jz uretprobe_syscall_return\n"
>  	"popq %r11\n"
>  	"popq %rcx\n"
> +	"popq %rbx\n"
> +	"popq %rax\n"
> +	"int3\n"
> +	"uretprobe_syscall_return:\n"
> +	"popq %r11\n"
> +	"popq %rcx\n"
> +	"popq %rbx\n"
>  
>  	/* The uretprobe syscall replaces stored %rax value with final
>  	 * return address, so we don't restore %rax in here and just
> @@ -338,6 +349,16 @@ extern u8 uretprobe_trampoline_entry[];
>  extern u8 uretprobe_trampoline_end[];
>  extern u8 uretprobe_syscall_check[];
>  
> +#define UINSNS_PER_PAGE                 (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES)
> +
> +bool arch_is_uretprobe_trampoline(unsigned long vaddr)
> +{
> +	unsigned long start = uprobe_get_trampoline_vaddr();
> +	unsigned long end = start + 2*UINSNS_PER_PAGE;
> +
> +	return vaddr >= start && vaddr < end;
> +}
> +
>  void *arch_uprobe_trampoline(unsigned long *psize)
>  {
>  	static uprobe_opcode_t insn = UPROBE_SWBP_INSN;
> @@ -418,6 +439,9 @@ SYSCALL_DEFINE0(uretprobe)
>  	regs->r11 = regs->flags;
>  	regs->cx  = regs->ip;
>  
> +	/* zero rbx to signal trampoline that uretprobe syscall was executed */
> +	regs->bx  = 0;

Can we just return -ENOSYS as like as other syscall instead of
using rbx as a side channel?
We can carefully check the return address is not -ERRNO when set up
and reserve the -ENOSYS for this use case.

Thank you,

> +
>  	return regs->ax;
>  
>  sigill:
> diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
> index e0a4c2082245..dbde57a68a1b 100644
> --- a/include/linux/uprobes.h
> +++ b/include/linux/uprobes.h
> @@ -213,6 +213,7 @@ extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
>  extern void uprobe_handle_trampoline(struct pt_regs *regs);
>  extern void *arch_uprobe_trampoline(unsigned long *psize);
>  extern unsigned long uprobe_get_trampoline_vaddr(void);
> +bool arch_is_uretprobe_trampoline(unsigned long vaddr);
>  #else /* !CONFIG_UPROBES */
>  struct uprobes_state {
>  };
> diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
> index fa04b14a7d72..73df64109f38 100644
> --- a/kernel/events/uprobes.c
> +++ b/kernel/events/uprobes.c
> @@ -1703,6 +1703,11 @@ void * __weak arch_uprobe_trampoline(unsigned long *psize)
>  	return &insn;
>  }
>  
> +bool __weak arch_is_uretprobe_trampoline(unsigned long vaddr)
> +{
> +	return vaddr == uprobe_get_trampoline_vaddr();
> +}
> +
>  static struct xol_area *__create_xol_area(unsigned long vaddr)
>  {
>  	struct mm_struct *mm = current->mm;
> @@ -1725,8 +1730,9 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
>  
>  	area->vaddr = vaddr;
>  	init_waitqueue_head(&area->wq);
> -	/* Reserve the 1st slot for get_trampoline_vaddr() */
> +	/* Reserve the first two slots for get_trampoline_vaddr() */
>  	set_bit(0, area->bitmap);
> +	set_bit(1, area->bitmap);
>  	insns = arch_uprobe_trampoline(&insns_size);
>  	arch_uprobe_copy_ixol(area->page, 0, insns, insns_size);
>  
> @@ -2536,7 +2542,7 @@ static void handle_swbp(struct pt_regs *regs)
>  	int is_swbp;
>  
>  	bp_vaddr = uprobe_get_swbp_addr(regs);
> -	if (bp_vaddr == uprobe_get_trampoline_vaddr())
> +	if (arch_is_uretprobe_trampoline(bp_vaddr))
>  		return uprobe_handle_trampoline(regs);
>  
>  	rcu_read_lock_trace();
> -- 
> 2.47.1
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Jiri Olsa @ 2025-01-14  9:22 UTC (permalink / raw)
  To: Jiri Olsa, oleg
  Cc: Aleksa Sarai, Eyal Birger, mhiramat, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <Z4K7D10rjuVeRCKq@krava>

On Sat, Jan 11, 2025 at 07:40:15PM +0100, Jiri Olsa wrote:
> On Sat, Jan 11, 2025 at 02:25:37AM +1100, Aleksa Sarai wrote:
> > On 2025-01-10, Eyal Birger <eyal.birger@gmail.com> wrote:
> > > Hi,
> > > 
> > > When attaching uretprobes to processes running inside docker, the attached
> > > process is segfaulted when encountering the retprobe. The offending commit
> > > is:
> > > 
> > > ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> > > 
> > > To my understanding, the reason is that now that uretprobe is a system call,
> > > the default seccomp filters in docker block it as they only allow a specific
> > > set of known syscalls.
> > 
> > FWIW, the default seccomp profile of Docker _should_ return -ENOSYS for
> > uretprobe (runc has a bunch of ugly logic to try to guarantee this if
> > Docker hasn't updated their profile to include it). Though I guess that
> > isn't sufficient for the magic that uretprobe(2) does...
> > 
> > > This behavior can be reproduced by the below bash script, which works before
> > > this commit.
> > > 
> > > Reported-by: Rafael Buchbinder <rafi@rbk.io>
> 
> hi,
> nice ;-) thanks for the report, the problem seems to be that uretprobe syscall
> is blocked and uretprobe trampoline does not expect that
> 
> I think we could add code to the uretprobe trampoline to detect this and
> execute standard int3 as fallback to process uretprobe, I'm checking on that

hack below seems to fix the issue, it's using rbx to signal that uretprobe
syscall got executed, if not, trampoline does int3 and executes uretprobe
handler in the old way

unfortunately now the uretprobe trampoline size crosses the xol slot limit so
will need to come up with some generic/arch code solution for that, code below
is neglecting that for now

jirka


---
 arch/x86/kernel/uprobes.c | 24 ++++++++++++++++++++++++
 include/linux/uprobes.h   |  1 +
 kernel/events/uprobes.c   | 10 ++++++++--
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5a952c5ea66b..b54863f6fa25 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -315,14 +315,25 @@ asm (
 	".global uretprobe_trampoline_entry\n"
 	"uretprobe_trampoline_entry:\n"
 	"pushq %rax\n"
+	"pushq %rbx\n"
 	"pushq %rcx\n"
 	"pushq %r11\n"
+	"movq $1, %rbx\n"
 	"movq $" __stringify(__NR_uretprobe) ", %rax\n"
 	"syscall\n"
 	".global uretprobe_syscall_check\n"
 	"uretprobe_syscall_check:\n"
+	"or %rbx,%rbx\n"
+	"jz uretprobe_syscall_return\n"
 	"popq %r11\n"
 	"popq %rcx\n"
+	"popq %rbx\n"
+	"popq %rax\n"
+	"int3\n"
+	"uretprobe_syscall_return:\n"
+	"popq %r11\n"
+	"popq %rcx\n"
+	"popq %rbx\n"
 
 	/* The uretprobe syscall replaces stored %rax value with final
 	 * return address, so we don't restore %rax in here and just
@@ -338,6 +349,16 @@ extern u8 uretprobe_trampoline_entry[];
 extern u8 uretprobe_trampoline_end[];
 extern u8 uretprobe_syscall_check[];
 
+#define UINSNS_PER_PAGE                 (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES)
+
+bool arch_is_uretprobe_trampoline(unsigned long vaddr)
+{
+	unsigned long start = uprobe_get_trampoline_vaddr();
+	unsigned long end = start + 2*UINSNS_PER_PAGE;
+
+	return vaddr >= start && vaddr < end;
+}
+
 void *arch_uprobe_trampoline(unsigned long *psize)
 {
 	static uprobe_opcode_t insn = UPROBE_SWBP_INSN;
@@ -418,6 +439,9 @@ SYSCALL_DEFINE0(uretprobe)
 	regs->r11 = regs->flags;
 	regs->cx  = regs->ip;
 
+	/* zero rbx to signal trampoline that uretprobe syscall was executed */
+	regs->bx  = 0;
+
 	return regs->ax;
 
 sigill:
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
index e0a4c2082245..dbde57a68a1b 100644
--- a/include/linux/uprobes.h
+++ b/include/linux/uprobes.h
@@ -213,6 +213,7 @@ extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
 extern void uprobe_handle_trampoline(struct pt_regs *regs);
 extern void *arch_uprobe_trampoline(unsigned long *psize);
 extern unsigned long uprobe_get_trampoline_vaddr(void);
+bool arch_is_uretprobe_trampoline(unsigned long vaddr);
 #else /* !CONFIG_UPROBES */
 struct uprobes_state {
 };
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index fa04b14a7d72..73df64109f38 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -1703,6 +1703,11 @@ void * __weak arch_uprobe_trampoline(unsigned long *psize)
 	return &insn;
 }
 
+bool __weak arch_is_uretprobe_trampoline(unsigned long vaddr)
+{
+	return vaddr == uprobe_get_trampoline_vaddr();
+}
+
 static struct xol_area *__create_xol_area(unsigned long vaddr)
 {
 	struct mm_struct *mm = current->mm;
@@ -1725,8 +1730,9 @@ static struct xol_area *__create_xol_area(unsigned long vaddr)
 
 	area->vaddr = vaddr;
 	init_waitqueue_head(&area->wq);
-	/* Reserve the 1st slot for get_trampoline_vaddr() */
+	/* Reserve the first two slots for get_trampoline_vaddr() */
 	set_bit(0, area->bitmap);
+	set_bit(1, area->bitmap);
 	insns = arch_uprobe_trampoline(&insns_size);
 	arch_uprobe_copy_ixol(area->page, 0, insns, insns_size);
 
@@ -2536,7 +2542,7 @@ static void handle_swbp(struct pt_regs *regs)
 	int is_swbp;
 
 	bp_vaddr = uprobe_get_swbp_addr(regs);
-	if (bp_vaddr == uprobe_get_trampoline_vaddr())
+	if (arch_is_uretprobe_trampoline(bp_vaddr))
 		return uprobe_handle_trampoline(regs);
 
 	rcu_read_lock_trace();
-- 
2.47.1


^ permalink raw reply related

* [PATCH v2 6/7] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: Dmitry V. Levin @ 2025-01-13 17:12 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, linux-kernel, linux-api
In-Reply-To: <20250113170925.GA392@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.

Current implementation supports changing only those bits of system call
information that are used by strace, 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 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>
---
 include/linux/ptrace.h      |  3 ++
 include/uapi/linux/ptrace.h |  4 +-
 kernel/ptrace.c             | 95 +++++++++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 90507d4afcd6..c8dbf1e498bf 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -17,6 +17,9 @@ struct syscall_info {
 	struct seccomp_data	data;
 };
 
+/* sizeof() the first published struct ptrace_syscall_info */
+#define PTRACE_SYSCALL_INFO_SIZE_VER0	84
+
 extern int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
 			    void *buf, int len, unsigned int gup_flags);
 
diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h
index 72c038fc71d0..ca75b3ab5d22 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;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 22e7d74cf4cd..41d37cb8f74a 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1016,6 +1016,97 @@ 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 unsigned long
+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;
+
+	if (nr != info->entry.nr)
+		return -ERANGE;
+
+	for (i = 0; i < ARRAY_SIZE(args); i++) {
+		args[i] = info->entry.args[i];
+		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 unsigned long
+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 unsigned long
+ptrace_set_syscall_info_exit(struct task_struct *child, struct pt_regs *regs,
+			     struct ptrace_syscall_info *info)
+{
+	if (info->exit.is_error)
+		syscall_set_return_value(child, regs, info->exit.rval, 0);
+	else
+		syscall_set_return_value(child, regs, 0, info->exit.rval);
+
+	return 0;
+}
+
+static int
+ptrace_set_syscall_info(struct task_struct *child, unsigned long user_size,
+			void __user *datavp)
+{
+	struct pt_regs *regs = task_pt_regs(child);
+	struct ptrace_syscall_info info;
+	int error;
+
+	BUILD_BUG_ON(sizeof(struct ptrace_syscall_info) < PTRACE_SYSCALL_INFO_SIZE_VER0);
+
+	if (user_size < PTRACE_SYSCALL_INFO_SIZE_VER0 || user_size > PAGE_SIZE)
+		return -EINVAL;
+
+	error = copy_struct_from_user(&info, sizeof(info), datavp, user_size);
+	if (error)
+		return error;
+
+	/* Reserved for future use. */
+	if (info.flags || info.reserved)
+		return -EINVAL;
+
+	/* Changing the type of the system call stop is not supported. */
+	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. */
+		return -EINVAL;
+	}
+}
 #endif /* CONFIG_HAVE_ARCH_TRACEHOOK */
 
 int ptrace_request(struct task_struct *child, long request,
@@ -1234,6 +1325,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

* [PATCH v2 0/7] ptrace: introduce PTRACE_SET_SYSCALL_INFO API
From: Dmitry V. Levin @ 2025-01-13 17:09 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, 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,
	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.

Current implementation supports changing only those bits of system call
information that are used by strace, 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 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:
    v2:
    * Add patch to fix syscall_set_return_value() on powerpc
    * Add patch to fix mips_get_syscall_arg() on mips
    * Merge two patches adding syscall_set_arguments() implementations
      from different sources into a single patch
    * 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):
  powerpc: properly negate error in syscall_set_return_value()
  mips: fix mips_get_syscall_arg() for O32 and N32
  syscall.h: add syscall_set_arguments() and syscall_set_return_value()
  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               |  72 ++-
 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            |  26 +-
 arch/riscv/include/asm/syscall.h              |  16 +
 arch/s390/include/asm/syscall.h               |  24 +
 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/linux/ptrace.h                        |   3 +
 include/uapi/linux/ptrace.h                   |   4 +-
 kernel/ptrace.c                               | 153 +++++-
 tools/testing/selftests/ptrace/Makefile       |   2 +-
 .../selftests/ptrace/set_syscall_info.c       | 441 ++++++++++++++++++
 26 files changed, 1052 insertions(+), 47 deletions(-)
 create mode 100644 tools/testing/selftests/ptrace/set_syscall_info.c

-- 
ldv

^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Andrey Albershteyn @ 2025-01-13 15:31 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-api, monstr, mpe, npiggin, christophe.leroy,
	naveen, maddy, luto, tglx, mingo, bp, dave.hansen, x86, hpa,
	chris, jcmvbkbc, viro, brauner, arnd, linux-alpha, linux-kernel,
	linux-m68k, linux-parisc, linuxppc-dev, linux-s390, linux-sh,
	sparclinux, linux-security-module, linux-arch
In-Reply-To: <doha6zamxgmqapwx4r6ehzbatzar4dcep33zehunonqforjzf5@lxpidn37tdjh>

On 2025-01-13 12:19:36, Jan Kara wrote:
> On Thu 09-01-25 18:45:40, 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. By having this we can manipulated
> > inode extended attributes not only on normal files but also on
> > special ones. This is not possible with FS_IOC_FSSETXATTR ioctl as
> > opening special files returns VFS special inode instead of
> > underlying filesystem one.
> > 
> > This patch adds two new syscalls which allows userspace to set
> > extended inode attributes on special files by using parent directory
> > to open FS inode.
> > 
> > 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
> > Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
> 
> Couple of comments below:
> 
> > @@ -2953,3 +2956,105 @@ 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 *, fsx, int, at_flags)
> 				       ^^^ at_flags should be probably
> unsigned - at least they seem to be for other syscalls.

sure

> 
> > +{
> > +	struct fd dir;
> > +	struct fileattr fa;
> > +	struct path filepath;
> > +	struct inode *inode;
> > +	int error;
> > +
> > +	if (at_flags)
> > +		return -EINVAL;
> 
> Shouldn't we support basic path resolve flags like AT_SYMLINK_NOFOLLOW or
> AT_EMPTY_PATH? I didn't put too much thought to this but intuitively I'd say
> we should follow what path_setxattrat() does.

Hmm, yeah, you are right these two can be passed. I thought about
setting AT_SYMLINK_NOFOLLOW by default (which is also missing here),
but adding allowing passing these seems to be fine.

> 
> > +
> > +	if (!capable(CAP_FOWNER))
> > +		return -EPERM;
> 
> Why? Firstly this does not handle user namespaces at all, secondly it
> doesn't match the check done during ioctl, and thirdly vfs_fileattr_get()
> should do all the needed checks?

Sorry, miss-understood how this works, I will remove this from both
get/set. get*() doesn't need it and set*() checks capabilities in
vfs_fileattr_set(). Thanks!

> 
> > +
> > +	dir = fdget(dfd);
> > +	if (!fd_file(dir))
> > +		return -EBADF;
> > +
> > +	if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
> > +		error = -EBADF;
> > +		goto out;
> > +	}
> > +
> > +	error = user_path_at(dfd, filename, at_flags, &filepath);
> > +	if (error)
> > +		goto out;
> 
> I guess this is OK for now but allowing full flexibility of the "_at"
> syscall (e.g. like setxattrat() does) would be preferred. Mostly so that
> userspace programmer doesn't have to read manpage in detail and think
> whether the particular combination of path arguments is supported by a
> particular syscall. Admittedly VFS could make this a bit simpler. Currently
> the boilerplate code that's needed in path_setxattrat() &
> filename_setxattr() / file_setxattr() is offputting.
> 
> > +
> > +	inode = filepath.dentry->d_inode;
> > +	if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
> > +		error = -EBADF;
> > +		goto out_path;
> > +	}
> 
> What's the motivation for this check?

This was one of the comments on the ioctl() patch, that it doesn't
make much sense to allow ioctl() to be called over different
filesystems. But for syscall this is probably make less sense to
restrict it like that. I will drop it.

> 
> > +
> > +	error = vfs_fileattr_get(filepath.dentry, &fa);
> > +	if (error)
> > +		goto out_path;
> > +
> > +	if (copy_fsxattr_to_user(&fa, fsx))
> > +		error = -EFAULT;
> > +
> > +out_path:
> > +	path_put(&filepath);
> > +out:
> > +	fdput(dir);
> > +	return error;
> > +}
> > +
> > +SYSCALL_DEFINE4(setfsxattrat, int, dfd, const char __user *, filename,
> > +		struct fsxattr *, fsx, int, at_flags)
> > +{
> 
> Same comments as for getfsxattrat() apply here as well.
> 
> > -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;
> >  
> > @@ -574,6 +573,7 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
> >  
> >  	return 0;
> >  }
> > +EXPORT_SYMBOL(copy_fsxattr_from_user);
> 
> I guess no need to export this function? The code you call it from cannot
> be compiled as a module.

Yes, that's true, I added this because copy_fsxattr_to_user() also
is exported (same as many other functions). I will drop this.

-- 
- Andrey


^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Jan Kara @ 2025-01-13 11:19 UTC (permalink / raw)
  To: Andrey Albershteyn
  Cc: linux-fsdevel, linux-api, monstr, mpe, npiggin, christophe.leroy,
	naveen, maddy, luto, tglx, mingo, bp, dave.hansen, x86, hpa,
	chris, jcmvbkbc, viro, brauner, jack, arnd, linux-alpha,
	linux-kernel, linux-m68k, linux-parisc, linuxppc-dev, linux-s390,
	linux-sh, sparclinux, linux-security-module, linux-arch
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

On Thu 09-01-25 18:45:40, 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. By having this we can manipulated
> inode extended attributes not only on normal files but also on
> special ones. This is not possible with FS_IOC_FSSETXATTR ioctl as
> opening special files returns VFS special inode instead of
> underlying filesystem one.
> 
> This patch adds two new syscalls which allows userspace to set
> extended inode attributes on special files by using parent directory
> to open FS inode.
> 
> 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
> Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>

Couple of comments below:

> @@ -2953,3 +2956,105 @@ 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 *, fsx, int, at_flags)
				       ^^^ at_flags should be probably
unsigned - at least they seem to be for other syscalls.

> +{
> +	struct fd dir;
> +	struct fileattr fa;
> +	struct path filepath;
> +	struct inode *inode;
> +	int error;
> +
> +	if (at_flags)
> +		return -EINVAL;

Shouldn't we support basic path resolve flags like AT_SYMLINK_NOFOLLOW or
AT_EMPTY_PATH? I didn't put too much thought to this but intuitively I'd say
we should follow what path_setxattrat() does.

> +
> +	if (!capable(CAP_FOWNER))
> +		return -EPERM;

Why? Firstly this does not handle user namespaces at all, secondly it
doesn't match the check done during ioctl, and thirdly vfs_fileattr_get()
should do all the needed checks?

> +
> +	dir = fdget(dfd);
> +	if (!fd_file(dir))
> +		return -EBADF;
> +
> +	if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
> +		error = -EBADF;
> +		goto out;
> +	}
> +
> +	error = user_path_at(dfd, filename, at_flags, &filepath);
> +	if (error)
> +		goto out;

I guess this is OK for now but allowing full flexibility of the "_at"
syscall (e.g. like setxattrat() does) would be preferred. Mostly so that
userspace programmer doesn't have to read manpage in detail and think
whether the particular combination of path arguments is supported by a
particular syscall. Admittedly VFS could make this a bit simpler. Currently
the boilerplate code that's needed in path_setxattrat() &
filename_setxattr() / file_setxattr() is offputting.

> +
> +	inode = filepath.dentry->d_inode;
> +	if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
> +		error = -EBADF;
> +		goto out_path;
> +	}

What's the motivation for this check?

> +
> +	error = vfs_fileattr_get(filepath.dentry, &fa);
> +	if (error)
> +		goto out_path;
> +
> +	if (copy_fsxattr_to_user(&fa, fsx))
> +		error = -EFAULT;
> +
> +out_path:
> +	path_put(&filepath);
> +out:
> +	fdput(dir);
> +	return error;
> +}
> +
> +SYSCALL_DEFINE4(setfsxattrat, int, dfd, const char __user *, filename,
> +		struct fsxattr *, fsx, int, at_flags)
> +{

Same comments as for getfsxattrat() apply here as well.

> -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;
>  
> @@ -574,6 +573,7 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL(copy_fsxattr_from_user);

I guess no need to export this function? The code you call it from cannot
be compiled as a module.

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: kernel test robot @ 2025-01-13  3:25 UTC (permalink / raw)
  To: Andrey Albershteyn, linux-fsdevel
  Cc: oe-kbuild-all, Andrey Albershteyn, linux-api, monstr, mpe,
	npiggin, christophe.leroy, naveen, maddy, luto, tglx, mingo, bp,
	dave.hansen, x86, hpa, chris, jcmvbkbc, viro, brauner, jack, arnd,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

Hi Andrey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on brauner-vfs/vfs.all]
[also build test WARNING on geert-m68k/for-next powerpc/next powerpc/fixes s390/features linus/master v6.13-rc6 next-20250110]
[cannot apply to geert-m68k/for-linus deller-parisc/for-next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master tip/x86/asm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrey-Albershteyn/fs-introduce-getfsxattrat-and-setfsxattrat-syscalls/20250110-014739
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20250109174540.893098-1-aalbersh%40kernel.org
patch subject: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
config: m68k-randconfig-r122-20250111 (https://download.01.org/0day-ci/archive/20250113/202501131033.KKMmoHBV-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 14.2.0
reproduce: (https://download.01.org/0day-ci/archive/20250113/202501131033.KKMmoHBV-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501131033.KKMmoHBV-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   fs/inode.c:957:24: sparse: sparse: context imbalance in 'inode_lru_isolate' - wrong count at exit
   fs/inode.c:1058:9: sparse: sparse: context imbalance in 'find_inode' - different lock contexts for basic block
   fs/inode.c:1099:9: sparse: sparse: context imbalance in 'find_inode_fast' - different lock contexts for basic block
   fs/inode.c:1829:5: sparse: sparse: context imbalance in 'insert_inode_locked' - wrong count at exit
   fs/inode.c:1947:20: sparse: sparse: context imbalance in 'iput_final' - unexpected unlock
   fs/inode.c:1961:6: sparse: sparse: context imbalance in 'iput' - wrong count at exit
   fs/inode.c:2494:17: sparse: sparse: context imbalance in '__wait_on_freeing_inode' - unexpected unlock
>> fs/inode.c:2998:39: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:2998:39: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:2998:39: sparse:     got struct fsxattr *fsx
   fs/inode.c:3032:41: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:3032:41: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:3032:41: sparse:     got struct fsxattr *fsx

vim +2998 fs/inode.c

  2959	
  2960	SYSCALL_DEFINE4(getfsxattrat, int, dfd, const char __user *, filename,
  2961			struct fsxattr *, fsx, int, at_flags)
  2962	{
  2963		struct fd dir;
  2964		struct fileattr fa;
  2965		struct path filepath;
  2966		struct inode *inode;
  2967		int error;
  2968	
  2969		if (at_flags)
  2970			return -EINVAL;
  2971	
  2972		if (!capable(CAP_FOWNER))
  2973			return -EPERM;
  2974	
  2975		dir = fdget(dfd);
  2976		if (!fd_file(dir))
  2977			return -EBADF;
  2978	
  2979		if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
  2980			error = -EBADF;
  2981			goto out;
  2982		}
  2983	
  2984		error = user_path_at(dfd, filename, at_flags, &filepath);
  2985		if (error)
  2986			goto out;
  2987	
  2988		inode = filepath.dentry->d_inode;
  2989		if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
  2990			error = -EBADF;
  2991			goto out_path;
  2992		}
  2993	
  2994		error = vfs_fileattr_get(filepath.dentry, &fa);
  2995		if (error)
  2996			goto out_path;
  2997	
> 2998		if (copy_fsxattr_to_user(&fa, fsx))
  2999			error = -EFAULT;
  3000	
  3001	out_path:
  3002		path_put(&filepath);
  3003	out:
  3004		fdput(dir);
  3005		return error;
  3006	}
  3007	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: kernel test robot @ 2025-01-11 21:05 UTC (permalink / raw)
  To: Andrey Albershteyn, linux-fsdevel
  Cc: oe-kbuild-all, Andrey Albershteyn, linux-api, monstr, mpe,
	npiggin, christophe.leroy, naveen, maddy, luto, tglx, mingo, bp,
	dave.hansen, x86, hpa, chris, jcmvbkbc, viro, brauner, jack, arnd,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

Hi Andrey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on brauner-vfs/vfs.all]
[also build test WARNING on geert-m68k/for-next powerpc/next powerpc/fixes s390/features linus/master v6.13-rc6 next-20250110]
[cannot apply to geert-m68k/for-linus deller-parisc/for-next jcmvbkbc-xtensa/xtensa-for-next tip/x86/asm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrey-Albershteyn/fs-introduce-getfsxattrat-and-setfsxattrat-syscalls/20250110-014739
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20250109174540.893098-1-aalbersh%40kernel.org
patch subject: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
config: riscv-randconfig-002-20250111 (https://download.01.org/0day-ci/archive/20250112/202501120410.3ZwwYXqY-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250112/202501120410.3ZwwYXqY-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501120410.3ZwwYXqY-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> <stdin>:1615:2: warning: #warning syscall getfsxattrat not implemented [-Wcpp]
>> <stdin>:1618:2: warning: #warning syscall setfsxattrat not implemented [-Wcpp]
--
>> <stdin>:1615:2: warning: #warning syscall getfsxattrat not implemented [-Wcpp]
>> <stdin>:1618:2: warning: #warning syscall setfsxattrat not implemented [-Wcpp]
--
>> <stdin>:1615:2: warning: #warning syscall getfsxattrat not implemented [-Wcpp]
>> <stdin>:1618:2: warning: #warning syscall setfsxattrat not implemented [-Wcpp]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Jiri Olsa @ 2025-01-11 18:40 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Eyal Birger, olsajiri, mhiramat, oleg, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <20250110.152323-sassy.torch.lavish.rent-vKX3ul5B3qyi@cyphar.com>

On Sat, Jan 11, 2025 at 02:25:37AM +1100, Aleksa Sarai wrote:
> On 2025-01-10, Eyal Birger <eyal.birger@gmail.com> wrote:
> > Hi,
> > 
> > When attaching uretprobes to processes running inside docker, the attached
> > process is segfaulted when encountering the retprobe. The offending commit
> > is:
> > 
> > ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> > 
> > To my understanding, the reason is that now that uretprobe is a system call,
> > the default seccomp filters in docker block it as they only allow a specific
> > set of known syscalls.
> 
> FWIW, the default seccomp profile of Docker _should_ return -ENOSYS for
> uretprobe (runc has a bunch of ugly logic to try to guarantee this if
> Docker hasn't updated their profile to include it). Though I guess that
> isn't sufficient for the magic that uretprobe(2) does...
> 
> > This behavior can be reproduced by the below bash script, which works before
> > this commit.
> > 
> > Reported-by: Rafael Buchbinder <rafi@rbk.io>

hi,
nice ;-) thanks for the report, the problem seems to be that uretprobe syscall
is blocked and uretprobe trampoline does not expect that

I think we could add code to the uretprobe trampoline to detect this and
execute standard int3 as fallback to process uretprobe, I'm checking on that

jirka


> > 
> > Eyal.
> > 
> > --- CODE ---
> > #!/bin/bash
> > 
> > cat > /tmp/x.c << EOF
> > #include <stdio.h>
> > #include <seccomp.h>
> > 
> > char *syscalls[] = {
> > "write",
> > "exit_group",
> > };
> > 
> > __attribute__((noinline)) int probed(void)
> > {
> > printf("Probed\n");
> > return 1;
> > }
> > 
> > void apply_seccomp_filter(char **syscalls, int num_syscalls)
> > {
> > scmp_filter_ctx ctx;
> > 
> > ctx = seccomp_init(SCMP_ACT_ERRNO(1));
> > for (int i = 0; i < num_syscalls; i++) {
> > seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
> > seccomp_syscall_resolve_name(syscalls[i]), 0);
> > }
> > seccomp_load(ctx);
> > seccomp_release(ctx);
> > }
> > 
> > int main(int argc, char *argv[])
> > {
> > int num_syscalls = sizeof(syscalls) / sizeof(syscalls[0]);
> > 
> > apply_seccomp_filter(syscalls, num_syscalls);
> > 
> > probed();
> > 
> > return 0;
> > }
> > EOF
> > 
> > cat > /tmp/trace.bt << EOF
> > uretprobe:/tmp/x:probed
> > {
> >     printf("ret=%d\n", retval);
> > }
> > EOF
> > 
> > gcc -o /tmp/x /tmp/x.c -lseccomp
> > 
> > /usr/bin/bpftrace /tmp/trace.bt &
> > 
> > sleep 5 # wait for uretprobe attach
> > /tmp/x
> > 
> > pkill bpftrace
> > 
> > rm /tmp/x /tmp/x.c /tmp/trace.bt
> > 
> 
> -- 
> Aleksa Sarai
> Senior Software Engineer (Containers)
> SUSE Linux GmbH
> https://www.cyphar.com/



^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: kernel test robot @ 2025-01-11 15:47 UTC (permalink / raw)
  To: Andrey Albershteyn, linux-fsdevel
  Cc: oe-kbuild-all, Andrey Albershteyn, linux-api, monstr, mpe,
	npiggin, christophe.leroy, naveen, maddy, luto, tglx, mingo, bp,
	dave.hansen, x86, hpa, chris, jcmvbkbc, viro, brauner, jack, arnd,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

Hi Andrey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on brauner-vfs/vfs.all]
[also build test WARNING on geert-m68k/for-next powerpc/next powerpc/fixes s390/features linus/master v6.13-rc6 next-20250110]
[cannot apply to geert-m68k/for-linus deller-parisc/for-next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master tip/x86/asm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrey-Albershteyn/fs-introduce-getfsxattrat-and-setfsxattrat-syscalls/20250110-014739
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20250109174540.893098-1-aalbersh%40kernel.org
patch subject: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
config: s390-randconfig-r133-20250111 (https://download.01.org/0day-ci/archive/20250111/202501112305.EPQr5jnx-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 14.2.0
reproduce: (https://download.01.org/0day-ci/archive/20250111/202501112305.EPQr5jnx-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501112305.EPQr5jnx-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   fs/inode.c:605:28: sparse: sparse: context imbalance in 'inode_wait_for_lru_isolating' - unexpected unlock
   fs/inode.c: note: in included file (through include/linux/wait.h, include/linux/wait_bit.h, include/linux/fs.h):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   fs/inode.c:999:28: sparse: sparse: context imbalance in 'inode_lru_isolate' - unexpected unlock
   fs/inode.c:1058:9: sparse: sparse: context imbalance in 'find_inode' - different lock contexts for basic block
   fs/inode.c:1099:9: sparse: sparse: context imbalance in 'find_inode_fast' - different lock contexts for basic block
   fs/inode.c:1829:5: sparse: sparse: context imbalance in 'insert_inode_locked' - wrong count at exit
   fs/inode.c:1947:20: sparse: sparse: context imbalance in 'iput_final' - unexpected unlock
   fs/inode.c:1961:6: sparse: sparse: context imbalance in 'iput' - wrong count at exit
   fs/inode.c:2494:17: sparse: sparse: context imbalance in '__wait_on_freeing_inode' - unexpected unlock
>> fs/inode.c:2960:1: sparse: sparse: Using plain integer as NULL pointer
>> fs/inode.c:2960:1: sparse: sparse: Using plain integer as NULL pointer
>> fs/inode.c:2960:1: sparse: sparse: Using plain integer as NULL pointer
>> fs/inode.c:2960:1: sparse: sparse: Using plain integer as NULL pointer
   fs/inode.c:2998:39: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:2998:39: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:2998:39: sparse:     got struct fsxattr *fsx
   fs/inode.c:2998:39: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:2998:39: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:2998:39: sparse:     got struct fsxattr *fsx
   fs/inode.c:3008:1: sparse: sparse: Using plain integer as NULL pointer
   fs/inode.c:3008:1: sparse: sparse: Using plain integer as NULL pointer
   fs/inode.c:3008:1: sparse: sparse: Using plain integer as NULL pointer
   fs/inode.c:3008:1: sparse: sparse: Using plain integer as NULL pointer
   fs/inode.c:3032:41: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:3032:41: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:3032:41: sparse:     got struct fsxattr *fsx
   fs/inode.c:3032:41: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct fsxattr [noderef] __user *ufa @@     got struct fsxattr *fsx @@
   fs/inode.c:3032:41: sparse:     expected struct fsxattr [noderef] __user *ufa
   fs/inode.c:3032:41: sparse:     got struct fsxattr *fsx

vim +2960 fs/inode.c

  2959	
> 2960	SYSCALL_DEFINE4(getfsxattrat, int, dfd, const char __user *, filename,
  2961			struct fsxattr *, fsx, int, at_flags)
  2962	{
  2963		struct fd dir;
  2964		struct fileattr fa;
  2965		struct path filepath;
  2966		struct inode *inode;
  2967		int error;
  2968	
  2969		if (at_flags)
  2970			return -EINVAL;
  2971	
  2972		if (!capable(CAP_FOWNER))
  2973			return -EPERM;
  2974	
  2975		dir = fdget(dfd);
  2976		if (!fd_file(dir))
  2977			return -EBADF;
  2978	
  2979		if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
  2980			error = -EBADF;
  2981			goto out;
  2982		}
  2983	
  2984		error = user_path_at(dfd, filename, at_flags, &filepath);
  2985		if (error)
  2986			goto out;
  2987	
  2988		inode = filepath.dentry->d_inode;
  2989		if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
  2990			error = -EBADF;
  2991			goto out_path;
  2992		}
  2993	
  2994		error = vfs_fileattr_get(filepath.dentry, &fa);
  2995		if (error)
  2996			goto out_path;
  2997	
  2998		if (copy_fsxattr_to_user(&fa, fsx))
  2999			error = -EFAULT;
  3000	
  3001	out_path:
  3002		path_put(&filepath);
  3003	out:
  3004		fdput(dir);
  3005		return error;
  3006	}
  3007	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: kernel test robot @ 2025-01-11 13:07 UTC (permalink / raw)
  To: Andrey Albershteyn, linux-fsdevel
  Cc: llvm, oe-kbuild-all, Andrey Albershteyn, linux-api, monstr, mpe,
	npiggin, christophe.leroy, naveen, maddy, luto, tglx, mingo, bp,
	dave.hansen, x86, hpa, chris, jcmvbkbc, viro, brauner, jack, arnd,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

Hi Andrey,

kernel test robot noticed the following build warnings:

[auto build test WARNING on brauner-vfs/vfs.all]
[also build test WARNING on geert-m68k/for-next powerpc/next powerpc/fixes s390/features linus/master v6.13-rc6 next-20250110]
[cannot apply to geert-m68k/for-linus deller-parisc/for-next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master tip/x86/asm]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Andrey-Albershteyn/fs-introduce-getfsxattrat-and-setfsxattrat-syscalls/20250110-014739
base:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git vfs.all
patch link:    https://lore.kernel.org/r/20250109174540.893098-1-aalbersh%40kernel.org
patch subject: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
config: arm-allnoconfig (https://download.01.org/0day-ci/archive/20250111/202501112052.ZJEvfjhd-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250111/202501112052.ZJEvfjhd-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501112052.ZJEvfjhd-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> <stdin>:1615:2: warning: syscall getfsxattrat not implemented [-W#warnings]
    1615 | #warning syscall getfsxattrat not implemented
         |  ^
>> <stdin>:1618:2: warning: syscall setfsxattrat not implemented [-W#warnings]
    1618 | #warning syscall setfsxattrat not implemented
         |  ^
   2 warnings generated.
--
>> <stdin>:1615:2: warning: syscall getfsxattrat not implemented [-W#warnings]
    1615 | #warning syscall getfsxattrat not implemented
         |  ^
>> <stdin>:1618:2: warning: syscall setfsxattrat not implemented [-W#warnings]
    1618 | #warning syscall setfsxattrat not implemented
         |  ^
   2 warnings generated.

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: Dmitry V. Levin @ 2025-01-11 11:49 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, linux-kernel, linux-api
In-Reply-To: <20250109152138.GE26424@redhat.com>

On Thu, Jan 09, 2025 at 04:21:39PM +0100, Oleg Nesterov wrote:
> On 01/08, Dmitry V. Levin wrote:
> >
> > +ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs,
> > +			      struct ptrace_syscall_info *info)
> > +{
> ...
> > +	syscall_set_nr(child, regs, nr);
> > +	syscall_set_arguments(child, regs, args);
> > +	if (nr == -1) {
> > +		/*
> > +		 * When the syscall number is set to -1, the syscall will be
> > +		 * skipped.  In this case also set the syscall return value to
> > +		 * -ENOSYS, otherwise on some architectures the corresponding
> > +		 * struct pt_regs field will remain unchanged.
> > +		 *
> > +		 * Note that on some architectures syscall_set_return_value()
> > +		 * modifies one of the struct pt_regs fields also modified by
> > +		 * syscall_set_arguments(), so the former should be called
> > +		 * after the latter.
> > +		 */
> > +		syscall_set_return_value(child, regs, -ENOSYS, 0);
> > +	}
> 
> This doesn't look nice to me...
> 
> We don't need this syscall_set_return_value(ENOSYS) on x86, right?

No, we don't need this on x86.

> So perhaps we should move this "if (nr == -1) code  into
> syscall_set_nr/syscall_set_arguments on those "some architectures" which
> actually need it ?

Thanks for the suggestion.  I think the best option is to skip
syscall_set_arguments() invocation in case of nr == -1.  It's not just
pointless, but also it would clobber the syscall return value on those
architectures like arm64 that share the same register both for the first
argument of syscall and its return value.

This is what I'm going to implement for the next iteration of the series:

	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);


-- 
ldv

^ permalink raw reply

* Re: Crash when attaching uretprobes to processes running in Docker
From: Aleksa Sarai @ 2025-01-10 15:25 UTC (permalink / raw)
  To: Eyal Birger
  Cc: Jiri Olsa, olsajiri, mhiramat, oleg, linux-kernel,
	linux-trace-kernel, BPF-dev-list, Song Liu, Yonghong Song,
	John Fastabend, peterz, tglx, bp, x86, linux-api, Andrii Nakryiko,
	Daniel Borkmann, Alexei Starovoitov, Andrii Nakryiko,
	rostedt@goodmis.org, rafi, Shmulik Ladkani
In-Reply-To: <CAHsH6Gs3Eh8DFU0wq58c_LF8A4_+o6z456J7BidmcVY2AqOnHQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2167 bytes --]

On 2025-01-10, Eyal Birger <eyal.birger@gmail.com> wrote:
> Hi,
> 
> When attaching uretprobes to processes running inside docker, the attached
> process is segfaulted when encountering the retprobe. The offending commit
> is:
> 
> ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")
> 
> To my understanding, the reason is that now that uretprobe is a system call,
> the default seccomp filters in docker block it as they only allow a specific
> set of known syscalls.

FWIW, the default seccomp profile of Docker _should_ return -ENOSYS for
uretprobe (runc has a bunch of ugly logic to try to guarantee this if
Docker hasn't updated their profile to include it). Though I guess that
isn't sufficient for the magic that uretprobe(2) does...

> This behavior can be reproduced by the below bash script, which works before
> this commit.
> 
> Reported-by: Rafael Buchbinder <rafi@rbk.io>
> 
> Eyal.
> 
> --- CODE ---
> #!/bin/bash
> 
> cat > /tmp/x.c << EOF
> #include <stdio.h>
> #include <seccomp.h>
> 
> char *syscalls[] = {
> "write",
> "exit_group",
> };
> 
> __attribute__((noinline)) int probed(void)
> {
> printf("Probed\n");
> return 1;
> }
> 
> void apply_seccomp_filter(char **syscalls, int num_syscalls)
> {
> scmp_filter_ctx ctx;
> 
> ctx = seccomp_init(SCMP_ACT_ERRNO(1));
> for (int i = 0; i < num_syscalls; i++) {
> seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
> seccomp_syscall_resolve_name(syscalls[i]), 0);
> }
> seccomp_load(ctx);
> seccomp_release(ctx);
> }
> 
> int main(int argc, char *argv[])
> {
> int num_syscalls = sizeof(syscalls) / sizeof(syscalls[0]);
> 
> apply_seccomp_filter(syscalls, num_syscalls);
> 
> probed();
> 
> return 0;
> }
> EOF
> 
> cat > /tmp/trace.bt << EOF
> uretprobe:/tmp/x:probed
> {
>     printf("ret=%d\n", retval);
> }
> EOF
> 
> gcc -o /tmp/x /tmp/x.c -lseccomp
> 
> /usr/bin/bpftrace /tmp/trace.bt &
> 
> sleep 5 # wait for uretprobe attach
> /tmp/x
> 
> pkill bpftrace
> 
> rm /tmp/x /tmp/x.c /tmp/trace.bt
> 

-- 
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH
https://www.cyphar.com/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Crash when attaching uretprobes to processes running in Docker
From: Eyal Birger @ 2025-01-10 15:12 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: olsajiri, mhiramat, oleg, linux-kernel, linux-trace-kernel,
	BPF-dev-list, Song Liu, Yonghong Song, John Fastabend, peterz,
	tglx, bp, x86, linux-api, Andrii Nakryiko, Daniel Borkmann,
	Alexei Starovoitov, Andrii Nakryiko, rostedt@goodmis.org, rafi,
	Shmulik Ladkani

Hi,

When attaching uretprobes to processes running inside docker, the attached
process is segfaulted when encountering the retprobe. The offending commit
is:

ff474a78cef5 ("uprobe: Add uretprobe syscall to speed up return probe")

To my understanding, the reason is that now that uretprobe is a system call,
the default seccomp filters in docker block it as they only allow a specific
set of known syscalls.

This behavior can be reproduced by the below bash script, which works before
this commit.

Reported-by: Rafael Buchbinder <rafi@rbk.io>

Eyal.

--- CODE ---
#!/bin/bash

cat > /tmp/x.c << EOF
#include <stdio.h>
#include <seccomp.h>

char *syscalls[] = {
"write",
"exit_group",
};

__attribute__((noinline)) int probed(void)
{
printf("Probed\n");
return 1;
}

void apply_seccomp_filter(char **syscalls, int num_syscalls)
{
scmp_filter_ctx ctx;

ctx = seccomp_init(SCMP_ACT_ERRNO(1));
for (int i = 0; i < num_syscalls; i++) {
seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
seccomp_syscall_resolve_name(syscalls[i]), 0);
}
seccomp_load(ctx);
seccomp_release(ctx);
}

int main(int argc, char *argv[])
{
int num_syscalls = sizeof(syscalls) / sizeof(syscalls[0]);

apply_seccomp_filter(syscalls, num_syscalls);

probed();

return 0;
}
EOF

cat > /tmp/trace.bt << EOF
uretprobe:/tmp/x:probed
{
    printf("ret=%d\n", retval);
}
EOF

gcc -o /tmp/x /tmp/x.c -lseccomp

/usr/bin/bpftrace /tmp/trace.bt &

sleep 5 # wait for uretprobe attach
/tmp/x

pkill bpftrace

rm /tmp/x /tmp/x.c /tmp/trace.bt

^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Andrey Albershteyn @ 2025-01-10  9:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-fsdevel, linux-api, Michal Simek, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Naveen N Rao,
	Madhavan Srinivasan, Andy Lutomirski, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
	chris, Max Filippov, Alexander Viro, Christian Brauner, Jan Kara,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux, linux-security-module,
	Linux-Arch
In-Reply-To: <e7deabf6-8bba-45d7-a0f4-395bc8e5aabe@app.fastmail.com>

On 2025-01-09 20:59:45, Arnd Bergmann wrote:
> On Thu, Jan 9, 2025, at 18:45, Andrey Albershteyn wrote:
> >
> >  arch/alpha/kernel/syscalls/syscall.tbl      |   2 +
> >  arch/m68k/kernel/syscalls/syscall.tbl       |   2 +
> >  arch/microblaze/kernel/syscalls/syscall.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 +
> 
> You seem to be missing a couple of files here: 
> 
> arch/arm/tools/syscall.tbl
> arch/arm64/tools/syscall_32.tbl
> arch/mips/kernel/syscalls/syscall_n32.tbl
> arch/mips/kernel/syscalls/syscall_n64.tbl
> arch/mips/kernel/syscalls/syscall_o32.tbl
> 
>        Arnd
> 

Thanks! Added

-- 
- Andrey


^ permalink raw reply

* Re: [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Arnd Bergmann @ 2025-01-09 19:59 UTC (permalink / raw)
  To: Andrey Albershteyn, linux-fsdevel
  Cc: linux-api, Michal Simek, Michael Ellerman, Nicholas Piggin,
	Christophe Leroy, Naveen N Rao, Madhavan Srinivasan,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H. Peter Anvin, chris, Max Filippov,
	Alexander Viro, Christian Brauner, Jan Kara, linux-alpha,
	linux-kernel, linux-m68k, linux-parisc, linuxppc-dev, linux-s390,
	linux-sh, sparclinux, linux-security-module, Linux-Arch
In-Reply-To: <20250109174540.893098-1-aalbersh@kernel.org>

On Thu, Jan 9, 2025, at 18:45, Andrey Albershteyn wrote:
>
>  arch/alpha/kernel/syscalls/syscall.tbl      |   2 +
>  arch/m68k/kernel/syscalls/syscall.tbl       |   2 +
>  arch/microblaze/kernel/syscalls/syscall.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 +

You seem to be missing a couple of files here: 

arch/arm/tools/syscall.tbl
arch/arm64/tools/syscall_32.tbl
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl

       Arnd

^ permalink raw reply

* [PATCH] fs: introduce getfsxattrat and setfsxattrat syscalls
From: Andrey Albershteyn @ 2025-01-09 17:45 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Andrey Albershteyn, linux-api, monstr, mpe, npiggin,
	christophe.leroy, naveen, maddy, luto, tglx, mingo, bp,
	dave.hansen, x86, hpa, chris, jcmvbkbc, viro, brauner, jack, arnd,
	linux-alpha, linux-kernel, linux-m68k, linux-parisc, linuxppc-dev,
	linux-s390, linux-sh, sparclinux, linux-security-module,
	linux-arch

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. By having this we can manipulated
inode extended attributes not only on normal files but also on
special ones. This is not possible with FS_IOC_FSSETXATTR ioctl as
opening special files returns VFS special inode instead of
underlying filesystem one.

This patch adds two new syscalls which allows userspace to set
extended inode attributes on special files by using parent directory
to open FS inode.

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
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---

Notes:
    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.

 arch/alpha/kernel/syscalls/syscall.tbl      |   2 +
 arch/m68k/kernel/syscalls/syscall.tbl       |   2 +
 arch/microblaze/kernel/syscalls/syscall.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                                  | 105 ++++++++++++++++++++
 fs/ioctl.c                                  |  17 +++-
 include/linux/fileattr.h                    |   1 +
 include/linux/syscalls.h                    |   4 +
 include/uapi/asm-generic/unistd.h           |   8 +-
 16 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index c59d53d6d3f3..4b9e687494c1 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/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index f5ed71f1910d..159476387f39 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 680f568b77f2..a6d59ee740b5 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/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index d9fc94c86965..b3578fac43d6 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 d8b4ab78bef0..808045d82c94 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 e9115b4d8b63..78dfc2c184d4 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 c8cad33bf250..d5a5c8339f0e 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 727f99d333b3..817dcd8603bc 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 4d0fb2fba7e2..b4842c027c5d 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 5eb708bff1c7..b6f0a7236aae 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 37effc1b134e..425d56be337d 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 6b4c77268fc0..fc8939c6c8a7 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,105 @@ 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 *, fsx, int, at_flags)
+{
+	struct fd dir;
+	struct fileattr fa;
+	struct path filepath;
+	struct inode *inode;
+	int error;
+
+	if (at_flags)
+		return -EINVAL;
+
+	if (!capable(CAP_FOWNER))
+		return -EPERM;
+
+	dir = fdget(dfd);
+	if (!fd_file(dir))
+		return -EBADF;
+
+	if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
+		error = -EBADF;
+		goto out;
+	}
+
+	error = user_path_at(dfd, filename, at_flags, &filepath);
+	if (error)
+		goto out;
+
+	inode = filepath.dentry->d_inode;
+	if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
+		error = -EBADF;
+		goto out_path;
+	}
+
+	error = vfs_fileattr_get(filepath.dentry, &fa);
+	if (error)
+		goto out_path;
+
+	if (copy_fsxattr_to_user(&fa, fsx))
+		error = -EFAULT;
+
+out_path:
+	path_put(&filepath);
+out:
+	fdput(dir);
+	return error;
+}
+
+SYSCALL_DEFINE4(setfsxattrat, int, dfd, const char __user *, filename,
+		struct fsxattr *, fsx, int, at_flags)
+{
+	struct fd dir;
+	struct fileattr fa;
+	struct inode *inode;
+	struct path filepath;
+	int error;
+
+	if (at_flags)
+		return -EINVAL;
+
+	if (!capable(CAP_FOWNER))
+		return -EPERM;
+
+	dir = fdget(dfd);
+	if (!fd_file(dir))
+		return -EBADF;
+
+	if (!S_ISDIR(file_inode(fd_file(dir))->i_mode)) {
+		error = -EBADF;
+		goto out;
+	}
+
+	if (copy_fsxattr_from_user(&fa, fsx)) {
+		error = -EFAULT;
+		goto out;
+	}
+
+	error = user_path_at(dfd, filename, at_flags, &filepath);
+	if (error)
+		goto out;
+
+	inode = filepath.dentry->d_inode;
+	if (file_inode(fd_file(dir))->i_sb->s_magic != inode->i_sb->s_magic) {
+		error = -EBADF;
+		goto out_path;
+	}
+
+	error = mnt_want_write(filepath.mnt);
+	if (error)
+		goto out_path;
+
+	error = vfs_fileattr_set(file_mnt_idmap(fd_file(dir)), filepath.dentry,
+				 &fa);
+	mnt_drop_write(filepath.mnt);
+
+out_path:
+	path_put(&filepath);
+out:
+	fdput(dir);
+	return error;
+}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 638a36be31c1..df14f1868165 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;
 
@@ -574,6 +573,7 @@ static int copy_fsxattr_from_user(struct fileattr *fa,
 
 	return 0;
 }
+EXPORT_SYMBOL(copy_fsxattr_from_user);
 
 /*
  * Generic function to check FS_IOC_FSSETXATTR/FS_IOC_SETFLAGS values and reject
@@ -646,6 +646,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 47c05a9851d0..8598e94b530b 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 c6333204d451..a983023d21ab 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, int at_flags);
+asmlinkage long sys_setfsxattrat(int dfd, const char __user *filename,
+				 struct fsxattr *fsx, 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 88dc393c2bca..50be2e1007bc 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
-- 
2.47.0


^ permalink raw reply related

* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: Oleg Nesterov @ 2025-01-09 15:21 UTC (permalink / raw)
  To: Dmitry V. Levin
  Cc: Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, linux-kernel, linux-api
In-Reply-To: <20250107230456.GE30633@strace.io>

On 01/08, Dmitry V. Levin wrote:
>
> +ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs,
> +			      struct ptrace_syscall_info *info)
> +{
...
> +	syscall_set_nr(child, regs, nr);
> +	syscall_set_arguments(child, regs, args);
> +	if (nr == -1) {
> +		/*
> +		 * When the syscall number is set to -1, the syscall will be
> +		 * skipped.  In this case also set the syscall return value to
> +		 * -ENOSYS, otherwise on some architectures the corresponding
> +		 * struct pt_regs field will remain unchanged.
> +		 *
> +		 * Note that on some architectures syscall_set_return_value()
> +		 * modifies one of the struct pt_regs fields also modified by
> +		 * syscall_set_arguments(), so the former should be called
> +		 * after the latter.
> +		 */
> +		syscall_set_return_value(child, regs, -ENOSYS, 0);
> +	}

This doesn't look nice to me...

We don't need this syscall_set_return_value(ENOSYS) on x86, right?

So perhaps we should move this "if (nr == -1) code  into
syscall_set_nr/syscall_set_arguments on those "some architectures" which
actually need it ?

Oleg.


^ permalink raw reply

* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: Eugene Syromiatnikov @ 2025-01-09 15:17 UTC (permalink / raw)
  To: Dmitry V. Levin
  Cc: Oleg Nesterov, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, linux-kernel, linux-api
In-Reply-To: <20250107230456.GE30633@strace.io>

On Wed, Jan 08, 2025 at 01:04:56AM +0200, Dmitry V. Levin wrote:
> 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.
> 
> Current implementation supports changing only those bits of system call
> information that are used by strace, 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 re-using struct ptrace_syscall_info.reserved to specify
> the additional details that should be set.  Currently, the reserved
> field of struct ptrace_syscall_info must be initialized with zeroes;
> arch, instruction_pointer, and stack_pointer fields are 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.

> index 72c038fc71d0..231b8bf7eeff 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

It seems prudent to also add a comment about 0x4212 being taken right
after "#define PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG 0x4211", or the
usage of this ptrace request number may be overlooked on the next update.

>  struct ptrace_syscall_info {
>  	__u8 op;	/* PTRACE_SYSCALL_INFO_* */
> -	__u8 pad[3];
> +	__u8 reserved[3];
>  	__u32 arch;
>  	__u64 instruction_pointer;
>  	__u64 stack_pointer;

I would like to suggest adding flags for changing scno and args right
away;  while it is possibly of limited use and seems like an unnecessary
overcomplication, at least changing arguments only seems natural to me,
to avoid possible interaction with scno-related shenanigans that might
present/appear on some kernels and/or architectures.  Also, it makes
the aforementioned possible extensions of the interface (changing
of ip/sp) more natural (as in those cases users might definitely want
to avoid touching syscall number/arguments).


^ permalink raw reply

* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: kernel test robot @ 2025-01-09 14:03 UTC (permalink / raw)
  To: Dmitry V. Levin, Oleg Nesterov
  Cc: oe-kbuild-all, Eugene Syromyatnikov, Mike Frysinger, Renzo Davoli,
	Davide Berardi, strace-devel, linux-kernel, linux-api
In-Reply-To: <20250107230456.GE30633@strace.io>

Hi Dmitry,

kernel test robot noticed the following build warnings:

[auto build test WARNING on openrisc/for-next]
[also build test WARNING on powerpc/next powerpc/fixes s390/features uml/next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master vgupta-arc/for-curr arm64/for-next/core linus/master uml/fixes tip/x86/core vgupta-arc/for-next v6.13-rc6 next-20250109]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmitry-V-Levin/Revert-arch-remove-unused-function-syscall_set_arguments/20250108-070658
base:   https://github.com/openrisc/linux.git for-next
patch link:    https://lore.kernel.org/r/20250107230456.GE30633%40strace.io
patch subject: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
config: mips-randconfig-r122-20250109 (https://download.01.org/0day-ci/archive/20250109/202501092150.9BH2s9AO-lkp@intel.com/config)
compiler: mips64-linux-gcc (GCC) 14.2.0
reproduce: (https://download.01.org/0day-ci/archive/20250109/202501092150.9BH2s9AO-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501092150.9BH2s9AO-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   kernel/ptrace.c:55:22: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/ptrace.c:55:22: sparse:    struct task_struct *
   kernel/ptrace.c:55:22: sparse:    struct task_struct [noderef] __rcu *
   kernel/ptrace.c:74:23: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct task_struct [noderef] __rcu *parent @@     got struct task_struct *new_parent @@
   kernel/ptrace.c:74:23: sparse:     expected struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:74:23: sparse:     got struct task_struct *new_parent
   kernel/ptrace.c:75:29: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct cred const [noderef] __rcu *ptracer_cred @@     got struct cred const * @@
   kernel/ptrace.c:75:29: sparse:     expected struct cred const [noderef] __rcu *ptracer_cred
   kernel/ptrace.c:75:29: sparse:     got struct cred const *
   kernel/ptrace.c:129:18: sparse: sparse: incorrect type in assignment (different address spaces) @@     expected struct cred const *old_cred @@     got struct cred const [noderef] __rcu *ptracer_cred @@
   kernel/ptrace.c:129:18: sparse:     expected struct cred const *old_cred
   kernel/ptrace.c:129:18: sparse:     got struct cred const [noderef] __rcu *ptracer_cred
   kernel/ptrace.c:133:25: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:133:25: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:133:25: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:160:27: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:160:27: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:160:27: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:192:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:192:28: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:192:28: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:198:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:198:30: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:198:30: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:251:44: sparse: sparse: incompatible types in comparison expression (different address spaces):
   kernel/ptrace.c:251:44: sparse:    struct task_struct [noderef] __rcu *
   kernel/ptrace.c:251:44: sparse:    struct task_struct *
   kernel/ptrace.c:494:54: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *parent @@     got struct task_struct [noderef] __rcu *parent @@
   kernel/ptrace.c:494:54: sparse:     expected struct task_struct *parent
   kernel/ptrace.c:494:54: sparse:     got struct task_struct [noderef] __rcu *parent
   kernel/ptrace.c:502:53: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected struct task_struct *new_parent @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/ptrace.c:502:53: sparse:     expected struct task_struct *new_parent
   kernel/ptrace.c:502:53: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/ptrace.c:550:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct task_struct *p1 @@     got struct task_struct [noderef] __rcu *real_parent @@
   kernel/ptrace.c:550:41: sparse:     expected struct task_struct *p1
   kernel/ptrace.c:550:41: sparse:     got struct task_struct [noderef] __rcu *real_parent
   kernel/ptrace.c:552:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct sighand_struct *sigh @@     got struct sighand_struct [noderef] __rcu *sighand @@
   kernel/ptrace.c:552:50: sparse:     expected struct sighand_struct *sigh
   kernel/ptrace.c:552:50: sparse:     got struct sighand_struct [noderef] __rcu *sighand
   kernel/ptrace.c:743:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:743:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:743:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:751:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:751:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:751:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:862:29: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:862:29: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:862:29: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:866:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:866:31: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:866:31: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1206:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:1206:37: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:1206:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1208:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:1208:39: sparse:     expected struct spinlock [usertype] *lock
   kernel/ptrace.c:1208:39: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c: note: in included file (through include/linux/fwnode.h, include/linux/logic_pio.h, include/asm-generic/io.h, ...):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
   include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:751:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:751:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:380:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *l @@     got struct spinlock [noderef] __rcu * @@
   kernel/ptrace.c:380:30: sparse:     expected struct spinlock [usertype] *l
   kernel/ptrace.c:380:30: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:409:12: sparse: sparse: context imbalance in 'ptrace_attach' - different lock contexts for basic block
   kernel/ptrace.c:500:38: sparse: sparse: dereference of noderef expression
   kernel/ptrace.c: note: in included file (through include/linux/fwnode.h, include/linux/logic_pio.h, include/asm-generic/io.h, ...):
   include/linux/list.h:83:21: sparse: sparse: self-comparison always evaluates to true
   kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
   include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:751:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:751:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:690:9: sparse: sparse: context imbalance in 'ptrace_getsiginfo' - different lock contexts for basic block
   include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:751:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:751:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:706:9: sparse: sparse: context imbalance in 'ptrace_setsiginfo' - different lock contexts for basic block
   kernel/ptrace.c: note: in included file:
   arch/mips/include/asm/syscall.h:85:25: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected int const [noderef] __user *__p @@     got int * @@
   arch/mips/include/asm/syscall.h:85:25: sparse:     expected int const [noderef] __user *__p
   arch/mips/include/asm/syscall.h:85:25: sparse:     got int *
>> arch/mips/include/asm/syscall.h:121:25: sparse: sparse: incorrect type in initializer (different address spaces) @@     expected int [noderef] __user *__p @@     got int * @@
   arch/mips/include/asm/syscall.h:121:25: sparse:     expected int [noderef] __user *__p
   arch/mips/include/asm/syscall.h:121:25: sparse:     got int *
   kernel/ptrace.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
   include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:751:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:751:37: sparse:     got struct spinlock [noderef] __rcu *
   include/linux/sched/signal.h:751:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected struct spinlock [usertype] *lock @@     got struct spinlock [noderef] __rcu * @@
   include/linux/sched/signal.h:751:37: sparse:     expected struct spinlock [usertype] *lock
   include/linux/sched/signal.h:751:37: sparse:     got struct spinlock [noderef] __rcu *
   kernel/ptrace.c:1369:9: sparse: sparse: context imbalance in 'ptrace_request' - different lock contexts for basic block

vim +121 arch/mips/include/asm/syscall.h

307e4cb2957c2f Dmitry V. Levin 2025-01-08  116  
307e4cb2957c2f Dmitry V. Levin 2025-01-08  117  #ifdef CONFIG_64BIT
307e4cb2957c2f Dmitry V. Levin 2025-01-08  118  	case 4: case 5: case 6: case 7:
307e4cb2957c2f Dmitry V. Levin 2025-01-08  119  #ifdef CONFIG_MIPS32_O32
307e4cb2957c2f Dmitry V. Levin 2025-01-08  120  		if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
307e4cb2957c2f Dmitry V. Levin 2025-01-08 @121  			put_user(*arg, (int *)usp + n);
307e4cb2957c2f Dmitry V. Levin 2025-01-08  122  		else
307e4cb2957c2f Dmitry V. Levin 2025-01-08  123  #endif
307e4cb2957c2f Dmitry V. Levin 2025-01-08  124  			regs->regs[4 + n] = *arg;
307e4cb2957c2f Dmitry V. Levin 2025-01-08  125  
307e4cb2957c2f Dmitry V. Levin 2025-01-08  126  		return;
307e4cb2957c2f Dmitry V. Levin 2025-01-08  127  #endif
307e4cb2957c2f Dmitry V. Levin 2025-01-08  128  	}
307e4cb2957c2f Dmitry V. Levin 2025-01-08  129  }
307e4cb2957c2f Dmitry V. Levin 2025-01-08  130  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
From: kernel test robot @ 2025-01-09  2:21 UTC (permalink / raw)
  To: Dmitry V. Levin, Oleg Nesterov
  Cc: llvm, oe-kbuild-all, Eugene Syromyatnikov, Mike Frysinger,
	Renzo Davoli, Davide Berardi, strace-devel, linux-kernel,
	linux-api
In-Reply-To: <20250107230456.GE30633@strace.io>

Hi Dmitry,

kernel test robot noticed the following build errors:

[auto build test ERROR on openrisc/for-next]
[also build test ERROR on powerpc/next powerpc/fixes s390/features uml/next jcmvbkbc-xtensa/xtensa-for-next arnd-asm-generic/master vgupta-arc/for-curr arm64/for-next/core linus/master uml/fixes tip/x86/core vgupta-arc/for-next v6.13-rc6 next-20250108]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmitry-V-Levin/Revert-arch-remove-unused-function-syscall_set_arguments/20250108-070658
base:   https://github.com/openrisc/linux.git for-next
patch link:    https://lore.kernel.org/r/20250107230456.GE30633%40strace.io
patch subject: [PATCH 5/6] ptrace: introduce PTRACE_SET_SYSCALL_INFO request
config: hexagon-randconfig-001-20250109 (https://download.01.org/0day-ci/archive/20250109/202501090954.gYTxI9sY-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250109/202501090954.gYTxI9sY-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501090954.gYTxI9sY-lkp@intel.com/

All errors (new ones prefixed by >>):

>> kernel/ptrace.c:1053:3: error: implicit declaration of function 'syscall_set_return_value' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                   syscall_set_return_value(child, regs, -ENOSYS, 0);
                   ^
   kernel/ptrace.c:1053:3: note: did you mean 'syscall_get_return_value'?
   arch/hexagon/include/asm/syscall.h:56:20: note: 'syscall_get_return_value' declared here
   static inline long syscall_get_return_value(struct task_struct *task,
                      ^
   kernel/ptrace.c:1075:3: error: implicit declaration of function 'syscall_set_return_value' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                   syscall_set_return_value(child, regs, info->exit.rval, 0);
                   ^
   2 errors generated.


vim +/syscall_set_return_value +1053 kernel/ptrace.c

  1021	
  1022	static unsigned long
  1023	ptrace_set_syscall_info_entry(struct task_struct *child, struct pt_regs *regs,
  1024				      struct ptrace_syscall_info *info)
  1025	{
  1026		unsigned long args[ARRAY_SIZE(info->entry.args)];
  1027		int nr = info->entry.nr;
  1028		int i;
  1029	
  1030		if (nr != info->entry.nr)
  1031			return -ERANGE;
  1032	
  1033		for (i = 0; i < ARRAY_SIZE(args); i++) {
  1034			args[i] = info->entry.args[i];
  1035			if (args[i] != info->entry.args[i])
  1036				return -ERANGE;
  1037		}
  1038	
  1039		syscall_set_nr(child, regs, nr);
  1040		syscall_set_arguments(child, regs, args);
  1041		if (nr == -1) {
  1042			/*
  1043			 * When the syscall number is set to -1, the syscall will be
  1044			 * skipped.  In this case also set the syscall return value to
  1045			 * -ENOSYS, otherwise on some architectures the corresponding
  1046			 * struct pt_regs field will remain unchanged.
  1047			 *
  1048			 * Note that on some architectures syscall_set_return_value()
  1049			 * modifies one of the struct pt_regs fields also modified by
  1050			 * syscall_set_arguments(), so the former should be called
  1051			 * after the latter.
  1052			 */
> 1053			syscall_set_return_value(child, regs, -ENOSYS, 0);
  1054		}
  1055	
  1056		return 0;
  1057	}
  1058	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox