merged into
e766b39ed060 ve/kthread: fix race when work can be added to stopped kthread 
worker #VSTOR-106887

--
Best regards,

Konstantin Khorenko,
Virtuozzo Linux Kernel Team

On 6/12/26 11:56, Pavel Tikhomirov wrote:
> Reviewed-by: Pavel Tikhomirov <[email protected]>
> 
> On 6/12/26 08:57, Konstantin Khorenko wrote:
>> ve_stop_ns() switches the VE to VE_STATE_STOPPING and then waits for all
>> in-flight per-VE user-mode helpers to drain via wait_khelpers(). After
>> the per-VE workqueue / cgroup release_agent infrastructure was removed,
>> this wait ended up running under ve->op_sem held for write.
>>
>> That is a deadlock: a call_usermodehelper_exec_ve() payload waited for
>> by wait_khelpers() may run arbitrary user code that accesses ve.* cgroup
>> files, and those take ve->op_sem (for read). ve_stop_ns() would then
>> block forever holding op_sem for write while the helper blocks trying to
>> acquire it.
>>
>> Drop ve->op_sem around wait_khelpers() and re-acquire it afterwards, the
>> way the code did before the release_agent removal (it used to drop the
>> lock around wait_khelpers() + ve_workqueue_stop()). The VE is already in
>> VE_STATE_STOPPING before the lock is dropped, so no new helper can be
>> queued and all op_sem entry points bail out on the state check.
>>
>> Fixes: 9b103188a9b2 ("ve/kthread: fix race when work can be added to stopped 
>> kthread worker")
>> Reported-by: Pavel Tikhomirov <[email protected]>
>> https://virtuozzo.atlassian.net/browse/VSTOR-132310
>> Signed-off-by: Konstantin Khorenko <[email protected]>
>> ---
>>  kernel/ve/ve.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
>> index 65723f28dbad..231c0300e929 100644
>> --- a/kernel/ve/ve.c
>> +++ b/kernel/ve/ve.c
>> @@ -575,7 +575,19 @@ void ve_stop_ns(struct pid_namespace *pid_ns)
>>      ve_set_state(ve, VE_STATE_STOPPING);
>>      synchronize_rcu();
>>  
>> +    /*
>> +     * Drop the lock before waiting for in-flight user-mode helpers.
>> +     * A call_usermodehelper_exec_ve() payload may access ve.* cgroup
>> +     * files, which take ve->op_sem, so waiting for it via wait_khelpers()
>> +     * while holding op_sem would deadlock. The state is already
>> +     * VE_STATE_STOPPING, so no new helper can be queued; all entry points
>> +     * must check the state before proceeding.
>> +     */
>> +    up_write(&ve->op_sem);
>> +
>>      wait_khelpers(ve);
>> +
>> +    down_write(&ve->op_sem);
>>      /*
>>       * Neither it can be in pseudosuper state
>>       * anymore, setup it again if needed.
> 

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to