Commit 69600335 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Pavel Emelyanov

parse_mountinfo_ent: fix the leakage of "opt"

1. parse_mountinfo_ent() mixes "return -1" and "goto err" on failure,
   this looks confusing and inconsistent.

2. And buggy. It forgets to free(opt) if parse_mnt_flags() fails.
Signed-off-by: 's avatarOleg Nesterov <oleg@redhat.com>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8b5faee7
...@@ -947,11 +947,11 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) ...@@ -947,11 +947,11 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
{ {
unsigned int kmaj, kmin; unsigned int kmaj, kmin;
int ret, n; int ret, n;
char *opt; char *opt = NULL;
new->mountpoint = xmalloc(PATH_MAX); new->mountpoint = xmalloc(PATH_MAX);
if (new->mountpoint == NULL) if (new->mountpoint == NULL)
return -1; goto err;
new->mountpoint[0] = '.'; new->mountpoint[0] = '.';
ret = sscanf(str, "%i %i %u:%u %ms %s %ms %n", ret = sscanf(str, "%i %i %u:%u %ms %s %ms %n",
...@@ -959,29 +959,29 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) ...@@ -959,29 +959,29 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
&kmaj, &kmin, &new->root, new->mountpoint + 1, &kmaj, &kmin, &new->root, new->mountpoint + 1,
&opt, &n); &opt, &n);
if (ret != 7) if (ret != 7)
return -1; goto err;
new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1); new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1);
new->s_dev = MKKDEV(kmaj, kmin); new->s_dev = MKKDEV(kmaj, kmin);
new->flags = 0; new->flags = 0;
if (parse_mnt_flags(opt, &new->flags)) if (parse_mnt_flags(opt, &new->flags))
return -1; goto err;
free(opt); /* after %ms scanf */ free(opt); /* we are going to reallocate/reuse this buffer */
opt = NULL;
str += n; str += n;
if (parse_mnt_opt(str, new, &n)) if (parse_mnt_opt(str, new, &n))
return -1; goto err;
str += n; str += n;
ret = sscanf(str, "%ms %ms %ms", fsname, &new->source, &opt); ret = sscanf(str, "%ms %ms %ms", fsname, &new->source, &opt);
if (ret != 3) if (ret != 3)
return -1; goto err;
new->fstype = find_fstype_by_name(*fsname); new->fstype = find_fstype_by_name(*fsname);
ret = -1;
new->options = xmalloc(strlen(opt) + 1); new->options = xmalloc(strlen(opt) + 1);
if (!new->options) if (!new->options)
goto err; goto err;
...@@ -990,9 +990,12 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname) ...@@ -990,9 +990,12 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
goto err; goto err;
ret = 0; ret = 0;
err: ret:
free(opt); xfree(opt);
return ret; return ret;
err:
ret = -1;
goto ret;
} }
struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid) struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment