diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..78d19eb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libcgroup-0.41.tar.bz2 diff --git a/.libcgroup.metadata b/.libcgroup.metadata new file mode 100644 index 0000000..7e93276 --- /dev/null +++ b/.libcgroup.metadata @@ -0,0 +1 @@ +9b7537bf2204f6b78d63a9f77e3c75443d28a6d5 SOURCES/libcgroup-0.41.tar.bz2 diff --git a/SOURCES/cgconfig.service b/SOURCES/cgconfig.service new file mode 100644 index 0000000..6be383f --- /dev/null +++ b/SOURCES/cgconfig.service @@ -0,0 +1,18 @@ +[Unit] +Description=Control Group configuration service + +# The service should be able to start as soon as possible, +# before any 'normal' services: +DefaultDependencies=no +Conflicts=shutdown.target +Before=basic.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +Delegate=yes +ExecStart=/usr/sbin/cgconfigparser -l /etc/cgconfig.conf -s 1664 +ExecStop=/usr/sbin/cgclear -l /etc/cgconfig.conf -e + +[Install] +WantedBy=sysinit.target diff --git a/SOURCES/fedora-config.patch b/SOURCES/fedora-config.patch new file mode 100644 index 0000000..5fafc32 --- /dev/null +++ b/SOURCES/fedora-config.patch @@ -0,0 +1,65 @@ +Fedora specific configuration - we want to mount all controllers by default for libvirt. + +diff -up libcgroup-0.34/samples/cgconfig.conf.orig libcgroup-0.34/samples/cgconfig.conf +--- libcgroup-0.34/samples/cgconfig.conf.orig 2009-03-04 10:40:06.000000000 +0100 ++++ libcgroup-0.34/samples/cgconfig.conf 2009-10-19 10:17:37.000000000 +0200 +@@ -10,39 +10,8 @@ + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + # +-#group daemons/www { +-# perm { +-# task { +-# uid = root; +-# gid = webmaster; +-# } +-# admin { +-# uid = root; +-# gid = root; +-# } +-# } +-# cpu { +-# cpu.shares = 1000; +-# } +-#} + # +-#group daemons/ftp { +-# perm { +-# task { +-# uid = root; +-# gid = ftpmaster; +-# } +-# admin { +-# uid = root; +-# gid = root; +-# } +-# } +-# cpu { +-# cpu.shares = 500; +-# } +-#} +-# +-#mount { +-# cpu = /mnt/cgroups/cpu; +-# cpuacct = /mnt/cgroups/cpuacct; +-#} ++# By default, we expect systemd mounts everything on boot, ++# so there is not much to do. ++# See man cgconfig.conf for further details, how to create groups ++# on system boot using this file. ++ +diff -up libcgroup-0.35.1/samples/cgconfig.sysconfig.orig libcgroup-0.35.1/samples/cgconfig.sysconfig +--- libcgroup-0.35.1/samples/cgconfig.sysconfig.orig 2010-03-09 14:56:34.000000000 +0100 ++++ libcgroup-0.35.1/samples/cgconfig.sysconfig 2010-03-09 16:30:12.000000000 +0100 +@@ -5,8 +5,6 @@ + # controller to limit cpu.shares of this default group and allowing some more + # important group take most of the CPU. + # +-# By default, create these groups: +-CREATE_DEFAULT=yes +- +-# Uncomment following line to disable creation of the default group on startup: +-# CREATE_DEFAULT=no ++# By default, do not create these groups: ++# CREATE_DEFAULT=yes ++CREATE_DEFAULT=no diff --git a/SOURCES/libcgroup-0.37-chmod.patch b/SOURCES/libcgroup-0.37-chmod.patch new file mode 100644 index 0000000..bca595f --- /dev/null +++ b/SOURCES/libcgroup-0.37-chmod.patch @@ -0,0 +1,31 @@ +diff -up libcgroup-0.41/src/api.c.chmod libcgroup-0.41/src/api.c +--- libcgroup-0.41/src/api.c.chmod 2014-01-13 15:05:56.000000000 +0100 ++++ libcgroup-0.41/src/api.c 2014-01-13 20:41:55.255577622 +0100 +@@ -153,6 +153,10 @@ static int cg_chown_file(FTS *fts, FTSEN + return ret; + } + ++int cg_chmod_file(FTS *fts, FTSENT *ent, mode_t dir_mode, ++ int dirm_change, mode_t file_mode, int filem_change, ++ int owner_is_umask); ++ + /* + * TODO: Need to decide a better place to put this function. + */ +@@ -160,6 +164,8 @@ static int cg_chown_recursive(char **pat + { + int ret = 0; + FTS *fts; ++ /* mode 664 */ ++ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; + + cgroup_dbg("chown: path is %s\n", *path); + fts = fts_open(path, FTS_PHYSICAL | FTS_NOCHDIR | +@@ -177,6 +183,7 @@ static int cg_chown_recursive(char **pat + cgroup_warn("Warning: fts_read failed\n"); + break; + } ++ cg_chmod_file(fts, ent, mode, 0, mode, 1, 1); + ret = cg_chown_file(fts, ent, owner, group); + } + fts_close(fts); diff --git a/SOURCES/libcgroup-0.40.rc1-coverity.patch b/SOURCES/libcgroup-0.40.rc1-coverity.patch new file mode 100644 index 0000000..439abf1 --- /dev/null +++ b/SOURCES/libcgroup-0.40.rc1-coverity.patch @@ -0,0 +1,99 @@ +diff -up libcgroup-0.41/src/api.c.coverity libcgroup-0.41/src/api.c +--- libcgroup-0.41/src/api.c.coverity 2014-01-13 20:52:49.853838149 +0100 ++++ libcgroup-0.41/src/api.c 2014-01-13 20:52:49.854838142 +0100 +@@ -2791,7 +2791,6 @@ static int cgroup_create_template_group( + if (group_name == NULL) { + ret = ECGOTHER; + last_errno = errno; +- free(template_name); + goto end; + } + +diff -up libcgroup-0.41/src/config.c.coverity libcgroup-0.41/src/config.c +--- libcgroup-0.41/src/config.c.coverity 2014-01-13 15:05:56.000000000 +0100 ++++ libcgroup-0.41/src/config.c 2014-01-13 20:52:49.854838142 +0100 +@@ -323,7 +323,7 @@ int config_group_task_perm(char *perm_ty + long val = atoi(value); + char buffer[CGROUP_BUFFER_LEN]; + struct cgroup *config_cgroup; +- int table_index; ++ int table_index, ret; + + switch (flag) { + case CGROUP: +@@ -367,10 +367,10 @@ int config_group_task_perm(char *perm_ty + if (!group) + goto group_task_error; + +- getgrnam_r(value, group, buffer, ++ ret = getgrnam_r(value, group, buffer, + CGROUP_BUFFER_LEN, &group_buffer); + +- if (group_buffer == NULL) { ++ if (ret != 0 || group_buffer == NULL) { + free(group); + goto group_task_error; + } +@@ -436,7 +436,7 @@ int config_group_admin_perm(char *perm_t + struct cgroup *config_cgroup; + long val = atoi(value); + char buffer[CGROUP_BUFFER_LEN]; +- int table_index; ++ int table_index, ret; + + switch (flag) { + case CGROUP: +@@ -479,10 +479,10 @@ int config_group_admin_perm(char *perm_t + if (!group) + goto admin_error; + +- getgrnam_r(value, group, buffer, ++ ret = getgrnam_r(value, group, buffer, + CGROUP_BUFFER_LEN, &group_buffer); + +- if (group_buffer == NULL) { ++ if (ret != 0 || group_buffer == NULL) { + free(group); + goto admin_error; + } +diff -up libcgroup-0.41/src/daemon/cgrulesengd.c.coverity libcgroup-0.41/src/daemon/cgrulesengd.c +--- libcgroup-0.41/src/daemon/cgrulesengd.c.coverity 2014-01-13 15:05:56.000000000 +0100 ++++ libcgroup-0.41/src/daemon/cgrulesengd.c 2014-01-13 20:52:49.854838142 +0100 +@@ -646,7 +646,7 @@ close: + + static int cgre_create_netlink_socket_process_msg(void) + { +- int sk_nl = 0, sk_unix = 0, sk_max; ++ int sk_nl = -1, sk_unix = -1, sk_max; + struct sockaddr_nl my_nla; + char buff[BUFF_SIZE]; + int rc = -1; +@@ -784,9 +784,9 @@ static int cgre_create_netlink_socket_pr + } + + close_and_exit: +- if (sk_nl > 0) ++ if (sk_nl > -1) + close(sk_nl); +- if (sk_unix > 0) ++ if (sk_unix > -1) + close(sk_unix); + return rc; + } +diff -upr libcgroup-0.40.rc1.orig/src/tools/lscgroup.c libcgroup-0.40.rc1/src/tools/lscgroup.c +--- libcgroup-0.40.rc1.orig/src/tools/lscgroup.c 2013-05-21 15:36:04.000000000 +0200 ++++ libcgroup-0.40.rc1/src/tools/lscgroup.c 2013-11-04 14:26:53.400473523 +0100 +@@ -97,11 +97,11 @@ static int display_controller_data(char + if (ret != 0) + return ret; + +- strncpy(cgroup_dir_path, info.full_path, FILENAME_MAX); ++ strncpy(cgroup_dir_path, info.full_path, FILENAME_MAX - 1); + /* remove problematic '/' characters from cgroup directory path*/ + trim_filepath(cgroup_dir_path); + +- strncpy(input_dir_path, input_path, FILENAME_MAX); ++ strncpy(input_dir_path, input_path, FILENAME_MAX - 1); + + /* remove problematic '/' characters from input directory path*/ + trim_filepath(input_dir_path); diff --git a/SOURCES/libcgroup-0.40.rc1-fread.patch b/SOURCES/libcgroup-0.40.rc1-fread.patch new file mode 100644 index 0000000..acc7eba --- /dev/null +++ b/SOURCES/libcgroup-0.40.rc1-fread.patch @@ -0,0 +1,49 @@ +diff -up libcgroup-0.41/src/api.c.fread libcgroup-0.41/src/api.c +--- libcgroup-0.41/src/api.c.fread 2014-01-13 21:01:32.067067615 +0100 ++++ libcgroup-0.41/src/api.c 2014-01-13 21:01:32.070067594 +0100 +@@ -2232,29 +2232,29 @@ static int cg_rd_ctrl_file(const char *s + const char *file, char **value) + { + char path[FILENAME_MAX]; +- FILE *ctrl_file = NULL; +- int ret; ++ int ctrl_file = -1; ++ ssize_t ret; + + if (!cg_build_path_locked(cgroup, path, subsys)) + return ECGFAIL; + + strncat(path, file, sizeof(path) - strlen(path)); +- ctrl_file = fopen(path, "re"); +- if (!ctrl_file) ++ ctrl_file = open(path, O_RDONLY | O_CLOEXEC); ++ if (ctrl_file < 0) + return ECGROUPVALUENOTEXIST; + + *value = calloc(CG_VALUE_MAX, 1); + if (!*value) { +- fclose(ctrl_file); ++ close(ctrl_file); + last_errno = errno; + return ECGOTHER; + } + + /* +- * using %as crashes when we try to read from files like ++ * using %as or fread crashes when we try to read from files like + * memory.stat + */ +- ret = fread(*value, 1, CG_VALUE_MAX-1, ctrl_file); ++ ret = read(ctrl_file, *value, CG_VALUE_MAX-1); + if (ret < 0) { + free(*value); + *value = NULL; +@@ -2264,7 +2264,7 @@ static int cg_rd_ctrl_file(const char *s + (*value)[ret-1] = '\0'; + } + +- fclose(ctrl_file); ++ close(ctrl_file); + + return 0; + } diff --git a/SOURCES/libcgroup-0.40.rc1-templates-fix.patch b/SOURCES/libcgroup-0.40.rc1-templates-fix.patch new file mode 100644 index 0000000..50e9aea --- /dev/null +++ b/SOURCES/libcgroup-0.40.rc1-templates-fix.patch @@ -0,0 +1,16 @@ +diff -up libcgroup-0.41/src/api.c.templates-fix libcgroup-0.41/src/api.c +--- libcgroup-0.41/src/api.c.templates-fix 2014-01-13 21:04:36.933747000 +0100 ++++ libcgroup-0.41/src/api.c 2014-01-13 21:16:44.478580105 +0100 +@@ -2974,10 +2974,10 @@ int cgroup_change_cgroup_flags(uid_t uid + available, "%d", pid); + break; + case 'p': +- if(procname) { ++ if(procname && strlen(basename(procname))) { + written = snprintf(newdest + j, + available, "%s", +- procname); ++ basename(procname)); + } else { + written = snprintf(newdest + j, + available, "%d", pid); diff --git a/SOURCES/libcgroup-0.41-CVE-2018-14348.patch b/SOURCES/libcgroup-0.41-CVE-2018-14348.patch new file mode 100644 index 0000000..ac33cff --- /dev/null +++ b/SOURCES/libcgroup-0.41-CVE-2018-14348.patch @@ -0,0 +1,33 @@ +From 9ed289ca9c792f525cf54e694b1b641300c000e6 Mon Sep 17 00:00:00 2001 +From: Michal Hocko +Date: Wed, 18 Jul 2018 11:24:29 +0200 +Subject: [PATCH] cgrulesengd: remove umask(0) + +One of our partners has noticed that cgred daemon is creating a log file +(/var/log/cgred) with too wide permissions (0666) and that is seen as +a security bug because an untrusted user can write to otherwise +restricted area. CVE-2018-14348 has been assigned to this issue. + +Signed-off-by: Michal Hocko +Acked-by: Balbir Singh +--- + src/daemon/cgrulesengd.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c +index 170837a..41aadd4 100644 +--- a/src/daemon/cgrulesengd.c ++++ b/src/daemon/cgrulesengd.c +@@ -885,9 +885,6 @@ int cgre_start_daemon(const char *logp, const int logf, + } else if (pid > 0) { + exit(EXIT_SUCCESS); + } +- +- /* Change the file mode mask. */ +- umask(0); + } else { + flog(LOG_DEBUG, "Not using daemon mode\n"); + pid = getpid(); +-- +2.17.1 + diff --git a/SOURCES/libcgroup-0.41-api.c-fix-order-of-memory-subsystem-parameters.patch b/SOURCES/libcgroup-0.41-api.c-fix-order-of-memory-subsystem-parameters.patch new file mode 100644 index 0000000..9700530 --- /dev/null +++ b/SOURCES/libcgroup-0.41-api.c-fix-order-of-memory-subsystem-parameters.patch @@ -0,0 +1,66 @@ +From 72a9e0c3d4f8daca9f7dc389edbc1013d7c0d808 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Fri, 8 Apr 2016 17:00:19 +0200 +Subject: [PATCH] api.c: fix order of memory subsystem parameters generated by + cgsnapshot +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Order of parameters usually doesn't matter, but that's not the case with +memory.limit_in_bytes and memory.memsw.limit_in_bytes. When the latter +is first in the list of parameters, the resulting configuration is not +loadable with cgconfigparser. + +This happens because when a cgroup is created, both memory.limit_in_bytes +and memory.memsw.limit_in_bytes parameters are initialized to highest +value possible (RESOURCE_MAX). And because memory.memsw.limit_in_bytes +must be always higher or equal to memory.limit_in_bytes, it's impossible +to change its value first. + +Make sure that after constructing parameter list of memory subsystem, +the mentioned parameters are in correct order. + +Signed-off-by: Nikola Forró +--- + src/api.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/src/api.c b/src/api.c +index 0bf0615..f5da553 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -2651,6 +2651,30 @@ int cgroup_get_cgroup(struct cgroup *cgroup) + } + } + closedir(dir); ++ ++ if (! strcmp(cgc->name, "memory")) { ++ /* ++ * Make sure that memory.limit_in_bytes is placed before ++ * memory.memsw.limit_in_bytes in the list of values ++ */ ++ int memsw_limit = -1; ++ int mem_limit = -1; ++ ++ for (j = 0; j < cgc->index; j++) { ++ if (! strcmp(cgc->values[j]->name, ++ "memory.memsw.limit_in_bytes")) ++ memsw_limit = j; ++ else if (! strcmp(cgc->values[j]->name, ++ "memory.limit_in_bytes")) ++ mem_limit = j; ++ } ++ ++ if (memsw_limit >= 0 && memsw_limit < mem_limit) { ++ struct control_value *val = cgc->values[memsw_limit]; ++ cgc->values[memsw_limit] = cgc->values[mem_limit]; ++ cgc->values[mem_limit] = val; ++ } ++ } + } + + /* Check if the group really exists or not */ +-- +2.4.11 + diff --git a/SOURCES/libcgroup-0.41-api.c-preserve-dirty-flag.patch b/SOURCES/libcgroup-0.41-api.c-preserve-dirty-flag.patch new file mode 100644 index 0000000..0836334 --- /dev/null +++ b/SOURCES/libcgroup-0.41-api.c-preserve-dirty-flag.patch @@ -0,0 +1,33 @@ +From ad27a46d8c0e180f71b4606d7b2a3bd3bebd7bbf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Thu, 13 Oct 2016 13:42:30 +0200 +Subject: [PATCH] api.c: preserve dirty flag when copying controller values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When setting cgroup parameters with cgset fails, no error is reported. +This is caused by the fact that cgroup_copy_controller_values is not +preserving dirty flags of the values, so it's making all errors +considered non-fatal. + +Signed-off-by: Nikola Forró +--- + src/api.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/api.c b/src/api.c +index 0bf0615..daf4ef0 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -1687,6 +1687,7 @@ static int cgroup_copy_controller_values(struct cgroup_controller *dst, + dst_val = dst->values[i]; + strncpy(dst_val->value, src_val->value, CG_VALUE_MAX); + strncpy(dst_val->name, src_val->name, FILENAME_MAX); ++ dst_val->dirty = src_val->dirty; + } + err: + return ret; +-- +2.7.4 + diff --git a/SOURCES/libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch b/SOURCES/libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch new file mode 100644 index 0000000..fba6b9b --- /dev/null +++ b/SOURCES/libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch @@ -0,0 +1,150 @@ +From 691430206f1104b752b0e52386f317e639137788 Mon Sep 17 00:00:00 2001 +From: Jan Chaloupka +Date: Mon, 15 Sep 2014 13:29:39 +0200 +Subject: [PATCH] api.c: support for setting multiline values in control files + +As of now, libcgroup does not support multiline values setting from configuration files. i.e. values in a form: + +net_prio.ifpriomap="lo 7 +eth0 66 +eth1 5 +eth2 4 +eth3 3"; + +Thus, setting of more network interfaces can not be done from configuration file. Or + +devices.allow="a *:* w +c 8:* r"; + +thus setting list of allow devices can not be set as well. The only way is to set it from userspace, e.g.: +# echo "lo 7" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap +# echo "eth 0" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap +# echo "eth 1" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap +# echo "eth 2" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap +# echo "eth 3" > /sys/fs/cgroup/net_prio/testGroup/net_prio.ifpriomap + +This patch allows setting of multiline variables. + +How this support works: +Multiline value is broken in lines and each line is set by write (man 2 write) syscall (without bufferring). +This implies change of fopen with open, fclose with close. +There is no control on multiline value, thus "eth0\n \t\n" can be set. However, setting +of " \t" will fail as write command returns -1. Thus administrator has to set correct +multiline values. + +Tested on virtual machine with fedora and rhel with network interface lo, eth0-eth3. Configuration file: + +# cat /etc/cgconfig.conf +group testGroup { + net_prio { + net_prio.ifpriomap="lo 7 +eth0 66 +eth1 5 +eth2 4 +eth3 3"; + } +} + +net_prio has to be created before: +# modprobe netprio_cgroup +# mkdir /sys/fs/cgroup/net_prio +# mount -t cgroup -onet_prio none /sys/fs/cgroup/net_prio + +Changelog: + test of success of strdup call + free str_val before return (str_val is changing in while cycle, + thus str_start_val points to the start of str_val before while) + +Signed-off-by: Jan Chaloupka +--- + src/api.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 44 insertions(+), 6 deletions(-) + +diff --git a/src/api.c b/src/api.c +index 5751b8f..d6c9d3a 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -1495,13 +1495,18 @@ static int cg_create_control_group(const char *path) + */ + static int cg_set_control_value(char *path, const char *val) + { +- FILE *control_file = NULL; ++ int ctl_file; ++ char *str_val; ++ char *str_val_start; ++ char *pos; ++ size_t len; ++ + if (!cg_test_mounted_fs()) + return ECGROUPNOTMOUNTED; + +- control_file = fopen(path, "r+e"); ++ ctl_file = open(path, O_RDWR | O_CLOEXEC); + +- if (!control_file) { ++ if (ctl_file == -1) { + if (errno == EPERM) { + /* + * We need to set the correct error value, does the +@@ -1512,6 +1517,7 @@ static int cg_set_control_value(char *path, const char *val) + */ + char *path_dir_end; + char *tasks_path; ++ FILE *control_file; + + path_dir_end = strrchr(path, '/'); + if (path_dir_end == NULL) +@@ -1543,15 +1549,47 @@ static int cg_set_control_value(char *path, const char *val) + return ECGROUPVALUENOTEXIST; + } + +- if (fprintf(control_file, "%s", val) < 0) { ++ /* Split the multiline value into lines. */ ++ /* One line is a special case of multiline value. */ ++ str_val = strdup(val); ++ if (str_val == NULL) { + last_errno = errno; +- fclose(control_file); ++ close(ctl_file); + return ECGOTHER; + } +- if (fclose(control_file) < 0) { ++ ++ str_val_start = str_val; ++ pos = str_val; ++ ++ do { ++ str_val = pos; ++ pos = strchr(str_val, '\n'); ++ ++ if (pos) { ++ *pos = '\0'; ++ ++pos; ++ } ++ ++ len = strlen(str_val); ++ if (len > 0) { ++ if (write(ctl_file, str_val, len) == -1) { ++ last_errno = errno; ++ free(str_val_start); ++ close(ctl_file); ++ return ECGOTHER; ++ } ++ } else ++ cgroup_warn("Warning: skipping empty line for %s\n", ++ path); ++ } while(pos); ++ ++ if (close(ctl_file)) { + last_errno = errno; ++ free(str_val_start); + return ECGOTHER; + } ++ ++ free(str_val_start); + return 0; + } + +-- +1.9.3 + diff --git a/SOURCES/libcgroup-0.41-change-cgroup-of-threads.patch b/SOURCES/libcgroup-0.41-change-cgroup-of-threads.patch new file mode 100644 index 0000000..05f009a --- /dev/null +++ b/SOURCES/libcgroup-0.41-change-cgroup-of-threads.patch @@ -0,0 +1,74 @@ +From c9d651cfd532da6494dab03190c0a207cdf7289c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Mon, 23 Jul 2018 17:38:26 +0200 +Subject: [PATCH] api.c: always move all tasks of a process to a cgroup + +--- + src/api.c | 40 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 38 insertions(+), 2 deletions(-) + +diff --git a/src/api.c b/src/api.c +index 803ff35..a2cf981 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -3180,7 +3180,12 @@ int cgroup_change_cgroup_path(const char *dest, pid_t pid, + const char *const controllers[]) + { + int ret; ++ int nr; + struct cgroup cgroup; ++ DIR *dir; ++ struct dirent *task_dir = NULL; ++ char path[FILENAME_MAX]; ++ pid_t tid; + + if (!cgroup_initialized) { + cgroup_warn("Warning: libcgroup is not initialized\n"); +@@ -3191,11 +3196,42 @@ int cgroup_change_cgroup_path(const char *dest, pid_t pid, + ret = cg_prepare_cgroup(&cgroup, pid, dest, controllers); + if (ret) + return ret; +- /* Add task to cgroup */ ++ /* Add process to cgroup */ + ret = cgroup_attach_task_pid(&cgroup, pid); +- if (ret) ++ if (ret) { + cgroup_warn("Warning: cgroup_attach_task_pid failed: %d\n", + ret); ++ goto finished; ++ } ++ ++ /* Add all threads to cgroup */ ++ snprintf(path, FILENAME_MAX, "/proc/%d/task/", pid); ++ dir = opendir(path); ++ if (!dir) { ++ last_errno = errno; ++ ret = ECGOTHER; ++ goto finished; ++ } ++ ++ while ((task_dir = readdir(dir)) != NULL) { ++ nr = sscanf(task_dir->d_name, "%i", &tid); ++ if (nr < 1) ++ continue; ++ ++ if (tid == pid) ++ continue; ++ ++ ret = cgroup_attach_task_pid(&cgroup, tid); ++ if (ret) { ++ cgroup_warn("Warning: cgroup_attach_task_pid failed: %d\n", ++ ret); ++ break; ++ } ++ } ++ ++ closedir(dir); ++ ++finished: + cgroup_free_controllers(&cgroup); + return ret; + } +-- +2.17.1 + diff --git a/SOURCES/libcgroup-0.41-coverity.patch b/SOURCES/libcgroup-0.41-coverity.patch new file mode 100644 index 0000000..3137356 --- /dev/null +++ b/SOURCES/libcgroup-0.41-coverity.patch @@ -0,0 +1,167 @@ +diff --git a/src/api.c b/src/api.c +index 1cd30df..93d0750 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -3642,14 +3642,14 @@ static int cg_read_stat(FILE *fp, struct cgroup_stat *cgroup_stat) + ret = ECGINVAL; + goto out_free; + } +- strncpy(cgroup_stat->name, token, FILENAME_MAX); ++ strncpy(cgroup_stat->name, token, FILENAME_MAX - 1); + + token = strtok_r(NULL, " ", &saveptr); + if (!token) { + ret = ECGINVAL; + goto out_free; + } +- strncpy(cgroup_stat->value, token, CG_VALUE_MAX); ++ strncpy(cgroup_stat->value, token, CG_VALUE_MAX - 1); + + out_free: + free(line); +@@ -3906,9 +3906,9 @@ int cgroup_get_controller_next(void **handle, struct cgroup_mount_point *info) + goto out_unlock; + } + +- strncpy(info->name, cg_mount_table[*pos].name, FILENAME_MAX); ++ strncpy(info->name, cg_mount_table[*pos].name, FILENAME_MAX - 1); + +- strncpy(info->path, cg_mount_table[*pos].mount.path, FILENAME_MAX); ++ strncpy(info->path, cg_mount_table[*pos].mount.path, FILENAME_MAX - 1); + + (*pos)++; + *handle = pos; +diff --git a/src/config.c b/src/config.c +index e1ee0a8..c3004eb 100644 +--- a/src/config.c ++++ b/src/config.c +@@ -168,7 +168,7 @@ int config_insert_cgroup(char *cg_name, int flag) + } + + config_cgroup = &config_table[*table_index]; +- strncpy(config_cgroup->name, cg_name, FILENAME_MAX); ++ strncpy(config_cgroup->name, cg_name, FILENAME_MAX - 1); + + /* + * Since this will be the last part to be parsed. +@@ -1583,7 +1583,7 @@ int cgroup_config_create_template_group(struct cgroup *cgroup, + int i, j, k; + struct cgroup *t_cgroup; + char buffer[FILENAME_MAX]; +- struct cgroup *aux_cgroup; ++ struct cgroup *aux_cgroup = NULL; + struct cgroup_controller *cgc; + int found; + +@@ -1659,7 +1659,7 @@ int cgroup_config_create_template_group(struct cgroup *cgroup, + /* no template is present for given name x controller pair + * add controller to result cgroup */ + aux_cgroup = cgroup_new_cgroup(cgroup->name); +- if (aux_cgroup) { ++ if (aux_cgroup == NULL) { + ret = ECGINVAL; + fprintf(stderr, "cgroup %s can't be created\n", + cgroup->name); +@@ -1683,5 +1683,6 @@ int cgroup_config_create_template_group(struct cgroup *cgroup, + } + + end: ++ cgroup_free(&aux_cgroup); + return ret; + } +diff --git a/src/tools/cgsnapshot.c b/src/tools/cgsnapshot.c +index a0599c1..66e3bbc 100644 +--- a/src/tools/cgsnapshot.c ++++ b/src/tools/cgsnapshot.c +@@ -428,6 +428,7 @@ static int display_cgroup_data(struct cgroup *group, + goto err; + } + fprintf(of, "\t\t%s=\"%s\";\n", output_name, value); ++ free(value); + } + fprintf(of, "\t}\n"); + } +diff --git a/src/wrapper.c b/src/wrapper.c +index 0952823..599128f 100644 +--- a/src/wrapper.c ++++ b/src/wrapper.c +@@ -48,7 +48,7 @@ struct cgroup *cgroup_new_cgroup(const char *name) + return NULL; + + init_cgroup(cgroup); +- strncpy(cgroup->name, name, sizeof(cgroup->name)); ++ strncpy(cgroup->name, name, sizeof(cgroup->name) - 1); + + return cgroup; + } +@@ -82,7 +82,7 @@ struct cgroup_controller *cgroup_add_controller(struct cgroup *cgroup, + if (!controller) + return NULL; + +- strncpy(controller->name, name, sizeof(controller->name)); ++ strncpy(controller->name, name, sizeof(controller->name) - 1); + controller->cgroup = cgroup; + controller->index = 0; + +@@ -560,7 +560,7 @@ struct cgroup *create_cgroup_from_name_value_pairs(const char *name, + goto scgroup_err; + } + +- strncpy(con, name_value[i].name, FILENAME_MAX); ++ strncpy(con, name_value[i].name, FILENAME_MAX - 1); + strtok(con, "."); + + /* find out whether we have to add the controller or +diff --git a/tests/libcgrouptest01.c b/tests/libcgrouptest01.c +index acc229a..d7770a0 100644 +--- a/tests/libcgrouptest01.c ++++ b/tests/libcgrouptest01.c +@@ -60,11 +60,11 @@ int main(int argc, char *argv[]) + if (fs_mounted) { + ctl1 = atoi(argv[2]); + ctl2 = atoi(argv[3]); +- strncpy(mountpoint, argv[4], sizeof(mountpoint)); ++ strncpy(mountpoint, argv[4], sizeof(mountpoint) - 1); + cgroup_dbg("C:DBG: mountpoint1 as recieved from script=%s\n", + mountpoint); + if (fs_mounted == FS_MULTI_MOUNTED) { +- strncpy(mountpoint2, argv[5], sizeof(mountpoint2)); ++ strncpy(mountpoint2, argv[5], sizeof(mountpoint2) - 1); + cgroup_dbg("C:DBG: mountpoint2 as recieved from " + "script=%s\n", mountpoint2); + } +diff --git a/tests/read_stats.c b/tests/read_stats.c +index a1bc244..0583039 100644 +--- a/tests/read_stats.c ++++ b/tests/read_stats.c +@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) + } + + root_len = strlen(info.full_path) - 1; +- strncpy(cgroup_path, info.path, FILENAME_MAX); ++ strncpy(cgroup_path, info.path, FILENAME_MAX - 1); + ret = read_stats(cgroup_path, controller); + if (ret < 0) + exit(EXIT_FAILURE); +@@ -72,7 +72,7 @@ int main(int argc, char *argv[]) + ECGEOF) { + if (info.type != CGROUP_FILE_TYPE_DIR) + continue; +- strncpy(cgroup_path, info.full_path + root_len, FILENAME_MAX); ++ strncpy(cgroup_path, info.full_path + root_len, FILENAME_MAX - 1); + strcat(cgroup_path, "/"); + ret = read_stats(cgroup_path, controller); + if (ret < 0) +diff --git a/tests/test_functions.c b/tests/test_functions.c +index 8f1d59e..f357ab2 100644 +--- a/tests/test_functions.c ++++ b/tests/test_functions.c +@@ -139,7 +139,7 @@ struct cgroup *create_new_cgroup_ds(int ctl, const char *grpname, + char group[FILENAME_MAX]; + char controller_name[FILENAME_MAX], control_file[FILENAME_MAX]; + +- strncpy(group, grpname, sizeof(group)); ++ strncpy(group, grpname, sizeof(group) - 1); + retval = set_controller(ctl, controller_name, control_file); + if (retval) { + fprintf(stderr, "Setting controller failled\n"); diff --git a/SOURCES/libcgroup-0.41-fix-infinite-loop.patch b/SOURCES/libcgroup-0.41-fix-infinite-loop.patch new file mode 100644 index 0000000..a41347b --- /dev/null +++ b/SOURCES/libcgroup-0.41-fix-infinite-loop.patch @@ -0,0 +1,40 @@ +From 62bab9d121d4fb416205f5ac53ad342184ae42b6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Tue, 8 Dec 2015 16:53:41 +0100 +Subject: [PATCH 2/6] api.c: fix infinite loop + +If getgrnam or getpwuid functions failed, the program entered +an infinite loop, because the rule pointer was never advanced. +This is now fixed by updating the pointer before continuing +to the next iteration. +--- + src/api.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/api.c b/src/api.c +index df90a6f..217d6c9 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -2664,13 +2664,17 @@ static struct cgroup_rule *cgroup_find_matching_rule_uid_gid(uid_t uid, + /* Get the group data. */ + sp = &(rule->username[1]); + grp = getgrnam(sp); +- if (!grp) ++ if (!grp) { ++ rule = rule->next; + continue; ++ } + + /* Get the data for UID. */ + usr = getpwuid(uid); +- if (!usr) ++ if (!usr) { ++ rule = rule->next; + continue; ++ } + + /* If UID is a member of group, we matched. */ + for (i = 0; grp->gr_mem[i]; i++) { +-- +2.17.0 + diff --git a/SOURCES/libcgroup-0.41-fix-log-level.patch b/SOURCES/libcgroup-0.41-fix-log-level.patch new file mode 100644 index 0000000..30055e3 --- /dev/null +++ b/SOURCES/libcgroup-0.41-fix-log-level.patch @@ -0,0 +1,38 @@ +From 7c99c167f41d3f8810808436d2ac58afc3a7d6c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Tue, 17 Apr 2018 13:33:03 +0200 +Subject: [PATCH 5/6] api.c: Fix level of failed user/group lookup warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Nikola Forró +--- + src/api.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/api.c b/src/api.c +index 51081b4..efde2d1 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -639,7 +639,7 @@ static int cgroup_parse_rules(bool cache, uid_t muid, + uid = CGRULE_INVALID; + gid = grp->gr_gid; + } else { +- cgroup_dbg("Warning: Entry for %s not" ++ cgroup_warn("Warning: Entry for %s not" + "found. Skipping rule on line" + " %d.\n", itr, linenum); + skipped = true; +@@ -656,7 +656,7 @@ static int cgroup_parse_rules(bool cache, uid_t muid, + uid = pwd->pw_uid; + gid = CGRULE_INVALID; + } else { +- cgroup_dbg("Warning: Entry for %s not" ++ cgroup_warn("Warning: Entry for %s not" + "found. Skipping rule on line" + " %d.\n", user, linenum); + skipped = true; +-- +2.17.0 + diff --git a/SOURCES/libcgroup-0.41-lex.patch b/SOURCES/libcgroup-0.41-lex.patch new file mode 100644 index 0000000..bcd536a --- /dev/null +++ b/SOURCES/libcgroup-0.41-lex.patch @@ -0,0 +1,25 @@ +From a8c2e967e74d280cd3b8554af0c95d823647d1c0 Mon Sep 17 00:00:00 2001 +From: Jan Chaloupka +Date: Thu, 6 Feb 2014 11:43:18 +0100 +Subject: [PATCH] lex updated, additional '\' char for ID token + +--- + libcgroup-0.41/src/lex.l | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libcgroup-0.41/src/lex.l b/libcgroup-0.41/src/lex.l +index 1b357db..d7bf575 100644 +--- a/libcgroup-0.41/src/lex.l ++++ b/libcgroup-0.41/src/lex.l +@@ -43,7 +43,7 @@ jmp_buf parser_error_env; + "namespace" {return NAMESPACE;} + "template" {return TEMPLATE;} + "default" {return DEFAULT;} +-[a-zA-Z0-9_\-\/\.\,\%\@]+ {yylval.name = strdup(yytext); return ID;} ++[a-zA-Z0-9_\-\/\.\,\%\@\\]+ {yylval.name = strdup(yytext); return ID;} + \"[^"]*\" {yylval.name = strdup(yytext+1); yylval.name[strlen(yylval.name)-1] = '\0'; return ID; } + . {return yytext[0];} + %% +-- +1.8.5.3 + diff --git a/SOURCES/libcgroup-0.41-prevent-buffer-overflow.patch b/SOURCES/libcgroup-0.41-prevent-buffer-overflow.patch new file mode 100644 index 0000000..d405159 --- /dev/null +++ b/SOURCES/libcgroup-0.41-prevent-buffer-overflow.patch @@ -0,0 +1,46 @@ +From 9c80e2cb4bca26993a12027c46a274bb43645630 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Wed, 22 Jun 2016 14:12:46 +0200 +Subject: [PATCH 3/6] api.c: fix potential buffer overflow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It is assumed that arguments read from /proc//cmdline don't exceed +buf_pname buffer size, which is FILENAME_MAX - 1 characters, but that's +not always the case. + +Add check to prevent buffer overflow and discard the excessive part of +an argument. + +Signed-off-by: Nikola Forró +--- + src/api.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/api.c b/src/api.c +index 217d6c9..4d98081 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -4065,13 +4065,17 @@ static int cg_get_procname_from_proc_cmdline(pid_t pid, + + while (c != EOF) { + c = fgetc(f); +- if ((c != EOF) && (c != '\0')) { ++ if ((c != EOF) && (c != '\0') && (len < FILENAME_MAX - 1)) { + buf_pname[len] = c; + len++; + continue; + } + buf_pname[len] = '\0'; + ++ if (len == FILENAME_MAX - 1) ++ while ((c != EOF) && (c != '\0')) ++ c = fgetc(f); ++ + /* + * The taken process name from /proc//status is + * shortened to 15 characters if it is over. So the +-- +2.17.0 + diff --git a/SOURCES/libcgroup-0.41-size-of-controller-values.patch b/SOURCES/libcgroup-0.41-size-of-controller-values.patch new file mode 100644 index 0000000..08aba87 --- /dev/null +++ b/SOURCES/libcgroup-0.41-size-of-controller-values.patch @@ -0,0 +1,142 @@ +From 5a64a79144e58a62426a34ef51b14e891f042fa2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Tue, 17 Apr 2018 13:54:38 +0200 +Subject: [PATCH 6/6] Increase maximal size of controller values +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Maximal length of a controller value is determined by CG_VALUE_MAX, +which is equal to 100. That is not sufficient in some cases. + +Add new constant CG_CONTROL_VALUE_MAX (to prevent breaking current API) +and set it to 4096, which is usually equal to the amount of bytes that +can be written to a sysctl file directly. + +Add warning message about exceeding the limit while parsing +configuration file. + +Signed-off-by: Nikola Forró +--- + src/api.c | 6 +++--- + src/libcgroup-internal.h | 5 ++++- + src/tools/cgset.c | 4 ++-- + src/wrapper.c | 17 ++++++++++++----- + 4 files changed, 21 insertions(+), 11 deletions(-) + +diff --git a/src/api.c b/src/api.c +index efde2d1..1cd30df 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -1561,7 +1561,7 @@ static int cgroup_copy_controller_values(struct cgroup_controller *dst, + } + + dst_val = dst->values[i]; +- strncpy(dst_val->value, src_val->value, CG_VALUE_MAX); ++ strncpy(dst_val->value, src_val->value, CG_CONTROL_VALUE_MAX); + strncpy(dst_val->name, src_val->name, FILENAME_MAX); + dst_val->dirty = src_val->dirty; + } +@@ -2286,7 +2286,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup, + if (ctrl_file < 0) + return ECGROUPVALUENOTEXIST; + +- *value = calloc(CG_VALUE_MAX, 1); ++ *value = calloc(CG_CONTROL_VALUE_MAX, 1); + if (!*value) { + close(ctrl_file); + last_errno = errno; +@@ -2297,7 +2297,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup, + * using %as or fread crashes when we try to read from files like + * memory.stat + */ +- ret = read(ctrl_file, *value, CG_VALUE_MAX-1); ++ ret = read(ctrl_file, *value, CG_CONTROL_VALUE_MAX-1); + if (ret < 0) { + free(*value); + *value = NULL; +diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h +index 4c0f46c..3a8e336 100644 +--- a/src/libcgroup-internal.h ++++ b/src/libcgroup-internal.h +@@ -32,6 +32,9 @@ __BEGIN_DECLS + /* Estimated number of groups created */ + #define MAX_GROUP_ELEMENTS 128 + ++/* Maximum length of a value */ ++#define CG_CONTROL_VALUE_MAX 4096 ++ + #define CG_NV_MAX 100 + #define CG_CONTROLLER_MAX 100 + /* Max number of mounted hierarchies. Event if one controller is mounted per +@@ -73,7 +76,7 @@ __BEGIN_DECLS + + struct control_value { + char name[FILENAME_MAX]; +- char value[CG_VALUE_MAX]; ++ char value[CG_CONTROL_VALUE_MAX]; + bool dirty; + }; + +diff --git a/src/tools/cgset.c b/src/tools/cgset.c +index ea9f90d..3d3c8cc 100644 +--- a/src/tools/cgset.c ++++ b/src/tools/cgset.c +@@ -151,8 +151,8 @@ int main(int argc, char *argv[]) + goto err; + } + +- strncpy(name_value[nv_number].value, buf, CG_VALUE_MAX); +- name_value[nv_number].value[CG_VALUE_MAX-1] = '\0'; ++ strncpy(name_value[nv_number].value, buf, CG_CONTROL_VALUE_MAX); ++ name_value[nv_number].value[CG_CONTROL_VALUE_MAX-1] = '\0'; + + nv_number++; + break; +diff --git a/src/wrapper.c b/src/wrapper.c +index c03472a..0952823 100644 +--- a/src/wrapper.c ++++ b/src/wrapper.c +@@ -132,10 +132,10 @@ int cgroup_add_value_string(struct cgroup_controller *controller, + if (!controller) + return ECGINVAL; + +- if (controller->index >= CG_VALUE_MAX) ++ if (controller->index >= CG_NV_MAX) + return ECGMAXVALUESEXCEEDED; + +- for (i = 0; i < controller->index && i < CG_VALUE_MAX; i++) { ++ for (i = 0; i < controller->index && i < CG_NV_MAX; i++) { + if (!strcmp(controller->values[i]->name, name)) + return ECGVALUEEXISTS; + } +@@ -145,8 +145,15 @@ int cgroup_add_value_string(struct cgroup_controller *controller, + if (!cntl_value) + return ECGCONTROLLERCREATEFAILED; + +- strncpy(cntl_value->name, name, sizeof(cntl_value->name)); +- strncpy(cntl_value->value, value, sizeof(cntl_value->value)); ++ if (strlen(value) >= sizeof(cntl_value->value)) { ++ fprintf(stderr, "value exceeds the maximum of %d characters\n", ++ sizeof(cntl_value->value)); ++ free(cntl_value); ++ return ECGCONFIGPARSEFAIL; ++ } ++ ++ strncpy(cntl_value->name, name, sizeof(cntl_value->name) - 1); ++ strncpy(cntl_value->value, value, sizeof(cntl_value->value) - 1); + cntl_value->dirty = true; + controller->values[controller->index] = cntl_value; + controller->index++; +@@ -356,7 +363,7 @@ int cgroup_set_value_string(struct cgroup_controller *controller, + for (i = 0; i < controller->index; i++) { + struct control_value *val = controller->values[i]; + if (!strcmp(val->name, name)) { +- strncpy(val->value, value, CG_VALUE_MAX); ++ strncpy(val->value, value, CG_CONTROL_VALUE_MAX - 1); + val->dirty = true; + return 0; + } +-- +2.17.0 + diff --git a/SOURCES/libcgroup-0.41-tasks-file-warning.patch b/SOURCES/libcgroup-0.41-tasks-file-warning.patch new file mode 100644 index 0000000..e094613 --- /dev/null +++ b/SOURCES/libcgroup-0.41-tasks-file-warning.patch @@ -0,0 +1,49 @@ +From 437b68f34c459d136c806e61dafb5825d2f97170 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nikola=20Forr=C3=B3?= +Date: Tue, 17 Apr 2018 13:32:28 +0200 +Subject: [PATCH 4/6] api.c: Show warning when tasks file can not be opened +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Nikola Forró +--- + src/api.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/api.c b/src/api.c +index 4d98081..51081b4 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -1190,12 +1190,15 @@ static int __cgroup_attach_task_pid(char *path, pid_t tid) + if (!tasks) { + switch (errno) { + case EPERM: +- return ECGROUPNOTOWNER; ++ ret = ECGROUPNOTOWNER; ++ break; + case ENOENT: +- return ECGROUPNOTEXIST; ++ ret = ECGROUPNOTEXIST; ++ break; + default: +- return ECGROUPNOTALLOWED; ++ ret = ECGROUPNOTALLOWED; + } ++ goto err; + } + ret = fprintf(tasks, "%d", tid); + if (ret < 0) { +@@ -1214,7 +1217,8 @@ static int __cgroup_attach_task_pid(char *path, pid_t tid) + err: + cgroup_warn("Warning: cannot write tid %d to %s:%s\n", + tid, path, strerror(errno)); +- fclose(tasks); ++ if (tasks) ++ fclose(tasks); + return ret; + } + +-- +2.17.0 + diff --git a/SPECS/libcgroup.spec b/SPECS/libcgroup.spec new file mode 100644 index 0000000..545e317 --- /dev/null +++ b/SPECS/libcgroup.spec @@ -0,0 +1,383 @@ +%global soversion_major 1 +%global soversion 1.0.41 +%global _hardened_build 1 + +Summary: Library to control and monitor control groups +Name: libcgroup +Version: 0.41 +Release: 19%{?dist} +License: LGPLv2+ +Group: Development/Libraries +URL: http://libcg.sourceforge.net/ +Source0: http://downloads.sourceforge.net/libcg/%{name}-%{version}.tar.bz2 +Source1: cgconfig.service + +Patch0: fedora-config.patch +Patch1: libcgroup-0.37-chmod.patch +Patch2: libcgroup-0.40.rc1-coverity.patch +Patch3: libcgroup-0.40.rc1-fread.patch +Patch4: libcgroup-0.40.rc1-templates-fix.patch +Patch5: libcgroup-0.41-lex.patch +Patch6: libcgroup-0.41-api.c-support-for-setting-multiline-values-in-contro.patch +# resolves #1348874 +Patch7: libcgroup-0.41-api.c-fix-order-of-memory-subsystem-parameters.patch +# resolves #1384504 +Patch8: libcgroup-0.41-api.c-preserve-dirty-flag.patch +Patch9: libcgroup-0.41-change-cgroup-of-threads.patch +Patch10: libcgroup-0.41-fix-infinite-loop.patch +Patch11: libcgroup-0.41-prevent-buffer-overflow.patch +Patch12: libcgroup-0.41-tasks-file-warning.patch +Patch13: libcgroup-0.41-fix-log-level.patch +Patch14: libcgroup-0.41-size-of-controller-values.patch +Patch15: libcgroup-0.41-CVE-2018-14348.patch +Patch16: libcgroup-0.41-coverity.patch + +BuildRequires: gcc, gcc-c++ +BuildRequires: byacc, coreutils, flex, pam-devel, systemd-units +Requires(pre): shadow-utils +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd + +%description +Control groups infrastructure. The library helps manipulate, control, +administrate and monitor control groups and the associated controllers. + +%package tools +Summary: Command-line utility programs, services and daemons for libcgroup +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{version}-%{release} +# needed for Delegate property in cgconfig.service +Requires: systemd >= 217-0.2 + +%description tools +This package contains command-line programs, services and a daemon for +manipulating control groups using the libcgroup library. + +%package pam +Summary: A Pluggable Authentication Module for libcgroup +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description pam +Linux-PAM module, which allows administrators to classify the user's login +processes to pre-configured control group. + +%package devel +Summary: Development libraries to develop applications that utilize control groups +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +It provides API to create/delete and modify cgroup nodes. It will also in the +future allow creation of persistent configuration for control groups and +provide scripts to manage that configuration. + +%prep +%setup -q -n %{name}-%{version} +%patch0 -p1 -b .config-patch +%patch1 -p1 -b .chmod +%patch2 -p1 -b .coverity +%patch3 -p1 -b .fread +%patch4 -p1 -b .templates-fix +%patch5 -p2 -b .lex +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 + +%build +%configure --enable-pam-module-dir=%{_libdir}/security \ + --enable-opaque-hierarchy="name=systemd" \ + --disable-daemon +make %{?_smp_mflags} + +%install +make DESTDIR=$RPM_BUILD_ROOT install + +# install config files +install -d ${RPM_BUILD_ROOT}%{_sysconfdir} +install -m 644 samples/cgconfig.conf $RPM_BUILD_ROOT/%{_sysconfdir}/cgconfig.conf +install -m 644 samples/cgsnapshot_blacklist.conf $RPM_BUILD_ROOT/%{_sysconfdir}/cgsnapshot_blacklist.conf + +# sanitize pam module, we need only pam_cgroup.so +mv -f $RPM_BUILD_ROOT%{_libdir}/security/pam_cgroup.so.*.*.* $RPM_BUILD_ROOT%{_libdir}/security/pam_cgroup.so +rm -f $RPM_BUILD_ROOT%{_libdir}/security/pam_cgroup.la $RPM_BUILD_ROOT/%{_libdir}/security/pam_cgroup.so.* + +rm -f $RPM_BUILD_ROOT/%{_libdir}/*.la + +rm -f $RPM_BUILD_ROOT/%{_mandir}/man5/cgred.conf.5* +rm -f $RPM_BUILD_ROOT/%{_mandir}/man5/cgrules.conf.5* +rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/cgrulesengd.8* + +# install unit and sysconfig files +install -d ${RPM_BUILD_ROOT}%{_unitdir} +install -m 644 %SOURCE1 ${RPM_BUILD_ROOT}%{_unitdir}/ +install -d ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig + +%pre +getent group cgred >/dev/null || groupadd -r cgred + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%post tools +%systemd_post cgconfig.service + +%preun tools +%systemd_preun cgconfig.service + +%postun tools +%systemd_postun_with_restart cgconfig.service + +%triggerun -- libcgroup < 0.38 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply cgconfig +# to migrate them to systemd targets +/usr/bin/systemd-sysv-convert --save cgconfig >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +/sbin/chkconfig --del cgconfig >/dev/null 2>&1 || : +/bin/systemctl try-restart cgconfig.service >/dev/null 2>&1 || : + +%files +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc README +%{_libdir}/libcgroup.so.* + +%files tools +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc README README_systemd +%config(noreplace) %{_sysconfdir}/cgconfig.conf +%config(noreplace) %{_sysconfdir}/cgsnapshot_blacklist.conf +/usr/bin/cgcreate +/usr/bin/cgget +/usr/bin/cgset +/usr/bin/cgdelete +/usr/bin/lscgroup +/usr/bin/lssubsys +/usr/sbin/cgconfigparser +/usr/sbin/cgclear +/usr/bin/cgsnapshot +%attr(2755, root, cgred) /usr/bin/cgexec +%attr(2755, root, cgred) /usr/bin/cgclassify +%attr(0644, root, root) %{_mandir}/man1/* +%attr(0644, root, root) %{_mandir}/man5/* +%attr(0644, root, root) %{_mandir}/man8/* +%{_unitdir}/cgconfig.service + +%files pam +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc README +%attr(0755,root,root) %{_libdir}/security/pam_cgroup.so + +%files devel +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc README +%{_includedir}/libcgroup.h +%{_includedir}/libcgroup/*.h +%{_libdir}/libcgroup.so +%{_libdir}/pkgconfig/libcgroup.pc + +%changelog +* Mon Oct 15 2018 Nikola Forró - 0.41-19 +- resolves: #1606973 + fix important Covscan defects + +* Thu Aug 02 2018 Nikola Forró - 0.41-18 +- resolves: #1611122 + fix CVE-2018-14348 + +* Tue Apr 17 2018 Nikola Forró - 0.41-17 +- backport several upstream fixes +- set Delegate property for cgconfig service to make sure complete + cgroup hierarchy is always created by systemd + +* Tue Feb 20 2018 Nikola Forró - 0.41-16 +- add missing gcc-c++ build dependency + +* Tue Feb 20 2018 Nikola Forró - 0.41-15 +- add missing gcc build dependency + +* Wed Feb 07 2018 Fedora Release Engineering - 0.41-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 0.41-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 0.41-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 0.41-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Oct 13 2016 Nikola Forró - 0.41-10 +- resolves: #1384504 + api.c: preserve dirty flag when copying controller values + +* Fri Jul 01 2016 Nikola Forró - 0.41-9 +- resolves: #1348874 + api.c: fix order of memory subsystem parameters generated by cgsnapshot + +* Thu Feb 04 2016 Fedora Release Engineering - 0.41-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 0.41-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Sep 23 2014 jchaloup - 0.41-6 +- resolves: #647107 + api.c: support for setting multiline values in control files + +* Sun Aug 17 2014 Fedora Release Engineering - 0.41-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 17 2014 Tom Callaway - 0.41-4 +- fix license handling + +* Sat Jun 07 2014 Fedora Release Engineering - 0.41-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Mar 03 2014 jchaloup - 0.41-2 +- lex.l update: add \ character into regexp for ID token + +* Tue Jan 14 2014 Peter Schiffer 0.41-1 +- resolves: #966008 + updated to 0.41 +- removed deprecated cgred service + please use Control Group Interface in Systemd instead + +* Sat Aug 03 2013 Fedora Release Engineering - 0.38-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu Jul 18 2013 Karsten Hopp 0.38-6 +- add BR: systemd-units + +* Tue Jul 09 2013 Karsten Hopp 0.38-5 +- bump release and rebuild to fix some dependencies on PPC + +* Thu Feb 14 2013 Fedora Release Engineering - 0.38-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Nov 23 2012 Peter Schiffer - 0.38-3 +- resolves: #850183 + scriptlets replaced with new systemd macros (thanks to vpavlin) +- cleaned .spec file + +* Thu Jul 19 2012 Fedora Release Engineering - 0.38-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Feb 20 2012 Jan Safranek 0.38-1 +- updated to 0.38 + +* Fri Feb 3 2012 Jan Safranek 0.38-0.rc1 +- updated to 0.38.rc1 + +* Fri Jan 13 2012 Fedora Release Engineering - 0.37.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon May 30 2011 Jan Safranek 0.37.1-4 +- fixed cgconfig service not to unmount stuff it did not mount +- added better sample cgconfig.conf file to reflect systemd + mounting all controllers during boot (#702111) + +* Wed May 25 2011 Ivana Hutarova Varekova 0.37.1-3 +- split tools part from libcgroup package + +* Fri Apr 8 2011 Jan Safranek 0.37.1-2 +- Remove /cgroup directory, groups are created in /sys/fs/cgroup + (#694687) + +* Thu Mar 3 2011 Jan Safranek 0.37.1-1 +- Update to 0.37.1 + +* Mon Feb 07 2011 Fedora Release Engineering - 0.37-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 17 2011 Jan Safranek 0.37-2 +- Create the 'cgred' group as system group, not as user +- Fix cgclassify exit code + +* Mon Dec 13 2010 Jan Safranek 0.37-1 +- Update to 0.37 +- use /sys/fs/cgroup as default directory to mount control groups (and rely on + systemd mounting tmpfs there) + +* Fri Nov 12 2010 Jan Safranek 0.36.2-3 +- Ignore systemd hierarchy - it's now invisible to libcgroup (#627378) + +* Mon Aug 2 2010 Jan Safranek 0.36.2-2 +- Fix initscripts to report stopped cgconfig service as not running + (#619091) + +* Tue Jun 22 2010 Jan Safranek 0.36.2-1 +- Update to 0.36.2, fixing packaging the libraries (#605434) +- Remove the dependency on redhat-lsb (#603578) + +* Fri May 21 2010 Jan Safranek 0.36-1 +- Update to 0.36.1 + +* Tue Mar 9 2010 Jan Safranek 0.35-1 +- Update to 0.35.1 +- Separate pam module to its own subpackage + +* Mon Jan 18 2010 Jan Safranek 0.34-4 +- Added README.Fedora to describe initscript integration + +* Mon Oct 19 2009 Jan Safranek 0.34-3 +- Change the default configuration to mount everything to /cgroup + +* Fri Jul 24 2009 Fedora Release Engineering - 0.34-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 7 2009 Jan Safranek 0.34-1 +- Update to 0.34 +* Mon Mar 09 2009 Dhaval Giani 0.33-3 +- Add a workaround for rt cgroup controller. +* Mon Mar 09 2009 Dhaval Giani 0.33-2 +- Change the cgconfig script to start earlier +- Move the binaries to /bin and /sbin +* Mon Mar 02 2009 Dhaval Giani 0.33-1 +- Update to latest upstream +* Wed Feb 25 2009 Fedora Release Engineering 0.32.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Mon Jan 05 2009 Dhaval Giani 0.32.2-3 +- Fix redhat-lsb dependency +* Mon Dec 29 2008 Dhaval Giani 0.32.2-2 +- Fix build dependencies +* Mon Dec 29 2008 Dhaval Giani 0.32.2-1 +- Update to latest upstream +* Thu Oct 23 2008 Dhaval Giani 0.32.1-1 +* Tue Feb 24 2009 Balbir Singh 0.33-1 +- Update to 0.33, spec file changes to add Makefiles and pam_cgroup module +* Fri Oct 10 2008 Dhaval Giani 0.32-1 +- Update to latest upstream +* Thu Sep 11 2008 Dhaval Giani 0.31-1 +- Update to latest upstream +* Sat Aug 2 2008 Dhaval Giani 0.1c-3 +- Change release to fix broken upgrade path +* Wed Jun 11 2008 Dhaval Giani 0.1c-1 +- Update to latest upstream version +* Tue Jun 3 2008 Balbir Singh 0.1b-3 +- Add post and postun. Also fix Requires for devel to depend on base n-v-r +* Sat May 31 2008 Balbir Singh 0.1b-2 +- Fix makeinstall, Source0 and URL (review comments from Tom) +* Mon May 26 2008 Balbir Singh 0.1b-1 +- Add a generatable spec file +* Tue May 20 2008 Balbir Singh 0.1-1 +- Get the spec file to work +* Tue May 20 2008 Dhaval Giani 0.01-1 +- The first version of libcg