Package init

This commit is contained in:
dogsheng 2019-12-25 17:13:03 +08:00
parent cd37642fc9
commit c1223ca9f0
22 changed files with 1097 additions and 75 deletions

View File

@ -1,36 +0,0 @@
# libcgroup
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +0,0 @@
# libcgroup
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -0,0 +1,12 @@
diff -Nur libcgroup-0.41.org/configure libcgroup-0.41/configure
--- libcgroup-0.41.org/configure 2018-08-23 04:23:34.965000000 -0400
+++ libcgroup-0.41/configure 2018-08-23 04:24:16.706000000 -0400
@@ -4689,7 +4689,7 @@
fi
-for ac_prog in 'bison -y' byacc
+for ac_prog in byacc 'bison -y'
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2

18
cgconfig.service Normal file
View File

@ -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

13
config.patch Normal file
View File

@ -0,0 +1,13 @@
--- libcgroup-0.41/samples/cgconfig.sysconfig.orig 2019-12-19 11:25:25.547000000 +0800
+++ libcgroup-0.41/samples/cgconfig.sysconfig 2019-12-19 11:26:01.142000000 +0800
@@ -5,8 +5,5 @@
# 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=no

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -0,0 +1,33 @@
From 94e9dcead2e8bce00deeef08ea364ec6dc7e1f45 Mon Sep 17 00:00:00 2001
From: Michal Hocko <mhocko@suse.com>
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 <mhocko@suse.com>
Acked-by: Balbir Singh <bsingharora@gmail.com>
---
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

View File

@ -0,0 +1,66 @@
From 72a9e0c3d4f8daca9f7dc389edbc1013d7c0d808 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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ó <nforro@redhat.com>
---
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

View File

@ -0,0 +1,33 @@
From ad27a46d8c0e180f71b4606d7b2a3bd3bebd7bbf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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ó <nforro@redhat.com>
---
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

View File

@ -0,0 +1,150 @@
From 691430206f1104b752b0e52386f317e639137788 Mon Sep 17 00:00:00 2001
From: Jan Chaloupka <jchaloup@redhat.com>
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 <jchaloup@redhat.com>
---
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

View File

@ -0,0 +1,63 @@
From 647274d80d18686a3129a2b50605869ac5178ccf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
Date: Tue, 8 Dec 2015 17:09:08 +0100
Subject: [PATCH 1/6] api.c: change cgroup of every thread of a process
When changing cgroup of multi-threaded process, only the main threads
cgroup actually changed. Now all threads of a process are enumerated
and cgroup is changed for each of them.
---
src/api.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/api.c b/src/api.c
index 0cc15c6..df90a6f 100644
--- a/src/api.c
+++ b/src/api.c
@@ -3177,10 +3177,13 @@ int cgroup_change_all_cgroups(void)
return -ECGOTHER;
while ((pid_dir = readdir(dir)) != NULL) {
- int err, pid;
+ int err, pid, tid;
uid_t euid;
gid_t egid;
char *procname = NULL;
+ DIR *tdir;
+ struct dirent *tid_dir = NULL;
+ char tpath[FILENAME_MAX] = { '\0' };
err = sscanf(pid_dir->d_name, "%i", &pid);
if (err < 1)
@@ -3194,11 +3197,24 @@ int cgroup_change_all_cgroups(void)
if (err)
continue;
- err = cgroup_change_cgroup_flags(euid,
- egid, procname, pid, CGFLAG_USECACHE);
- if (err)
- cgroup_dbg("cgroup change pid %i failed\n", pid);
+ snprintf(tpath, FILENAME_MAX, "%s%d/task/", path, pid);
+
+ tdir = opendir(tpath);
+ if (!tdir)
+ continue;
+
+ while ((tid_dir = readdir(tdir)) != NULL) {
+ err = sscanf(tid_dir->d_name, "%i", &tid);
+ if (err < 1)
+ continue;
+
+ err = cgroup_change_cgroup_flags(euid,
+ egid, procname, tid, CGFLAG_USECACHE);
+ if (err)
+ cgroup_dbg("cgroup change tid %i failed\n", tid);
+ }
+ closedir(tdir);
free(procname);
}
--
2.17.0

View File

@ -0,0 +1,40 @@
From 62bab9d121d4fb416205f5ac53ad342184ae42b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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

View File

@ -0,0 +1,38 @@
From 7c99c167f41d3f8810808436d2ac58afc3a7d6c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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ó <nforro@redhat.com>
---
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

25
libcgroup-0.41-lex.patch Normal file
View File

@ -0,0 +1,25 @@
From a8c2e967e74d280cd3b8554af0c95d823647d1c0 Mon Sep 17 00:00:00 2001
From: Jan Chaloupka <jchaloup@redhat.com>
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

View File

@ -0,0 +1,46 @@
From 9c80e2cb4bca26993a12027c46a274bb43645630 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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/<pid>/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ó <nforro@redhat.com>
---
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/<pid>/status is
* shortened to 15 characters if it is over. So the
--
2.17.0

View File

@ -0,0 +1,142 @@
From 5a64a79144e58a62426a34ef51b14e891f042fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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ó <nforro@redhat.com>
---
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

View File

@ -0,0 +1,49 @@
From 437b68f34c459d136c806e61dafb5825d2f97170 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
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ó <nforro@redhat.com>
---
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

BIN
libcgroup-0.41.tar.bz2 Normal file

Binary file not shown.

174
libcgroup.spec Normal file
View File

@ -0,0 +1,174 @@
%global soversion_major 1
%global soversion 1.0.41
%global _hardened_build 1
Summary: Libcgroup is a library that abstracts the control group file system in Linux
Name: libcgroup
Version: 0.41
Release: 22
License: LGPLv2+
URL: http://libcg.sourceforge.net/
Source0: http://downloads.sourceforge.net/libcg/%{name}-%{version}.tar.bz2
Source1: cgconfig.service
Provides: libcgroup-pam libcgroup-tools
Obsoletes: libcgroup-pam libcgroup-tools
Patch0: 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
Patch7: libcgroup-0.41-api.c-fix-order-of-memory-subsystem-parameters.patch
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
Patch9000: bugfix-change-parser-match-order-fix-cgconfig-error.patch
BuildRequires: gcc,gcc-c++,byacc
BuildRequires: systemd-units,pam-devel,flex,coreutils
Requires: systemd >= 217-0.2
Requires(pre): shadow-utils
%description
Cgroups is a Linux kernel feature that limits, accounts for, and isolates
the resource usage (CPU, memory, disk I/O, network, etc.) of a collection of processes.
The library helps manipulte and administrate control groups.
%package devel
Summary: Devel helps applications to use cgroups
Requires: %{name}%{?_isa} = %{version}-%{release}
%description devel
Devel provides API for creating,deleting and modifying cgroup nodes.It allows
the creation of cgroups' configuration and provides scripts for managing it.
%package help
Summary: It provides helpful information for libcgroup
%description help
It provides helpful information for libcgroup-pam,libcgroup-devel,libcgroup-tools and libcgroup.
%prep
%setup -q -n %{name}-%{version}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p2
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch9000 -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
# config
install -d ${RPM_BUILD_ROOT}%{_sysconfdir}
install -d ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig
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
# Only one pam_cgroup.so is needed
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.so.*
rm -f $RPM_BUILD_ROOT%{_libdir}/security/pam_cgroup.la
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*
# unit and sysconfig
install -d ${RPM_BUILD_ROOT}%{_unitdir}
install -m 644 %SOURCE1 ${RPM_BUILD_ROOT}%{_unitdir}/
%pre
getent group cgred >/dev/null || groupadd -r cgred
%post
%systemd_post cgconfig.service
%preun
%systemd_preun cgconfig.service
%postun
%systemd_postun_with_restart cgconfig.service
%triggerun -- libcgroup < 0.38
/usr/bin/systemd-sysv-convert --save cgconfig >/dev/null 2>&1 ||:
/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
%{_libdir}/libcgroup.so.*
%config(noreplace) %{_sysconfdir}/cgsnapshot_blacklist.conf
%config(noreplace) %{_sysconfdir}/cgconfig.conf
/usr/bin/cgget
/usr/bin/cgset
/usr/bin/cgcreate
/usr/bin/cgdelete
/usr/bin/cgsnapshot
/usr/bin/lscgroup
/usr/bin/lssubsys
/usr/sbin/cgclear
/usr/sbin/cgconfigparser
%attr(2755, root, cgred) /usr/bin/cgexec
%attr(2755, root, cgred) /usr/bin/cgclassify
%attr(0755,root,root) %{_libdir}/security/pam_cgroup.so
%{_unitdir}/cgconfig.service
%files devel
%{!?_licensedir:%global license %%doc}
%license COPYING
%{_libdir}/libcgroup.so
%{_libdir}/pkgconfig/libcgroup.pc
%{_includedir}/libcgroup.h
%{_includedir}/libcgroup/*.h
%files help
%license COPYING
%doc README README_systemd
%attr(0644, root, root) %{_mandir}/man1/*
%attr(0644, root, root) %{_mandir}/man5/*
%attr(0644, root, root) %{_mandir}/man8/*
%changelog
* Thu Dec 19 2019 openEuler Buildteam <buildteam@openeuler.org> - 0.41-22
- Type:enhancement
- Id:NA
- SUG:NA
- DESC:modify the config patch
* Thu Nov 7 2019 openEuler Buildteam <buildteam@openeuler.org> - 0.41-21
- Type:enhancement
- Id:NA
- SUG:NA
- DESC:modify the release
* Tue Jan 22 2019 lunankun<lunankun@huawei.com> - 0.41-20.h1
- Type:bugfix
- ID:NA
- SUG:restart
- DESC:change parser match order fix cgconfig error.