The risc-v kernel copyin() routine loops forever if the user passs a
pointer with the high bit set. I"m using qemu 5.2.0 to run this image:
I compile and run this program:
fcntl(1, F_GETLK, 0x800000c000000000);
The kernel fcntl calls copyin(), which never returns. I'm guessing that
copyin's bgt in copyinout.S should be a bgtu:
beqz a2, copyin_end /* If len == 0 then skip loop */
add a3, a0, a2
li a4, VM_MAXUSER_ADDRESS
bgt a3, a4, copyio_fault_nopcb
Thanks for the report, indeed the use of bgt seems inappropriate here. I will look at this in detail shortly.
Also, creat(0x0000004000000000UL,0) causes copyinstr() to
loop forever. Perhaps bgeu rather that bgt.
(In reply to Robert Morris from comment #2)
I have posted a review for the fix, which uses the bgeu instruction:
I was wondering why these cases would loop continuously, rather than panic the system with a fatal page fault. I was able to track this down too:
So, thanks again for the detailed report. Out of curiosity, did you find the issue by inspection, or did it manifest in some real program or test?
(In reply to Mitchell Horne from comment #3)
I found the bug using a symbolic execution system for risc-v
that I've been working on.