From 35b321354e3c5216b3fa6aed408e985273e0575e Mon Sep 17 00:00:00 2001
From: zhangxiaoyu <zhangxiaoyu58@huawei.com>
Date: Mon, 31 May 2021 20:31:26 +0800
Subject: [PATCH 25/25] get cgroup data len first, and malloc read buff by len

Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
---
 src/lxc/lxccontainer.c | 56 ++++++++++++++++++++++++++++--------------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 5769b251..01e6cbb6 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -5757,11 +5757,11 @@ WRAP_API_1(bool, lxcapi_set_start_timeout, unsigned int)
 
 static uint64_t metrics_get_ull(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item)
 {
-    char buf[80] = {0};
+    char buf[81] = {0};
     int len = 0;
     uint64_t val = 0;
 
-    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf), c->name, c->config_path);
+    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
     if (len <= 0) {
         DEBUG("unable to read cgroup item %s", item);
         return 0;
@@ -5773,11 +5773,11 @@ static uint64_t metrics_get_ull(struct lxc_container *c, struct cgroup_ops *cgro
 
 static uint64_t metrics_get_ull_with_max(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item)
 {
-    char buf[80] = {0};
+    char buf[81] = {0};
     int len = 0;
     uint64_t val = 0;
 
-    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf), c->name, c->config_path);
+    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
     if (len <= 0) {
         DEBUG("unable to read cgroup item %s", item);
         return 0;
@@ -5808,22 +5808,29 @@ static inline bool is_blk_metrics_total(const char *value)
 
 static void metrics_get_blk_stats(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item, struct lxc_blkio_metrics *stats)
 {
-#define BUFSIZE 4096
-    char buf[BUFSIZE] = {0};
+    char *buf = NULL;
     int i = 0;
     int len = 0;
+    int ret = 0;
     char **lines = NULL;
     char **cols = NULL;
 
-    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf), c->name, c->config_path);
+    len = cgroup_ops->get(cgroup_ops, item, NULL, 0, c->name, c->config_path);
     if (len <= 0) {
         DEBUG("unable to read cgroup item %s", item);
         return;
     }
 
+    buf = malloc(len + 1);
+    (void)memset(buf, 0, len + 1);
+    ret = cgroup_ops->get(cgroup_ops, item, buf, len, c->name, c->config_path);
+    if (ret != len) {
+        DEBUG("get cgroup item %s len %d has changed to %d", item, len, ret);
+    }
+
     lines = lxc_string_split_and_trim(buf, '\n');
     if (lines == NULL) {
-        return;
+        goto out;
     }
 
     (void)memset(stats, 0, sizeof(struct lxc_blkio_metrics));
@@ -5833,12 +5840,14 @@ static void metrics_get_blk_stats(struct lxc_container *c, struct cgroup_ops *cg
         if (cols == NULL) {
             goto err_out;
         }
-        if (is_blk_metrics_read(cols[1])) {
-            stats->read += strtoull(cols[2], NULL, 0);
-        } else if (is_blk_metrics_write(cols[1])) {
-            stats->write += strtoull(cols[2], NULL, 0);
+        if (lxc_array_len((void **)cols) == 3) {
+            if (is_blk_metrics_read(cols[1])) {
+                stats->read += strtoull(cols[2], NULL, 0);
+            } else if (is_blk_metrics_write(cols[1])) {
+                stats->write += strtoull(cols[2], NULL, 0);
+            }
         }
-        if (is_blk_metrics_total(cols[0])) {
+        if (lxc_array_len((void **)cols) == 2 && is_blk_metrics_total(cols[0])) {
             stats->total = strtoull(cols[1], NULL, 0);
         }
 
@@ -5846,29 +5855,38 @@ static void metrics_get_blk_stats(struct lxc_container *c, struct cgroup_ops *cg
     }
 err_out:
     lxc_free_array((void **)lines, free);
+out:
+    free(buf);
     return;
 }
 
 static void metrics_get_io_stats_v2(struct lxc_container *c, struct cgroup_ops *cgroup_ops, const char *item, struct lxc_blkio_metrics *stats, func_is_io_stat_read is_io_stat_read, func_is_io_stat_write is_io_stat_write)
 {
-#define BUFSIZE 4096
-    char buf[BUFSIZE] = {0};
+    char *buf = NULL;
     int i = 0;
     int j = 0;
     int len = 0;
+    int ret = 0;
     char **lines = NULL;
     char **cols = NULL;
     char **kv = NULL;
 
-    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf), c->name, c->config_path);
+    len = cgroup_ops->get(cgroup_ops, item, NULL, 0, c->name, c->config_path);
     if (len <= 0) {
         DEBUG("unable to read cgroup item %s", item);
         return;
     }
 
+    buf = malloc(len + 1);
+    (void)memset(buf, 0, len + 1);
+    ret = cgroup_ops->get(cgroup_ops, item, buf, len, c->name, c->config_path);
+    if (ret != len) {
+        DEBUG("get cgroup item %s len %d change to %d", item, len, ret);
+    }
+
     lines = lxc_string_split_and_trim(buf, '\n');
     if (lines == NULL) {
-        return;
+        goto out;
     }
 
     (void)memset(stats, 0, sizeof(struct lxc_blkio_metrics));
@@ -5900,6 +5918,8 @@ static void metrics_get_io_stats_v2(struct lxc_container *c, struct cgroup_ops *
 
 err_out:
     lxc_free_array((void **)lines, free);
+out:
+    free(buf);
     return;
 }
 
@@ -5915,7 +5935,7 @@ static uint64_t metrics_match_get_ull(struct lxc_container *c, struct cgroup_ops
     char **cols = NULL;
     size_t matchlen = 0;
 
-    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf), c->name, c->config_path);
+    len = cgroup_ops->get(cgroup_ops, item, buf, sizeof(buf) - 1, c->name, c->config_path);
     if (len <= 0) {
         DEBUG("unable to read cgroup item %s", item);
         goto err_out;
-- 
2.25.1

