Re: [PATCH 08/10] parisc: fix livelock in uaccess

Helge Deller
2023-02-28T19:32:30Z

Hi Al,

On 2/28/23 20:14, Al Viro wrote:
> On Tue, Feb 28, 2023 at 07:26:48PM +0100, Helge Deller wrote:
>
>> I can test both parisc32 and parisc64.
>>
>>> Just to confirm: your "can be killed with ^C" had been on the
>>> mainline parisc kernel (with userfaultfd enable, of course, or it wouldn't
>>> hang up at all), right?
>>
>> It was a recent mainline kernel with your patch.
>
> Er... Reproducer *is* supposed to block; the bug is that on the kernel
> without this patch it would (AFAICS) be impossible to kill - not even
> with kill -9. With bug fixed the behaviour should be "blocks and is
> killable", i.e. what you've reported.
>
> What does it do on unpatched kernel? *IF* the big is there, it would
> block and be unkillable by any means. Could you verify that?

I just tried 32- and 64-bit kernels.
With and without your patch on top of kernel 6.2.
The result is always the same:
The process hangs, but does not consume CPU and can be killed with ^C or kill command.

strace output is:

userfaultfd(0) = 3
ioctl(3, UFFDIO_API, {api=0xaa, features=0 => features=UFFD_FEATURE_EVENT_FORK|UFFD_FEATURE_EVENT_REMAP|UFFD_FEATURE_EVENT_REMOVE|UFFD_FEATURE_MISSING_HUGETLBFS|UFFD_FEATURE_MISSING_SHMEM|UFFD_FEATURE_EVENT_UNMAP|UFFD_FEATURE_SIGBUS|UFFD_FEATURE_THREAD_ID|0x800, ioctls=1<<_UFFDIO_REGISTER|1<<_UFFDIO_UNREGISTER|1<<_UFFDIO_API}) = 0
ioctl(3, UFFDIO_REGISTER, {range={start=0xf7afa000, len=0x1000}, mode=UFFDIO_REGISTER_MODE_MISSING, ioctls=1<<_UFFDIO_WAKE|1<<_UFFDIO_COPY|1<<_UFFDIO_ZEROPAGE}) = 0
fstatfs64(0, 88, {f_type=DEVPTS_SUPER_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NOEXEC|ST_RELATIME}) = 0

<here it hangs until I kill the process with SIGTERM>

--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=859, si_uid=0} ---
+++ killed by SIGTERM +++
Terminated

It seems the code flow doesn't reaches fault_signal_pending(), or it returns false...

Helge