conf/ile: make sure buffer is large enough

conf.c: In function 'lxc_assign_network': conf.c:3096:25: error: '%lu' directive output may be truncated writing between 1 and 20 bytes into a region of size 19 [-Werror=format-truncation=] snprintf(pidstr, 19, "%lu", (unsigned long) pid); ^~~ conf.c:3096:24: note: using the range [1, 18446744073709551615] for directive argument snprintf(pidstr, 19, "%lu", (unsigned long) pid); ^~~~~ In file included from /usr/include/stdio.h:938:0, from conf.c:35: /usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: note: format output between 2 and 21 bytes into a destination of size 19 return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __bos (__s), __fmt, __va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ confile.c: In function 'network_new_hwaddrs': confile.c:2889:38: error: '%02x' directive output may be truncated writing between 2 and 8 bytes into a region of size 6 [-Werror=format-truncation=] snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", ^~~~ confile.c:2889:23: note: using the range [0, 4294967295] for directive argument snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", ^~~~~~~~~~~~~~~~~~~~~~~~~ confile.c:2889:23: note: using the range [0, 4294967295] for directive argument In file included from /usr/include/stdio.h:938:0, from confile.c:24: /usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: note: format output between 18 and 36 bytes into a destination of size 18 return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __bos (__s), __fmt, __va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Not sure whether the latter is really a problem. We might need an additional fix later on. Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 4ce84082
...@@ -3058,7 +3058,7 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname, ...@@ -3058,7 +3058,7 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname,
int bytes, pipefd[2]; int bytes, pipefd[2];
char *token, *saveptr = NULL; char *token, *saveptr = NULL;
char buffer[MAX_BUFFER_SIZE]; char buffer[MAX_BUFFER_SIZE];
char netdev_link[IFNAMSIZ+1]; char netdev_link[IFNAMSIZ + 1];
if (netdev->type != LXC_NET_VETH) { if (netdev->type != LXC_NET_VETH) {
ERROR("nic type %d not support for unprivileged use", ERROR("nic type %d not support for unprivileged use",
...@@ -3066,12 +3066,13 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname, ...@@ -3066,12 +3066,13 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname,
return -1; return -1;
} }
if(pipe(pipefd) < 0) { if (pipe(pipefd) < 0) {
SYSERROR("pipe failed"); SYSERROR("pipe failed");
return -1; return -1;
} }
if ((child = fork()) < 0) { child = fork();
if (child < 0) {
SYSERROR("fork"); SYSERROR("fork");
close(pipefd[0]); close(pipefd[0]);
close(pipefd[1]); close(pipefd[1]);
...@@ -3079,35 +3080,45 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname, ...@@ -3079,35 +3080,45 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname,
} }
if (child == 0) { // child if (child == 0) { // child
/* close the read-end of the pipe */ /* Call lxc-user-nic pid type bridge. */
close(pipefd[0]); int ret;
/* redirect the stdout to write-end of the pipe */ char pidstr[LXC_NUMSTRLEN64];
dup2(pipefd[1], STDOUT_FILENO);
/* close the write-end of the pipe */
close(pipefd[1]);
// Call lxc-user-nic pid type bridge close(pipefd[0]); /* Close the read-end of the pipe. */
char pidstr[20];
if (netdev->link) { /* Redirect stdout to write-end of the pipe. */
ret = dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]); /* Close the write-end of the pipe. */
if (ret < 0) {
SYSERROR("Failed to dup2() to redirect stdout to pipe file descriptor.");
exit(EXIT_FAILURE);
}
if (netdev->link)
strncpy(netdev_link, netdev->link, IFNAMSIZ); strncpy(netdev_link, netdev->link, IFNAMSIZ);
} else { else
strncpy(netdev_link, "none", IFNAMSIZ); strncpy(netdev_link, "none", IFNAMSIZ);
}
snprintf(pidstr, 19, "%lu", (unsigned long) pid); ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
pidstr[19] = '\0'; if (ret < 0 || ret >= LXC_NUMSTRLEN64)
exit(EXIT_FAILURE);
pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
INFO("Execing lxc-user-nic %s %s %s veth %s %s", lxcpath,
lxcname, pidstr, netdev_link, netdev->name);
execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, lxcpath, lxcname, execlp(LXC_USERNIC_PATH, LXC_USERNIC_PATH, lxcpath, lxcname,
pidstr, "veth", netdev_link, netdev->name, NULL); pidstr, "veth", netdev_link, netdev->name, NULL);
SYSERROR("execvp lxc-user-nic");
exit(1); SYSERROR("Failed to exec lxc-user-nic.");
exit(EXIT_FAILURE);
} }
/* close the write-end of the pipe */ /* close the write-end of the pipe */
close(pipefd[1]); close(pipefd[1]);
bytes = read(pipefd[0], &buffer, MAX_BUFFER_SIZE); bytes = read(pipefd[0], &buffer, MAX_BUFFER_SIZE);
if (bytes < 0) { if (bytes < 0)
SYSERROR("read failed"); SYSERROR("Failed to read from pipe file descriptor.");
}
buffer[bytes - 1] = '\0'; buffer[bytes - 1] = '\0';
if (wait_for_pid(child) != 0) { if (wait_for_pid(child) != 0) {
...@@ -3122,21 +3133,23 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname, ...@@ -3122,21 +3133,23 @@ static int unpriv_assign_nic(const char *lxcpath, char *lxcname,
token = strtok_r(buffer, ":", &saveptr); token = strtok_r(buffer, ":", &saveptr);
if (!token) if (!token)
return -1; return -1;
netdev->name = malloc(IFNAMSIZ+1);
netdev->name = malloc(IFNAMSIZ + 1);
if (!netdev->name) { if (!netdev->name) {
ERROR("Out of memory"); SYSERROR("Failed to allocate memory.");
return -1; return -1;
} }
memset(netdev->name, 0, IFNAMSIZ+1); memset(netdev->name, 0, IFNAMSIZ + 1);
strncpy(netdev->name, token, IFNAMSIZ); strncpy(netdev->name, token, IFNAMSIZ);
/* fill netdev->veth_attr.pair field */ /* fill netdev->veth_attr.pair field */
token = strtok_r(NULL, ":", &saveptr); token = strtok_r(NULL, ":", &saveptr);
if (!token) if (!token)
return -1; return -1;
netdev->priv.veth_attr.pair = strdup(token); netdev->priv.veth_attr.pair = strdup(token);
if (!netdev->priv.veth_attr.pair) { if (!netdev->priv.veth_attr.pair) {
ERROR("Out of memory"); ERROR("Failed to allocate memory.");
return -1; return -1;
} }
......
...@@ -2957,21 +2957,21 @@ next: ...@@ -2957,21 +2957,21 @@ next:
} \ } \
} }
static void new_hwaddr(char *hwaddr) static bool new_hwaddr(char *hwaddr)
{ {
FILE *f; int ret;
f = fopen("/dev/urandom", "r");
if (f) { /* COMMENT(brauner): Initialize random number generator. */
unsigned int seed; (void)randseed(true);
int ret = fread(&seed, sizeof(seed), 1, f);
if (ret != 1) ret = snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x", rand() % 255,
seed = time(NULL); rand() % 255, rand() % 255);
fclose(f); if (ret < 0 || ret >= 18) {
srand(seed); SYSERROR("Failed to call snprintf().");
} else return false;
srand(time(NULL)); }
snprintf(hwaddr, 18, "00:16:3e:%02x:%02x:%02x",
rand() % 255, rand() % 255, rand() % 255); return true;
} }
/* /*
...@@ -2993,27 +2993,33 @@ bool network_new_hwaddrs(struct lxc_conf *conf) ...@@ -2993,27 +2993,33 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
if (!conf->unexpanded_config) if (!conf->unexpanded_config)
return true; return true;
while (*lstart) { while (*lstart) {
char newhwaddr[18], oldhwaddr[17]; char newhwaddr[18], oldhwaddr[17];
lend = strchr(lstart, '\n'); lend = strchr(lstart, '\n');
if (!lend) if (!lend)
lend = lstart + strlen(lstart); lend = lstart + strlen(lstart);
else else
lend++; lend++;
if (strncmp(lstart, key, strlen(key)) != 0) { if (strncmp(lstart, key, strlen(key)) != 0) {
lstart = lend; lstart = lend;
continue; continue;
} }
p = strchr(lstart+strlen(key), '='); p = strchr(lstart+strlen(key), '=');
if (!p) { if (!p) {
lstart = lend; lstart = lend;
continue; continue;
} }
p++; p++;
while (isblank(*p)) while (isblank(*p))
p++; p++;
if (!*p) if (!*p)
return true; return true;
p2 = p; p2 = p;
while (*p2 && !isblank(*p2) && *p2 != '\n') while (*p2 && !isblank(*p2) && *p2 != '\n')
p2++; p2++;
...@@ -3022,8 +3028,12 @@ bool network_new_hwaddrs(struct lxc_conf *conf) ...@@ -3022,8 +3028,12 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
lstart = lend; lstart = lend;
continue; continue;
} }
memcpy(oldhwaddr, p, 17); memcpy(oldhwaddr, p, 17);
new_hwaddr(newhwaddr);
if (!new_hwaddr(newhwaddr))
return false;
memcpy(p, newhwaddr, 17); memcpy(p, newhwaddr, 17);
lxc_list_for_each(it, &conf->network) { lxc_list_for_each(it, &conf->network) {
struct lxc_netdev *n = it->elem; struct lxc_netdev *n = it->elem;
...@@ -3033,6 +3043,7 @@ bool network_new_hwaddrs(struct lxc_conf *conf) ...@@ -3033,6 +3043,7 @@ bool network_new_hwaddrs(struct lxc_conf *conf)
lstart = lend; lstart = lend;
} }
return true; return true;
} }
......
...@@ -1014,7 +1014,7 @@ int randseed(bool srand_it) ...@@ -1014,7 +1014,7 @@ int randseed(bool srand_it)
/* /*
srand pre-seed function based on /dev/urandom srand pre-seed function based on /dev/urandom
*/ */
unsigned int seed=time(NULL)+getpid(); unsigned int seed = time(NULL) + getpid();
FILE *f; FILE *f;
f = fopen("/dev/urandom", "r"); f = fopen("/dev/urandom", "r");
......
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