Both early error returns inside the rcu_read_lock() section returned
without dropping the lock:
rcu_read_lock();
ve_nsproxy = rcu_dereference(ve->ve_nsproxy);
if (!ve_nsproxy || !ve_nsproxy->pid_ns_for_children)
return -EBUSY; /* RCU read lock still held */
if (pid_max_min > val || pid_max_max < val)
return -EINVAL; /* RCU read lock still held */
Writing an out-of-range value to the ve cgroup pid_max file, or writing
to a CT whose pid_ns_for_children is not set up yet, returned with the
RCU read lock held, leaving preempt_count/RCU unbalanced (RCU stalls and
"sleeping in RCU read-side critical section" splats on the next sleeping
call). Add rcu_read_unlock() before both error returns.
Fixes: 3f103833ed3b ("ve/pid: Export kernel.pid_max via ve cgroup")
https://virtuozzo.atlassian.net/browse/VSTOR-132310
Signed-off-by: Konstantin Khorenko <[email protected]>
---
kernel/ve/ve.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 198c82f010cc..37ac9c4ba0f5 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -1403,9 +1403,11 @@ static int ve_pid_max_write_running_u64(struct
cgroup_subsys_state *css,
rcu_read_lock();
ve_nsproxy = rcu_dereference(ve->ve_nsproxy);
if (!ve_nsproxy || !ve_nsproxy->pid_ns_for_children) {
+ rcu_read_unlock();
return -EBUSY;
}
if (pid_max_min > val || pid_max_max < val) {
+ rcu_read_unlock();
return -EINVAL;
}
--
2.47.1
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel