[Devel] [PATCH RHEL7 COMMIT] cgroup: fix css_tryget() to not succeed on offlined css

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jul 19 15:24:08 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-862.6.3.vz7.62.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.6.3.vz7.62.4
------>
commit 892dd3829a9978894d19ba090f6125c470949495
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Thu Jul 19 15:24:08 2018 +0300

    cgroup: fix css_tryget() to not succeed on offlined css
    
    We made the backport of the upstream commit d3daf28da16a ("cgroup: use percpu
    refcnt for cgroup_subsys_states") which contains the following hunk:
    
    @@ -123,11 +117,9 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
     {
            if (css->flags & CSS_ROOT)
                    return true;
    -       return __css_tryget(css);
    +       return percpu_ref_tryget(&css->refcnt);
    
    RedHat backpoted:
           2070d50e1cbe ("percpu-refcount: rename percpu_ref_tryget() to percpu_ref_tryget_live()")
           4fb6e25049cb ("percpu-refcount: implement percpu_ref_tryget()")
    
    The first patch simply renames existed percpu_ref_tryget() to percpu_ref_tryget_live().
    Upstream version obviously changes percpu_ref_tryget() in css_tryget()
    to percpu_ref_tryget_live(). Redhat's version doesn't do that, because
    css_tryget() doesn't use percpu counter in Redhat's kernel source.
    
    The second patch adds new function percpu_ref_tryget() which our
    css_tryget() wrongly uses. This may lead to successful css_tryget()
    on offlined css, which shouldn't happen. And that may lead to all sorts
    of issues like use-after-frees, crashes, etc...
    
    Use percpu_ref_tryget_live() in css_tryget() to fix this.
    
    Fixes: 3d9ce312825f ("ms/cgroup: use percpu refcnt for cgroup_subsys_states")
    https://jira.sw.ru/browse/PSBM-75892
    
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 include/linux/cgroup.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index e18fcd930eb1..9f43eb357c6a 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -167,7 +167,7 @@ static inline bool css_tryget(struct cgroup_subsys_state *css)
 {
 	if (css->flags & CSS_ROOT)
 		return true;
-	return percpu_ref_tryget(&css->refcnt);
+	return percpu_ref_tryget_live(&css->refcnt);
 }
 
 /*


More information about the Devel mailing list