Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv: add riscv arch support #375

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

riscv: add riscv arch support #375

wants to merge 2 commits into from

Conversation

Jer6y
Copy link

@Jer6y Jer6y commented Apr 10, 2024

add riscv arch support

Why does using -O0 result in fewer test case failures compared to using -O2 on openEuler RISCV? I am not certain of the reason, but it may be related to some issues with the compiler optimizations.

The porting effectiveness test can be found at the link https://github.com/Jer6y/rv_linux_bug, which also describes a bug related to ptrace on RISCV Linux that has not yet been fixed. However, it is possible to perform some rather rudimentary operations locally to temporarily correct the ptrace issue.

#368

*add riscv arch support

Signed-off-by: luojun <[email protected]>
@Jer6y
Copy link
Author

Jer6y commented Apr 11, 2024

README Summary

This is a brief readme introduction on how to properly run and operate proot on openEuler RISCV 23.09. Before compiling and running, there is a bug with RISCV Linux ptrace that needs to be addressed.

Bug summary

A ptrace bug in riscv linux , when tracer want to change tracee's a0 register in option PTRACE_SYSCALL to stop the tracee

Bug descrption

  • Hardware Environment : Qemu 7.2.0, qemu-system-riscv64
  • OS Distribution: openEuler 23.09 RISCV community
  • Linux Kernel Version: 6.4.0
  • Bug Description : when i am trying to use ptrace for tracer to change the tracee's a0 register in riscv linux when tracee is trace stopped by PTRACE_SYSCALL, actually , it doesn't change a0 , but it actually can change a1 ... a7 and other registers

Bug analysis

  • Take a look at this patch [PATCH] riscv: entry: Save a0 prior syscall_enter_from_user_mode() (kernel.org)

  • we need to know that where will sleep in when tracee signal self in syscall enter. take a look at file in linux /arch/riscv/kernel/traps.c , the function do_trap_ecall_u , every time process execute syscall will get in the function , and will be blocked in syscall_enter_from_user_mode if it is traced for syscall enter and exit . and you will know that regs->orig_a0 is be assigned before syscall_enter_from_user_mode . and if we use ptrace for tracer to change the register , we can't change orig_a0 , we can only change a0, because riscv ptrace USERSPACE don't support the orig_a0 change. so, actually , we can't change orig_a0 use PTRACE_SYSCALL option.

Bug Reproduction

compile code.c and test.c in riscv linux

gcc code.c -o a.out
gcc test.c -o test

put a.out test in the same directory

execute a.out

./a.out

what do "a.out" and "test" do ?

  • a.out
    • fork and setup tracee relationship between father and son
    • father process : take waitpid to get tracee and use ptrace syscall to change a0 to NULL when tracee is executing execve syscall
    • son process : first claim itself can be traced and signal self to be trace stopped , then execute ./test ELF
  • test
    • print all argument passed by execve syscall , also the envp
  • if ptrace execute success , test will not be excuted , but actually , ./test works well .

hot to fix bug

  • add orig_a0 to USERSPACE : This behavior can affect many modules, including some user space header files such as asm/ptrace.h, etc. I have not submitted the corresponding patch, but rather reported it as a bug to the Linux community.

simple way to support ptrace and run proot

  • Note : The methods for all these options are only applicable for temporarily modifying the kernel code locally.
    • insert the code "if(regs->orig_a0 != regs->a0 ) regs->orig_a0 = regs->a0" at the end of the syscall_trace_enter function in the file /kernel/entry/common.c.
    • The places marked with red lines are where you need to add the corresponding code.
    • The addition of this code is rather crude:

testcase for riscv proot

I employed a temporary solution by recompiling the openEuler kernel locally, and this is the result of my proot test cases.

Clipchamp.1.mp4

Compared to running on x86, there were 7 additional failures.

This could be due to the ptrace still having bugs, or it might be that the ported code requires further improvement.

use proot on openEuler riscv to chroot

Clipchamp.1.mp4

*fix bug on riscv for loader mprotect syscall

Signed-off-by: luojun <[email protected]>
@Kreijstal
Copy link

ahh just what I was looking for!

would that fix work over for https://github.com/proot-me/proot-rs as well?

@Jer6y
Copy link
Author

Jer6y commented Jun 23, 2024

ahh just what I was looking for!

would that fix work over for https://github.com/proot-me/proot-rs as well?

I'm sorry that I'm not so familiar with Rust. Perhaps in the future, I will support rust proot, possibly when RISC-V mobile phones come out.

@lrzlin
Copy link

lrzlin commented Jun 25, 2024

Why does using -O0 result in fewer test case failures compared to using -O2 on openEuler RISCV? I am not certain of the reason, but it may be related to some issues with the compiler optimizations.

Maybe you should trying add $cc in SYSCALL macro's clobber list and make result from =r to +r.

Ref: riscv nolibc header https://github.com/torvalds/linux/blob/master/tools/include/nolibc/arch-riscv.h

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants