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 <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
+
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?= <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
+
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?= <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
+
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 <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
+
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?= <nforro@redhat.com>
+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?= <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
+
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?= <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
+
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 <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
+
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?= <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
+
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?= <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
+
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?= <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
+
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ó <nforro@redhat.com> - 0.41-19
+- resolves: #1606973
+  fix important Covscan defects
+
+* Thu Aug 02 2018 Nikola Forró <nforro@redhat.com> - 0.41-18
+- resolves: #1611122
+  fix CVE-2018-14348
+
+* Tue Apr 17 2018 Nikola Forró <nforro@redhat.com> - 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ó <nforro@redhat.com> - 0.41-16
+- add missing gcc-c++ build dependency
+
+* Tue Feb 20 2018 Nikola Forró <nforro@redhat.com> - 0.41-15
+- add missing gcc build dependency
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.41-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.41-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.41-12
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.41-11
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Oct 13 2016 Nikola Forró <nforro@redhat.com> - 0.41-10
+- resolves: #1384504
+  api.c: preserve dirty flag when copying controller values
+
+* Fri Jul 01 2016 Nikola Forró <nforro@redhat.com> - 0.41-9
+- resolves: #1348874
+  api.c: fix order of memory subsystem parameters generated by cgsnapshot
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.41-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue Sep 23 2014 jchaloup <jchaloup@redhat.com> - 0.41-6
+- resolves: #647107
+  api.c: support for setting multiline values in control files
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Thu Jul 17 2014 Tom Callaway <spot@fedoraproject.org> - 0.41-4
+- fix license handling
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Mon Mar 03 2014 jchaloup <jchaloup@redhat.com> - 0.41-2
+- lex.l update: add \ character into regexp for ID token
+
+* Tue Jan 14 2014 Peter Schiffer <pschiffe@redhat.com> 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 <rel-eng@lists.fedoraproject.org> - 0.38-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Thu Jul 18 2013 Karsten Hopp <karsten@redhat.com> 0.38-6
+- add BR: systemd-units
+
+* Tue Jul 09 2013 Karsten Hopp <karsten@redhat.com> 0.38-5
+- bump release and rebuild to fix some dependencies on PPC
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.38-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Fri Nov 23 2012 Peter Schiffer <pschiffe@redhat.com> - 0.38-3
+- resolves: #850183
+  scriptlets replaced with new systemd macros (thanks to vpavlin)
+- cleaned .spec file
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.38-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Mon Feb 20 2012 Jan Safranek <jsafrane@redhat.com> 0.38-1
+- updated to 0.38
+
+* Fri Feb  3 2012 Jan Safranek <jsafrane@redhat.com> 0.38-0.rc1
+- updated to 0.38.rc1
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.37.1-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Mon May 30 2011 Jan Safranek <jsafrane@redhat.com> 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 <varekova@redhat.com> 0.37.1-3
+- split tools part from libcgroup package
+
+* Fri Apr  8 2011 Jan Safranek <jsafrane@redhat.com> 0.37.1-2
+- Remove /cgroup directory, groups are created in /sys/fs/cgroup
+  (#694687)
+
+* Thu Mar  3 2011 Jan Safranek <jsafrane@redhat.com> 0.37.1-1
+- Update to 0.37.1
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.37-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Jan 17 2011 Jan Safranek <jsafrane@redhat.com> 0.37-2
+- Create the 'cgred' group as system group, not as user
+- Fix cgclassify exit code
+
+* Mon Dec 13 2010 Jan Safranek <jsafrane@redhat.com> 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 <jsafrane@redhat.com> 0.36.2-3
+- Ignore systemd hierarchy - it's now invisible to libcgroup (#627378)
+
+* Mon Aug  2 2010 Jan Safranek <jsafrane@redhat.com> 0.36.2-2
+- Fix initscripts to report stopped cgconfig service as not running
+  (#619091)
+
+* Tue Jun 22 2010 Jan Safranek <jsafrane@redhat.com> 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 <jsafrane@redhat.com> 0.36-1
+- Update to 0.36.1
+
+* Tue Mar  9 2010 Jan Safranek <jsafrane@redhat.com> 0.35-1
+- Update to 0.35.1
+- Separate pam module to its own subpackage
+
+* Mon Jan 18 2010 Jan Safranek <jsafrane@redhat.com> 0.34-4
+- Added README.Fedora to describe initscript integration
+
+* Mon Oct 19 2009 Jan Safranek <jsafrane@redhat.com> 0.34-3
+- Change the default configuration to mount everything to /cgroup
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.34-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue Jul  7 2009 Jan Safranek <jsafrane@redhat.com> 0.34-1
+- Update to 0.34
+* Mon Mar 09 2009 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.33-3
+- Add a workaround for rt cgroup controller.
+* Mon Mar 09 2009 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.33-2
+- Change the cgconfig script to start earlier
+- Move the binaries to /bin and /sbin
+* Mon Mar 02 2009 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.33-1
+- Update to latest upstream
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> 0.32.2-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Mon Jan 05 2009 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.32.2-3
+- Fix redhat-lsb dependency
+* Mon Dec 29 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.32.2-2
+- Fix build dependencies
+* Mon Dec 29 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.32.2-1
+- Update to latest upstream
+* Thu Oct 23 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.32.1-1
+* Tue Feb 24 2009 Balbir Singh <balbir@linux.vnet.ibm.com> 0.33-1
+- Update to 0.33, spec file changes to add Makefiles and pam_cgroup module
+* Fri Oct 10 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.32-1
+- Update to latest upstream
+* Thu Sep 11 2008 Dhaval Giani <dhaval@linux-vnet.ibm.com> 0.31-1
+- Update to latest upstream
+* Sat Aug 2 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.1c-3
+- Change release to fix broken upgrade path
+* Wed Jun 11 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.1c-1
+- Update to latest upstream version
+* Tue Jun 3 2008 Balbir Singh <balbir@linux.vnet.ibm.com> 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 <balbir@linux.vnet.ibm.com> 0.1b-2
+- Fix makeinstall, Source0 and URL (review comments from Tom)
+* Mon May 26 2008 Balbir Singh <balbir@linux.vnet.ibm.com> 0.1b-1
+- Add a generatable spec file
+* Tue May 20 2008 Balbir Singh <balbir@linux.vnet.ibm.com> 0.1-1
+- Get the spec file to work
+* Tue May 20 2008 Dhaval Giani <dhaval@linux.vnet.ibm.com> 0.01-1
+- The first version of libcg