getpriority(PRIO_PROCESS, tid) returns ESRCH for live guest threads
Description
A multithreaded guest program can abort when it calls
getpriority(PRIO_PROCESS, tid) for a live guest thread id.
On Linux, PRIO_PROCESS accepts a process id, and Linux thread ids are valid
targets because threads are represented as tasks. If tid refers to a live
thread in the same process, getpriority(PRIO_PROCESS, tid) should return that
task's nice value.
In elfuse, getpriority currently appears to accept only who == 0 or
who == guest_pid. When a guest runtime calls getpriority(PRIO_PROCESS, 2)
for a live guest thread, elfuse returns -ESRCH.
Observed Behavior
Verbose elfuse log:
syscall 141 ... (0x0, 0x2, ...)
-> -3
On AArch64:
syscall 141 = getpriority
x0 = 0 = PRIO_PROCESS
x1 = 2 = target guest tid
return -3 = -ESRCH
The guest then aborts because getpriority unexpectedly failed with
ESRCH:
Check failed: niceness != -1 || errno == 0 No such process
Expected Behavior
If who names a live guest thread, elfuse should treat it as a valid
PRIO_PROCESS target and return the emulated nice value.
For example:
getpriority(PRIO_PROCESS, 0) -> current nice value
getpriority(PRIO_PROCESS, guest_pid) -> current nice value
getpriority(PRIO_PROCESS, live_tid) -> current nice value
getpriority(PRIO_PROCESS, dead_tid) -> -ESRCH
setpriority(PRIO_PROCESS, tid, prio) should likely follow the same target
validation rules.
Suspected Root Cause
proc_sys_getpriority() only accepts self or the process id:
if (who != 0 && who != (int) guest_pid)
return -LINUX_ESRCH;
This rejects valid guest thread ids even though elfuse tracks them in the thread
table.
Suggested Fix
For PRIO_PROCESS, accept:
who == 0
who == guest_pid
thread_tid_alive(who)
Then return 20 - emu_nice.
Apply equivalent target validation to proc_sys_setpriority().
Test Suggestion
Add a regression test that creates a guest thread and calls:
getpriority(PRIO_PROCESS, child_tid)
Expected result should be the current nice value, not -ESRCH.
Also test:
setpriority(PRIO_PROCESS, child_tid, 5);
getpriority(PRIO_PROCESS, child_tid);
Expected result should reflect the emulated nice value.
getpriority(PRIO_PROCESS, tid) returns ESRCH for live guest threads
Description
A multithreaded guest program can abort when it calls
getpriority(PRIO_PROCESS, tid)for a live guest thread id.On Linux,
PRIO_PROCESSaccepts a process id, and Linux thread ids are validtargets because threads are represented as tasks. If
tidrefers to a livethread in the same process,
getpriority(PRIO_PROCESS, tid)should return thattask's nice value.
In elfuse,
getprioritycurrently appears to accept onlywho == 0orwho == guest_pid. When a guest runtime callsgetpriority(PRIO_PROCESS, 2)for a live guest thread, elfuse returns
-ESRCH.Observed Behavior
Verbose elfuse log:
On AArch64:
The guest then aborts because
getpriorityunexpectedly failed withESRCH:Expected Behavior
If
whonames a live guest thread, elfuse should treat it as a validPRIO_PROCESStarget and return the emulated nice value.For example:
setpriority(PRIO_PROCESS, tid, prio)should likely follow the same targetvalidation rules.
Suspected Root Cause
proc_sys_getpriority()only accepts self or the process id:This rejects valid guest thread ids even though elfuse tracks them in the thread
table.
Suggested Fix
For
PRIO_PROCESS, accept:who == 0who == guest_pidthread_tid_alive(who)Then return
20 - emu_nice.Apply equivalent target validation to
proc_sys_setpriority().Test Suggestion
Add a regression test that creates a guest thread and calls:
Expected result should be the current nice value, not
-ESRCH.Also test:
Expected result should reflect the emulated nice value.