lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f4c4f465-72b9-4682-99e6-c249ecab8572@huaweicloud.com>
Date: Fri, 4 Jul 2025 11:02:52 +0800
From: Chen Ridong <chenridong@...weicloud.com>
To: Michal Koutný <mkoutny@...e.com>
Cc: peterz@...radead.org, rafael@...nel.org, pavel@...nel.org,
 timvp@...gle.com, tj@...nel.org, linux-pm@...r.kernel.org,
 linux-kernel@...r.kernel.org, lujialin4@...wei.com, chenridong@...wei.com
Subject: Re: [PATCH next] sched,freezer: prevent tasks from escaping being
 frozen



On 2025/7/4 1:01, Michal Koutný wrote:
> Hello Ridong.
> 
> On Thu, Jul 03, 2025 at 01:34:27PM +0000, Chen Ridong <chenridong@...weicloud.com> wrote:
>> 2. The cgroup freezer state changes to FROZEN (Can be triggered by reading
>>    freezer.state).
> /o\
> 
>> 3. freezing() is called and returns false.
> 
> I can see how this can happen because freezer_lock != freezer_mutex.
> 
>> As a result, the task may escape being frozen when it should be.
>>
>> To fix this, move the setting of the FROZEN flag to occur just before
>> schedule(). This ensures the flag is only set when we're certain the
>> task must be switched out.
> 
> Is it sufficient? (If the task is spuriously woken up, the next
> iteration in that refrigerator loop would be subject to same race, no?)
> 
> Thanks,
> Michal

Hi, Michal:

Regarding your question: Did you mean that the task was frozen, received
another signal to wake up, but should have remained frozen instead of
entering the running state?

For this scenario, the solution I've found is that the task can only
break out of the frozen state when its cgroup is thawed. The code
modification would look like the following, and we'll need to add the
cgroup_thawed(p) function:

--- a/kernel/freezer.c
+++ b/kernel/freezer.c
@@ -71,19 +71,20 @@ bool __refrigerator(bool check_kthr_stop)
        for (;;) {
                bool freeze;

-               raw_spin_lock_irq(&current->pi_lock);
-               WRITE_ONCE(current->__state, TASK_FROZEN);
-               /* unstale saved_state so that __thaw_task() will wake
us up */
-               current->saved_state = TASK_RUNNING;
-               raw_spin_unlock_irq(&current->pi_lock);
-
                spin_lock_irq(&freezer_lock);
-               freeze = freezing(current) && !(check_kthr_stop &&
kthread_should_stop());
+               freeze = (freezing(current) && !cgroup_thawed(current))
+                        && !(check_kthr_stop && kthread_should_stop());
                spin_unlock_irq(&freezer_lock);

                if (!freeze)
                        break;

+               raw_spin_lock_irq(&current->pi_lock);
+               WRITE_ONCE(current->__state, TASK_FROZEN);
+               /* unstale saved_state so that __thaw_task() will wake
us up */
+               current->saved_state = TASK_RUNNING;
+               raw_spin_unlock_irq(&current->pi_lock);
+

I'd welcome any suggestions for better solutions to this problem.

Best regards,
Ridong


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ