lxcfs/0007-fix-memory-leak.patch

339 lines
10 KiB
Diff
Raw Normal View History

2019-11-06 19:42:23 +08:00
diff --git a/../lxcfs-3.0.2/bindings.c b/bindings.c
index 713b7ea..c04993c 100644
--- a/../lxcfs-3.0.2/bindings.c
+++ b/bindings.c
@@ -351,7 +351,7 @@ static void append_line(char **contents, size_t *len, char *line, ssize_t linele
*len = newlen;
}
-static char *slurp_file(const char *from, int fd)
+static char *slurp_file(int fd)
{
char *line = NULL;
char *contents = NULL;
@@ -484,6 +484,7 @@ bool cgfs_set_value(const char *controller, const char *cgroup, const char *file
const char *value)
{
int ret, fd, cfd;
+ bool ret_bool;
size_t len;
char *fnam, *tmpc;
@@ -495,16 +496,25 @@ bool cgfs_set_value(const char *controller, const char *cgroup, const char *file
* . + /cgroup + / + file + \0
*/
len = strlen(cgroup) + strlen(file) + 3;
- fnam = alloca(len);
+ fnam = malloc(len);
+ if (!fnam) {
+ return false;
+ }
ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
- if (ret < 0 || (size_t)ret >= len)
+ if (ret < 0 || (size_t)ret >= len) {
+ free(fnam);
return false;
+ }
fd = openat(cfd, fnam, O_WRONLY);
- if (fd < 0)
+ if (fd < 0) {
+ free(fnam);
return false;
+ }
- return write_string(fnam, value, fd);
+ ret_bool = write_string(fnam, value, fd);
+ free(fnam);
+ return ret_bool;
}
// Chown all the files in the cgroup directory. We do this when we create
@@ -874,16 +884,26 @@ bool cgfs_get_value(const char *controller, const char *cgroup, const char *file
* . + /cgroup + / + file + \0
*/
len = strlen(cgroup) + strlen(file) + 3;
- fnam = alloca(len);
+ fnam = malloc(len);
+ if (!fnam) {
+ return false;
+ }
ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
- if (ret < 0 || (size_t)ret >= len)
+ if (ret < 0 || (size_t)ret >= len) {
+ free(fnam);
return false;
+ }
fd = openat(cfd, fnam, O_RDONLY);
- if (fd < 0)
+ if (fd < 0) {
+ free(fnam);
return false;
+ }
- *value = slurp_file(fnam, fd);
+ free(fnam);
+ store_lock();
+ *value = slurp_file(fd);
+ store_unlock();
return *value != NULL;
}
@@ -3067,7 +3087,7 @@ static int read_file(const char *path, char *buf, size_t size,
static unsigned long get_memlimit(const char *cgroup, const char *file)
{
char *memlimit_str = NULL;
- unsigned long memlimit = -1;
+ unsigned long memlimit = 0;
if (cgfs_get_value("memory", cgroup, file, &memlimit_str))
memlimit = strtoul(memlimit_str, NULL, 10);
@@ -3079,15 +3099,19 @@ static unsigned long get_memlimit(const char *cgroup, const char *file)
static unsigned long get_min_memlimit(const char *cgroup, const char *file)
{
- char *copy = strdupa(cgroup);
+ char copy[MAXPATHLEN];
+ strcpy(copy, cgroup);
unsigned long memlimit = 0, retlimit;
retlimit = get_memlimit(copy, file);
+ if (retlimit == 0) {
+ return retlimit;
+ }
while (strcmp(copy, "/") != 0) {
- copy = dirname(copy);
+ dirname(copy);
memlimit = get_memlimit(copy, file);
- if (memlimit != -1 && memlimit < retlimit)
+ if (memlimit != 0 && memlimit < retlimit)
retlimit = memlimit;
};
@@ -3100,8 +3124,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
struct fuse_context *fc = fuse_get_context();
struct file_info *d = (struct file_info *)fi->fh;
char *cg;
- char *memusage_str = NULL, *memstat_str = NULL,
- *memswlimit_str = NULL, *memswusage_str = NULL;
+ char *memusage_str = NULL, *memstat_str = NULL, *memswusage_str = NULL;
unsigned long memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
cached = 0, hosttotal = 0, active_anon = 0, inactive_anon = 0,
active_file = 0, inactive_file = 0, unevictable = 0, shmem = 0,
@@ -3132,6 +3155,8 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
prune_init_slice(cg);
memlimit = get_min_memlimit(cg, "memory.limit_in_bytes");
+ if (memlimit == 0)
+ goto err;
if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
goto err;
if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))
@@ -3139,8 +3164,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
// Following values are allowed to fail, because swapaccount might be turned
// off for current kernel
- if(cgfs_get_value("memory", cg, "memory.memsw.limit_in_bytes", &memswlimit_str) &&
- cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str))
+ if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str))
{
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
memswusage = strtoul(memswusage_str, NULL, 10);
@@ -3161,9 +3185,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
if (!f)
goto err;
+ char *printme, lbuf[100];
while (getline(&line, &linelen, f) != -1) {
ssize_t l;
- char *printme, lbuf[100];
memset(lbuf, 0, 100);
if (startswith(line, "MemTotal:")) {
@@ -3273,7 +3297,6 @@ err:
free(line);
free(cg);
free(memusage_str);
- free(memswlimit_str);
free(memswusage_str);
free(memstat_str);
return rv;
@@ -3285,7 +3308,7 @@ err:
*/
static char *get_cpuset(const char *cg)
{
- char *answer;
+ char *answer = NULL;
if (!cgfs_get_value("cpuset", cg, "cpuset.cpus", &answer))
return NULL;
@@ -3888,7 +3911,7 @@ static int proc_uptime_read(char *buf, size_t size, off_t offset,
}
struct devinfo {
- char name[100];
+ char *name;
int major, minor;
struct devinfo *next;
};
@@ -3896,7 +3919,7 @@ struct devinfo {
int getns(pid_t pid, char *ns_type)
{
char fpath[100];
- memset(fpath, 0, sizeof(fpath));
+ memset(fpath, 0, sizeof(fpath));
snprintf(fpath, 99, "/proc/%d/ns/%s", pid, ns_type);
return open(fpath, O_RDONLY);
}
@@ -3930,42 +3953,42 @@ struct devinfo* container_dev_read(pid_t pid) {
stream = fdopen(mypipe[1], "w");
if (stream == NULL) {
lxcfs_error("Error opening pipe for writing: %s\n", strerror(errno));
- goto child_out;
+ goto child_out;
}
nsfd = getns(pid, "mnt");
if (nsfd < 0) {
lxcfs_error("Error getting mnt ns: %s\n", strerror(errno));
- goto child_out;
+ goto child_out;
}
if (setns(nsfd, 0) < 0) {
lxcfs_error("Error setting mnt ns: %s\n", strerror(errno));
- goto child_out;
+ goto child_out;
}
dir = opendir("/dev");
if (dir == NULL) {
lxcfs_error("Error opening dir /dev: %s\n", strerror(errno));
- goto child_out;
+ goto child_out;
}
while ((ptr = readdir(dir)) != NULL) {
if (ptr->d_type != DT_BLK && ptr->d_type != DT_CHR) {
continue;
}
- memset(fpath, 0, sizeof(fpath));
+ memset(fpath, 0, sizeof(fpath));
snprintf(fpath, 99, "/dev/%s", ptr->d_name);
stat(fpath, &dev_stat);
fprintf(stream, "%s %d ", ptr->d_name, dev_stat.st_rdev);
fflush(stream);
}
- closedir(dir);
+ closedir(dir);
stat("/", &dev_stat);
dev_num = dev_stat.st_dev & (~0xf);
fprintf(stream, "sda %d end 0 ", dev_num);
fflush(stream);
-child_out:
- fclose(stream);
+ fclose(stream);
exit(0);
}
+child_out:
close(mypipe[1]);
stream = fdopen(mypipe[0], "r");
if (stream == NULL) {
@@ -3977,24 +4000,24 @@ child_out:
break;
}
if (head == NULL) {
- do {
- head = (struct devinfo*)malloc(sizeof(struct devinfo));
- } while (!head);
+ do {
+ head = (struct devinfo*)malloc(sizeof(struct devinfo));
+ } while (!head);
end = head;
} else {
- do {
- end->next = (struct devinfo*)malloc(sizeof(struct devinfo));
- } while (!end->next);
+ do {
+ end->next = (struct devinfo*)malloc(sizeof(struct devinfo));
+ } while (!end->next);
end = end->next;
}
end->next = NULL;
- strncpy(end->name, dev_name, 100);
+ end->name = must_copy_string(dev_name);
end->major = (dev_num & 0xff00) >> 8;
end->minor = dev_num & 0x00ff;
}
err:
- if (stream)
- fclose(stream);
+ if (stream)
+ fclose(stream);
if (child_pid > 0)
wait_for_pid(child_pid);
return head;
@@ -4006,6 +4029,7 @@ void free_devinfo_list(struct devinfo *ptr)
while (ptr != NULL) {
tmp = ptr;
ptr = ptr->next;
+ free(tmp->name);
free(tmp);
}
}
@@ -4082,6 +4106,7 @@ static int proc_diskstats_read(char *buf, size_t size, off_t offset,
for (ptr = container_devinfo; ptr != NULL; ptr = ptr->next) {
if (major == ptr->major && minor == ptr->minor) {
strncpy(dev_name, ptr->name, 71);
+ dev_name[71] = '\0';
}
}
@@ -4159,7 +4184,7 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
struct fuse_context *fc = fuse_get_context();
struct file_info *d = (struct file_info *)fi->fh;
char *cg = NULL;
- char *memswlimit_str = NULL, *memlimit_str = NULL, *memusage_str = NULL, *memswusage_str = NULL;
+ char *memusage_str = NULL, *memswusage_str = NULL;
unsigned long memswlimit = 0, memlimit = 0, memusage = 0, memswusage = 0, swap_total = 0, swap_free = 0;
ssize_t total_len = 0, rv = 0;
ssize_t l = 0;
@@ -4185,20 +4210,25 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
prune_init_slice(cg);
memlimit = get_min_memlimit(cg, "memory.limit_in_bytes");
+ if (memlimit == 0)
+ goto err;
if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
goto err;
memusage = strtoul(memusage_str, NULL, 10);
- if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str) &&
- cgfs_get_value("memory", cg, "memory.memsw.limit_in_bytes", &memswlimit_str)) {
+ if (cgfs_get_value("memory", cg, "memory.memsw.usage_in_bytes", &memswusage_str)) {
memswlimit = get_min_memlimit(cg, "memory.memsw.limit_in_bytes");
memswusage = strtoul(memswusage_str, NULL, 10);
- swap_total = (memswlimit - memlimit) / 1024;
- swap_free = (memswusage - memusage) / 1024;
+ if (memswlimit > memlimit) {
+ swap_total = (memswlimit - memlimit) / 1024;
+ }
+ if (memswusage > memusage) {
+ swap_free = (memswusage - memusage) / 1024;
+ }
}
total_len = snprintf(d->buf, d->size, "Filename\t\t\t\tType\t\tSize\tUsed\tPriority\n");
@@ -4246,8 +4276,6 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
err:
free(cg);
- free(memswlimit_str);
- free(memlimit_str);
free(memusage_str);
free(memswusage_str);
return rv;