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: <a5fc83e3-4d4a-49da-8dc8-8bf3973bc851@huaweicloud.com>
Date: Fri, 25 Jul 2025 09:48:09 +0800
From: Chen Ridong <chenridong@...weicloud.com>
To: tj@...nel.org, hannes@...xchg.org, mkoutny@...e.com, lizefan@...wei.com
Cc: cgroups@...r.kernel.org, linux-kernel@...r.kernel.org,
 lujialin4@...wei.com, chenridong@...wei.com, gaoyingjie@...ontech.com
Subject: Re: [PATCH v2 -next] cgroup: remove offline draining in root
 destruction to avoid hung_tasks



On 2025/7/22 19:27, Chen Ridong wrote:
> From: Chen Ridong <chenridong@...wei.com>
> 
> A hung task can occur during [1] LTP cgroup testing when repeatedly
> mounting/unmounting perf_event and net_prio controllers with
> systemd.unified_cgroup_hierarchy=1. The hang manifests in
> cgroup_lock_and_drain_offline() during root destruction.
> 
> Related case:
> cgroup_fj_function_perf_event cgroup_fj_function.sh perf_event
> cgroup_fj_function_net_prio cgroup_fj_function.sh net_prio

This can be easily reproduced by the process(offered by Yingjie):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>

#define LOOPS 10000
#define TMPDIR "/tmp"
#define CGROUP_BASE "ltp_cgtest"
#define CONTROLLERS_COUNT 2

const char *controllers[CONTROLLERS_COUNT] = {"perf_event", "net_prio"};

void safe_mkdir(const char *path) {
    if (mkdir(path, 0777) == -1 && errno != EEXIST) {
        fprintf(stderr, "mkdir(%s) failed: %s\n", path, strerror(errno));
        exit(1);
    }
}

void safe_rmdir(const char *path) {
    if (rmdir(path) == -1 && errno != ENOENT) {
        fprintf(stderr, "rmdir(%s) failed: %s\n", path, strerror(errno));
    }
}

int is_mounted(const char *mnt) {
    FILE *fp = fopen("/proc/mounts", "r");
    if (!fp) return 0;
    char line[512];
    int found = 0;
    while (fgets(line, sizeof(line), fp)) {
        if (strstr(line, mnt)) {
            found = 1;
            break;
        }
    }
    fclose(fp);
    return found;
}

int main(void) {
    if (getuid() != 0) {
        fprintf(stderr, "This program must be run as root\n");
        return 1;
    }

    FILE *fcg = fopen("/proc/cgroups", "r");
    if (!fcg) {
        fprintf(stderr, "Kernel does not support cgroups\n");
        return 1;
    }
    fclose(fcg);

    char mnt[256];
    for (int i = 1; i <= LOOPS; ++i) {
        for (int c = 0; c < CONTROLLERS_COUNT; ++c) {
            snprintf(mnt, sizeof(mnt), "%s/cgroup_%s", TMPDIR, controllers[c]);
            printf("=== Loop %d: %s ===\n", i, controllers[c]);
            fflush(stdout);

            safe_mkdir(mnt);

            if (!is_mounted(mnt)) {
                if (mount(controllers[c], mnt, "cgroup", 0, controllers[c]) == -1) {
                    fprintf(stderr, "Failed to mount cgroup v1 for %s at %s: %s\n",
                            controllers[c], mnt, strerror(errno));
                    safe_rmdir(mnt);
                    continue;
                }
            }

            if (umount2(mnt, 0) == -1) {
                fprintf(stderr, "umount(%s) failed: %s\n", mnt, strerror(errno));
            }
            safe_rmdir(mnt);
        }
    }
    return 0;
}


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ