Blame SOURCES/libcgroup-0.41-size-of-controller-values.patch

1c5b3f
From 5a64a79144e58a62426a34ef51b14e891f042fa2 Mon Sep 17 00:00:00 2001
1c5b3f
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
1c5b3f
Date: Tue, 17 Apr 2018 13:54:38 +0200
1c5b3f
Subject: [PATCH 6/6] Increase maximal size of controller values
1c5b3f
MIME-Version: 1.0
1c5b3f
Content-Type: text/plain; charset=UTF-8
1c5b3f
Content-Transfer-Encoding: 8bit
1c5b3f
1c5b3f
Maximal length of a controller value is determined by CG_VALUE_MAX,
1c5b3f
which is equal to 100. That is not sufficient in some cases.
1c5b3f
1c5b3f
Add new constant CG_CONTROL_VALUE_MAX (to prevent breaking current API)
1c5b3f
and set it to 4096, which is usually equal to the amount of bytes that
1c5b3f
can be written to a sysctl file directly.
1c5b3f
1c5b3f
Add warning message about exceeding the limit while parsing
1c5b3f
configuration file.
1c5b3f
1c5b3f
Signed-off-by: Nikola Forró <nforro@redhat.com>
1c5b3f
---
1c5b3f
 src/api.c                |  6 +++---
1c5b3f
 src/libcgroup-internal.h |  5 ++++-
1c5b3f
 src/tools/cgset.c        |  4 ++--
1c5b3f
 src/wrapper.c            | 17 ++++++++++++-----
1c5b3f
 4 files changed, 21 insertions(+), 11 deletions(-)
1c5b3f
1c5b3f
diff --git a/src/api.c b/src/api.c
1c5b3f
index efde2d1..1cd30df 100644
1c5b3f
--- a/src/api.c
1c5b3f
+++ b/src/api.c
1c5b3f
@@ -1561,7 +1561,7 @@ static int cgroup_copy_controller_values(struct cgroup_controller *dst,
1c5b3f
 		}
1c5b3f
 
1c5b3f
 		dst_val = dst->values[i];
1c5b3f
-		strncpy(dst_val->value, src_val->value, CG_VALUE_MAX);
1c5b3f
+		strncpy(dst_val->value, src_val->value, CG_CONTROL_VALUE_MAX);
1c5b3f
 		strncpy(dst_val->name, src_val->name, FILENAME_MAX);
1c5b3f
 		dst_val->dirty = src_val->dirty;
1c5b3f
 	}
1c5b3f
@@ -2286,7 +2286,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup,
1c5b3f
 	if (ctrl_file < 0)
1c5b3f
 		return ECGROUPVALUENOTEXIST;
1c5b3f
 
1c5b3f
-	*value = calloc(CG_VALUE_MAX, 1);
1c5b3f
+	*value = calloc(CG_CONTROL_VALUE_MAX, 1);
1c5b3f
 	if (!*value) {
1c5b3f
 		close(ctrl_file);
1c5b3f
 		last_errno = errno;
1c5b3f
@@ -2297,7 +2297,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup,
1c5b3f
 	 * using %as or fread crashes when we try to read from files like
1c5b3f
 	 * memory.stat
1c5b3f
 	 */
1c5b3f
-	ret = read(ctrl_file, *value, CG_VALUE_MAX-1);
1c5b3f
+	ret = read(ctrl_file, *value, CG_CONTROL_VALUE_MAX-1);
1c5b3f
 	if (ret < 0) {
1c5b3f
 		free(*value);
1c5b3f
 		*value = NULL;
1c5b3f
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
1c5b3f
index 4c0f46c..3a8e336 100644
1c5b3f
--- a/src/libcgroup-internal.h
1c5b3f
+++ b/src/libcgroup-internal.h
1c5b3f
@@ -32,6 +32,9 @@ __BEGIN_DECLS
1c5b3f
 /* Estimated number of groups created */
1c5b3f
 #define MAX_GROUP_ELEMENTS	128
1c5b3f
 
1c5b3f
+/* Maximum length of a value */
1c5b3f
+#define CG_CONTROL_VALUE_MAX 4096
1c5b3f
+
1c5b3f
 #define CG_NV_MAX 100
1c5b3f
 #define CG_CONTROLLER_MAX 100
1c5b3f
 /* Max number of mounted hierarchies. Event if one controller is mounted per
1c5b3f
@@ -73,7 +76,7 @@ __BEGIN_DECLS
1c5b3f
 
1c5b3f
 struct control_value {
1c5b3f
 	char name[FILENAME_MAX];
1c5b3f
-	char value[CG_VALUE_MAX];
1c5b3f
+	char value[CG_CONTROL_VALUE_MAX];
1c5b3f
 	bool dirty;
1c5b3f
 };
1c5b3f
 
1c5b3f
diff --git a/src/tools/cgset.c b/src/tools/cgset.c
1c5b3f
index ea9f90d..3d3c8cc 100644
1c5b3f
--- a/src/tools/cgset.c
1c5b3f
+++ b/src/tools/cgset.c
1c5b3f
@@ -151,8 +151,8 @@ int main(int argc, char *argv[])
1c5b3f
 				goto err;
1c5b3f
 			}
1c5b3f
 
1c5b3f
-			strncpy(name_value[nv_number].value, buf, CG_VALUE_MAX);
1c5b3f
-			name_value[nv_number].value[CG_VALUE_MAX-1] = '\0';
1c5b3f
+			strncpy(name_value[nv_number].value, buf, CG_CONTROL_VALUE_MAX);
1c5b3f
+			name_value[nv_number].value[CG_CONTROL_VALUE_MAX-1] = '\0';
1c5b3f
 
1c5b3f
 			nv_number++;
1c5b3f
 			break;
1c5b3f
diff --git a/src/wrapper.c b/src/wrapper.c
1c5b3f
index c03472a..0952823 100644
1c5b3f
--- a/src/wrapper.c
1c5b3f
+++ b/src/wrapper.c
1c5b3f
@@ -132,10 +132,10 @@ int cgroup_add_value_string(struct cgroup_controller *controller,
1c5b3f
 	if (!controller)
1c5b3f
 		return ECGINVAL;
1c5b3f
 
1c5b3f
-	if (controller->index >= CG_VALUE_MAX)
1c5b3f
+	if (controller->index >= CG_NV_MAX)
1c5b3f
 		return ECGMAXVALUESEXCEEDED;
1c5b3f
 
1c5b3f
-	for (i = 0; i < controller->index && i < CG_VALUE_MAX; i++) {
1c5b3f
+	for (i = 0; i < controller->index && i < CG_NV_MAX; i++) {
1c5b3f
 		if (!strcmp(controller->values[i]->name, name))
1c5b3f
 			return ECGVALUEEXISTS;
1c5b3f
 	}
1c5b3f
@@ -145,8 +145,15 @@ int cgroup_add_value_string(struct cgroup_controller *controller,
1c5b3f
 	if (!cntl_value)
1c5b3f
 		return ECGCONTROLLERCREATEFAILED;
1c5b3f
 
1c5b3f
-	strncpy(cntl_value->name, name, sizeof(cntl_value->name));
1c5b3f
-	strncpy(cntl_value->value, value, sizeof(cntl_value->value));
1c5b3f
+	if (strlen(value) >= sizeof(cntl_value->value)) {
1c5b3f
+		fprintf(stderr, "value exceeds the maximum of %d characters\n",
1c5b3f
+			sizeof(cntl_value->value));
1c5b3f
+		free(cntl_value);
1c5b3f
+		return ECGCONFIGPARSEFAIL;
1c5b3f
+	}
1c5b3f
+
1c5b3f
+	strncpy(cntl_value->name, name, sizeof(cntl_value->name) - 1);
1c5b3f
+	strncpy(cntl_value->value, value, sizeof(cntl_value->value) - 1);
1c5b3f
 	cntl_value->dirty = true;
1c5b3f
 	controller->values[controller->index] = cntl_value;
1c5b3f
 	controller->index++;
1c5b3f
@@ -356,7 +363,7 @@ int cgroup_set_value_string(struct cgroup_controller *controller,
1c5b3f
 	for (i = 0; i < controller->index; i++) {
1c5b3f
 		struct control_value *val = controller->values[i];
1c5b3f
 		if (!strcmp(val->name, name)) {
1c5b3f
-			strncpy(val->value, value, CG_VALUE_MAX);
1c5b3f
+			strncpy(val->value, value, CG_CONTROL_VALUE_MAX - 1);
1c5b3f
 			val->dirty = true;
1c5b3f
 			return 0;
1c5b3f
 		}
1c5b3f
-- 
1c5b3f
2.17.0
1c5b3f