Unverified Commit 1c605abd by Stéphane Graber Committed by GitHub

Merge pull request #2405 from brauner/2018-04-17/getgrgid_r

configure: check for getgrgid_r()
parents c693e2f0 ea753960
......@@ -600,6 +600,10 @@ AC_CHECK_LIB(pthread, main)
AC_CHECK_FUNCS(statvfs)
AC_CHECK_LIB(util, openpty)
AC_CHECK_FUNCS([openpty hasmntopt setmntent endmntent utmpxname])
AC_CHECK_FUNCS([getgrgid_r],
AM_CONDITIONAL(HAVE_GETGRGID_R, true)
AC_DEFINE(HAVE_GETGRGID_R,1,[Have getgrgid_r]),
AM_CONDITIONAL(HAVE_GETGRGID_R, false))
AC_CHECK_FUNCS([getline],
AM_CONDITIONAL(HAVE_GETLINE, true)
AC_DEFINE(HAVE_GETLINE,1,[Have getline]),
......@@ -620,6 +624,10 @@ AC_CHECK_FUNCS([prlimit64],
AM_CONDITIONAL(HAVE_PRLIMIT64, true)
AC_DEFINE(HAVE_PRLIMIT64,1,[Have prlimit64]),
AM_CONDITIONAL(HAVE_PRLIMIT64, false))
AC_CHECK_FUNCS([pthread_setcancelstate],
AM_CONDITIONAL(HAVE_PTHREAD_SETCANCELSTATE, true)
AC_DEFINE(HAVE_PTHREAD_SETCANCELSTATE,1,[Have pthread_setcancelstate]),
AM_CONDITIONAL(HAVE_PTHREAD_SETCANCELSTATE, false))
AC_CHECK_FUNCS([strlcpy],
AM_CONDITIONAL(HAVE_STRLCPY, true)
AC_DEFINE(HAVE_STRLCPY,1,[Have strlcpy]),
......
/* liblxcapi
*
* Copyright © 2018 Christian Brauner <christian.brauner@ubuntu.com>.
* Copyright © 2018 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This function has been copied from musl.
*/
#define _GNU_SOURCE
#include <byteswap.h>
#include <errno.h>
#include <grp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#define LOGIN_NAME_MAX 256
#define NSCDVERSION 2
#define GETPWBYNAME 0
#define GETPWBYUID 1
#define GETGRBYNAME 2
#define GETGRBYGID 3
#define GETINITGR 15
#define REQVERSION 0
#define REQTYPE 1
#define REQKEYLEN 2
#define REQ_LEN 3
#define PWVERSION 0
#define PWFOUND 1
#define PWNAMELEN 2
#define PWPASSWDLEN 3
#define PWUID 4
#define PWGID 5
#define PWGECOSLEN 6
#define PWDIRLEN 7
#define PWSHELLLEN 8
#define PW_LEN 9
#define GRVERSION 0
#define GRFOUND 1
#define GRNAMELEN 2
#define GRPASSWDLEN 3
#define GRGID 4
#define GRMEMCNT 5
#define GR_LEN 6
#define INITGRVERSION 0
#define INITGRFOUND 1
#define INITGRNGRPS 2
#define INITGR_LEN 3
#define FIX(x) (gr->gr_##x = gr->gr_##x - line + buf)
static unsigned atou(char **s)
{
unsigned x;
for (x = 0; **s - '0' < 10U; ++*s)
x = 10 * x + (**s - '0');
return x;
}
static int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size,
char ***mem, size_t *nmem, struct group **res)
{
ssize_t l;
char *s, *mems;
size_t i;
int rv = 0;
#ifdef HAVE_PTHREAD_SETCANCELSTATE
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
#endif
for (;;) {
if ((l = getline(line, size, f)) < 0) {
rv = ferror(f) ? errno : 0;
free(*line);
*line = 0;
gr = 0;
goto end;
}
line[0][l - 1] = 0;
s = line[0];
gr->gr_name = s++;
if (!(s = strchr(s, ':')))
continue;
*s++ = 0;
gr->gr_passwd = s;
if (!(s = strchr(s, ':')))
continue;
*s++ = 0;
gr->gr_gid = atou(&s);
if (*s != ':')
continue;
*s++ = 0;
mems = s;
break;
}
for (*nmem = !!*s; *s; s++)
if (*s == ',')
++*nmem;
free(*mem);
*mem = calloc(sizeof(char *), *nmem + 1);
if (!*mem) {
rv = errno;
free(*line);
*line = 0;
gr = 0;
goto end;
}
if (*mems) {
mem[0][0] = mems;
for (s = mems, i = 0; *s; s++)
if (*s == ',')
*s++ = 0, mem[0][++i] = s;
mem[0][++i] = 0;
} else {
mem[0][0] = 0;
}
gr->gr_mem = *mem;
end:
#ifdef HAVE_PTHREAD_SETCANCELSTATE
pthread_setcancelstate(cs, 0);
#endif
*res = gr;
if (rv)
errno = rv;
return rv;
}
static char *itoa(char *p, uint32_t x)
{
// number of digits in a uint32_t + NUL
p += 11;
*--p = 0;
do {
*--p = '0' + x % 10;
x /= 10;
} while (x);
return p;
}
static const struct {
short sun_family;
char sun_path[21];
} addr = {AF_UNIX, "/var/run/nscd/socket"};
static FILE *__nscd_query(int32_t req, const char *key, int32_t *buf,
size_t len, int *swap)
{
size_t i;
int fd;
FILE *f = 0;
int32_t req_buf[REQ_LEN] = {NSCDVERSION, req,
strnlen(key, LOGIN_NAME_MAX) + 1};
struct msghdr msg = {.msg_iov =
(struct iovec[]){{&req_buf, sizeof(req_buf)},
{(char *)key, strlen(key) + 1}},
.msg_iovlen = 2};
int errno_save = errno;
*swap = 0;
retry:
memset(buf, 0, len);
buf[0] = NSCDVERSION;
fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
return NULL;
if (!(f = fdopen(fd, "r"))) {
close(fd);
return 0;
}
if (req_buf[2] > LOGIN_NAME_MAX)
return f;
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
/* If there isn't a running nscd we simulate a "not found"
* result and the caller is responsible for calling
* fclose on the (unconnected) socket. The value of
* errno must be left unchanged in this case. */
if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
errno = errno_save;
return f;
}
goto error;
}
if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
goto error;
if (!fread(buf, len, 1, f)) {
/* If the VERSION entry mismatches nscd will disconnect. The
* most likely cause is that the endianness mismatched. So, we
* byteswap and try once more. (if we already swapped, just
* fail out)
*/
if (ferror(f))
goto error;
if (!*swap) {
fclose(f);
for (i = 0; i < sizeof(req_buf) / sizeof(req_buf[0]);
i++) {
req_buf[i] = bswap_32(req_buf[i]);
}
*swap = 1;
goto retry;
} else {
errno = EIO;
goto error;
}
}
if (*swap) {
for (i = 0; i < len / sizeof(buf[0]); i++) {
buf[i] = bswap_32(buf[i]);
}
}
/* The first entry in every nscd response is the version number. This
* really shouldn't happen, and is evidence of some form of malformed
* response.
*/
if (buf[0] != NSCDVERSION) {
errno = EIO;
goto error;
}
return f;
error:
fclose(f);
return 0;
}
static int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf,
size_t *size, char ***mem, size_t *nmem, struct group **res)
{
FILE *f;
int rv = 0;
#ifdef HAVE_PTHREAD_SETCANCELSTATE
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
#endif
*res = 0;
f = fopen("/etc/group", "rbe");
if (!f) {
rv = errno;
goto done;
}
while (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {
if ((name && !strcmp(name, (*res)->gr_name)) ||
(!name && (*res)->gr_gid == gid)) {
break;
}
}
fclose(f);
if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
int32_t req = name ? GETGRBYNAME : GETGRBYGID;
int32_t i;
const char *key;
int32_t groupbuf[GR_LEN] = {0};
size_t len = 0;
size_t grlist_len = 0;
char gidbuf[11] = {0};
int swap = 0;
char *ptr;
if (name) {
key = name;
} else {
if (gid < 0 || gid > UINT32_MAX) {
rv = 0;
goto done;
}
key = itoa(gidbuf, gid);
}
f = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);
if (!f) {
rv = errno;
goto done;
}
if (!groupbuf[GRFOUND]) {
rv = 0;
goto cleanup_f;
}
if (!groupbuf[GRNAMELEN] || !groupbuf[GRPASSWDLEN]) {
rv = EIO;
goto cleanup_f;
}
if ((int64_t)groupbuf[GRNAMELEN] >
(int64_t)(SIZE_MAX - groupbuf[GRPASSWDLEN])) {
rv = ENOMEM;
goto cleanup_f;
}
len = groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
for (i = 0; i < groupbuf[GRMEMCNT]; i++) {
uint32_t name_len;
if (fread(&name_len, sizeof name_len, 1, f) < 1) {
rv = ferror(f) ? errno : EIO;
goto cleanup_f;
}
if (swap) {
name_len = bswap_32(name_len);
}
if (name_len > SIZE_MAX - grlist_len ||
name_len > SIZE_MAX - len) {
rv = ENOMEM;
goto cleanup_f;
}
len += name_len;
grlist_len += name_len;
}
if (len > *size || !*buf) {
char *tmp = realloc(*buf, len);
if (!tmp) {
rv = errno;
goto cleanup_f;
}
*buf = tmp;
*size = len;
}
if (!fread(*buf, len, 1, f)) {
rv = ferror(f) ? errno : EIO;
goto cleanup_f;
}
if (((size_t)(groupbuf[GRMEMCNT] + 1)) > *nmem) {
if (((size_t)(groupbuf[GRMEMCNT] + 1)) >
(SIZE_MAX / sizeof(char *))) {
rv = ENOMEM;
goto cleanup_f;
}
char **tmp = realloc(*mem, (groupbuf[GRMEMCNT] + 1) *
sizeof(char *));
if (!tmp) {
rv = errno;
goto cleanup_f;
}
*mem = tmp;
*nmem = groupbuf[GRMEMCNT] + 1;
}
if (groupbuf[GRMEMCNT]) {
mem[0][0] =
*buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
for (ptr = mem[0][0], i = 0;
ptr != mem[0][0] + grlist_len; ptr++)
if (!*ptr)
mem[0][++i] = ptr + 1;
mem[0][i] = 0;
if (i != groupbuf[GRMEMCNT]) {
rv = EIO;
goto cleanup_f;
}
} else {
mem[0][0] = 0;
}
gr->gr_name = *buf;
gr->gr_passwd = gr->gr_name + groupbuf[GRNAMELEN];
gr->gr_gid = groupbuf[GRGID];
gr->gr_mem = *mem;
if (gr->gr_passwd[-1] ||
gr->gr_passwd[groupbuf[GRPASSWDLEN] - 1]) {
rv = EIO;
goto cleanup_f;
}
if ((name && strcmp(name, gr->gr_name)) ||
(!name && gid != gr->gr_gid)) {
rv = EIO;
goto cleanup_f;
}
*res = gr;
cleanup_f:
fclose(f);
goto done;
}
done:
#ifdef HAVE_PTHREAD_SETCANCELSTATE
pthread_setcancelstate(cs, 0);
#endif
if (rv)
errno = rv;
return rv;
}
static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf,
size_t size, struct group **res)
{
char *line = 0;
size_t len = 0;
char **mem = 0;
size_t nmem = 0;
int rv = 0;
size_t i;
#ifdef HAVE_PTHREAD_SETCANCELSTATE
int cs;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
#endif
rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
if (*res && size < len + (nmem + 1) * sizeof(char *) + 32) {
*res = 0;
rv = ERANGE;
}
if (*res) {
buf += (16 - (uintptr_t)buf) % 16;
gr->gr_mem = (void *)buf;
buf += (nmem + 1) * sizeof(char *);
memcpy(buf, line, len);
FIX(name);
FIX(passwd);
for (i = 0; mem[i]; i++)
gr->gr_mem[i] = mem[i] - line + buf;
gr->gr_mem[i] = 0;
}
free(mem);
free(line);
#ifdef HAVE_PTHREAD_SETCANCELSTATE
pthread_setcancelstate(cs, 0);
#endif
if (rv)
errno = rv;
return rv;
}
int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
{
return getgr_r(0, gid, gr, buf, size, res);
}
/* liblxcapi
*
* Copyright © 2018 Christian Brauner <christian.brauner@ubuntu.com>.
* Copyright © 2018 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This function has been copied from musl.
*/
#ifndef _GETGRGID_R_H
#define _GETGRGID_R_H
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
extern int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size,
struct group **res);
#endif /* _GETGRGID_R_H */
......@@ -63,6 +63,10 @@ if !HAVE_GETSUBOPT
noinst_HEADERS += tools/include/getsubopt.h
endif
if !HAVE_GETGRGID_R
noinst_HEADERS += ../include/getgrgid_r.h
endif
sodir=$(libdir)
LSM_SOURCES = \
......@@ -155,6 +159,10 @@ if !HAVE_STRLCPY
liblxc_la_SOURCES += ../include/strlcpy.c ../include/strlcpy.h
endif
if !HAVE_GETGRGID_R
liblxc_la_SOURCES += ../include/getgrgid_r.c ../include/getgrgid_r.h
endif
AM_CFLAGS=-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
-DLXCPATH=\"$(LXCPATH)\" \
-DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \
......@@ -308,6 +316,10 @@ if !HAVE_STRLCPY
init_lxc_static_SOURCES += ../include/strlcpy.c ../include/strlcpy.h
endif
if !HAVE_GETGRGID_R
liblxc_la_SOURCES += ../include/getgrgid_r.c ../include/getgrgid_r.h
endif
init_lxc_static_LDFLAGS = -all-static
init_lxc_static_LDADD = @CAP_LIBS@
init_lxc_static_CFLAGS = $(AM_CFLAGS) -DNO_LXC_CONF
......
......@@ -606,8 +606,9 @@ static void lxc_attach_get_init_uidgid(uid_t *init_uid, gid_t *init_gid)
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
/* Read capabilities. */
snprintf(proc_fn, __PROC_STATUS_LEN, "/proc/%d/status", 1);
ret = snprintf(proc_fn, __PROC_STATUS_LEN, "/proc/%d/status", 1);
if (ret < 0 || ret >= __PROC_STATUS_LEN)
return;
proc_file = fopen(proc_fn, "r");
if (!proc_file)
......
......@@ -1748,9 +1748,6 @@ static int recursive_count_nrtasks(char *dirname)
while ((direntp = readdir(dir))) {
struct stat mystat;
if (!direntp)
break;
if (!strcmp(direntp->d_name, ".") ||
!strcmp(direntp->d_name, ".."))
continue;
......
......@@ -213,7 +213,7 @@ static int lxc_cmd_rsp_send(int fd, struct lxc_cmd_rsp *rsp)
return -1;
}
if (rsp->datalen <= 0)
if (!rsp->data || rsp->datalen <= 0)
return 0;
ret = send(fd, rsp->data, rsp->datalen, 0);
......
......@@ -1561,15 +1561,24 @@ static bool create_run_template(struct lxc_container *c, char *tpath,
/* note n2[n2args-1] is NULL */
n2[n2args - 5] = "--mapped-uid";
snprintf(txtuid, 20, "%d", hostuid_mapped);
ret = snprintf(txtuid, 20, "%d", hostuid_mapped);
if (ret < 0 || ret >= 20) {
free(newargv);
free(n2);
_exit(EXIT_FAILURE);
}
n2[n2args - 4] = txtuid;
n2[n2args - 3] = "--mapped-gid";
ret = snprintf(txtgid, 20, "%d", hostgid_mapped);
if (ret < 0 || ret >= 20) {
free(newargv);
free(n2);
_exit(EXIT_FAILURE);
}
n2[n2args - 2] = txtgid;
n2[n2args - 1] = NULL;
free(newargv);
......@@ -2328,58 +2337,64 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
WRAP_API(char **, lxcapi_get_interfaces)
static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface, const char* family, int scope)
static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
const char *family, int scope)
{
int i, ret;
pid_t pid;
int i, count = 0, pipefd[2];
char **addresses = NULL;
int pipefd[2];
char address[INET6_ADDRSTRLEN];
int count = 0;
char **addresses = NULL;
if(pipe(pipefd) < 0) {
SYSERROR("pipe failed");
ret = pipe(pipefd);
if (ret < 0) {
SYSERROR("Failed to create pipe");
return NULL;
}
pid = fork();
if (pid < 0) {
SYSERROR("failed to fork task to get container ips");
SYSERROR("Failed to create new process");
close(pipefd[0]);
close(pipefd[1]);
return NULL;
}
if (pid == 0) { /* child */
int ret = 1, nbytes;
struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
if (pid == 0) {
ssize_t nbytes;
char addressOutputBuffer[INET6_ADDRSTRLEN];
void *tempAddrPtr = NULL;
int ret = 1;
char *address = NULL;
void *tempAddrPtr = NULL;
struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
/* close the read-end of the pipe */
close(pipefd[0]);
if (!enter_net_ns(c)) {
SYSERROR("failed to enter namespace");
SYSERROR("Failed to attach to network namespace");
goto out;
}
/* Grab the list of interfaces */
if (getifaddrs(&interfaceArray)) {
SYSERROR("failed to get interfaces list");
SYSERROR("Failed to get interfaces list");
goto out;
}
/* Iterate through the interfaces */
for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
for (tempIfAddr = interfaceArray; tempIfAddr;
tempIfAddr = tempIfAddr->ifa_next) {
if (tempIfAddr->ifa_addr == NULL)
continue;
if(tempIfAddr->ifa_addr->sa_family == AF_INET) {
if (tempIfAddr->ifa_addr->sa_family == AF_INET) {
if (family && strcmp(family, "inet"))
continue;
tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr;
}
else {
} else {
if (family && strcmp(family, "inet6"))
continue;
......@@ -2395,15 +2410,15 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
continue;
address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family,
tempAddrPtr,
addressOutputBuffer,
sizeof(addressOutputBuffer));
tempAddrPtr, addressOutputBuffer,
sizeof(addressOutputBuffer));
if (!address)
continue;
continue;
nbytes = write(pipefd[1], address, INET6_ADDRSTRLEN);
if (nbytes < 0) {
ERROR("write failed");
nbytes = lxc_write_nointr(pipefd[1], address, INET6_ADDRSTRLEN);
if (nbytes != INET6_ADDRSTRLEN) {
SYSERROR("Failed to send ipv6 address \"%s\"",
address);
goto out;
}
count++;
......@@ -2411,7 +2426,7 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
ret = 0;
out:
if(interfaceArray)
if (interfaceArray)
freeifaddrs(interfaceArray);
/* close the write-end of the pipe, thus sending EOF to the reader */
......@@ -2422,15 +2437,19 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
/* close the write-end of the pipe */
close(pipefd[1]);
while (read(pipefd[0], &address, INET6_ADDRSTRLEN) == INET6_ADDRSTRLEN) {
if(!add_to_array(&addresses, address, count))
while (lxc_read_nointr(pipefd[0], &address, INET6_ADDRSTRLEN) == INET6_ADDRSTRLEN) {
address[INET6_ADDRSTRLEN - 1] = '\0';
if (!add_to_array(&addresses, address, count))
ERROR("PARENT: add_to_array failed");
count++;
}
if (wait_for_pid(pid) != 0) {
for(i=0;i<count;i++)
for (i = 0; i < count; i++)
free(addresses[i]);
free(addresses);
addresses = NULL;
}
......@@ -2439,7 +2458,7 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
close(pipefd[0]);
/* Append NULL to the array */
if(addresses)
if (addresses)
addresses = (char **)lxc_append_null_to_array((void **)addresses, count);
return addresses;
......@@ -2684,7 +2703,10 @@ static bool mod_rdep(struct lxc_container *c0, struct lxc_container *c, bool inc
if (stat(path, &fbuf) < 0)
goto out;
if (!fbuf.st_size) {
remove(path);
ret = remove(path);
if (ret < 0)
SYSERROR("Failed to remove \"%s\"", path);
}
}
......@@ -3417,14 +3439,20 @@ static bool add_rdepends(struct lxc_container *c, struct lxc_container *c0)
bool should_default_to_snapshot(struct lxc_container *c0,
struct lxc_container *c1)
{
int ret;
size_t l0 = strlen(c0->config_path) + strlen(c0->name) + 2;
size_t l1 = strlen(c1->config_path) + strlen(c1->name) + 2;
char *p0 = alloca(l0 + 1);
char *p1 = alloca(l1 + 1);
char *rootfs = c0->lxc_conf->rootfs.path;
snprintf(p0, l0, "%s/%s", c0->config_path, c0->name);
snprintf(p1, l1, "%s/%s", c1->config_path, c1->name);
ret = snprintf(p0, l0, "%s/%s", c0->config_path, c0->name);
if (ret < 0 || ret >= l0)
return false;
ret = snprintf(p1, l1, "%s/%s", c1->config_path, c1->name);
if (ret < 0 || ret >= l1)
return false;
if (!is_btrfs_fs(p0) || !is_btrfs_fs(p1))
return false;
......
......@@ -123,7 +123,10 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
memcpy(netdev->priv.veth_attr.veth1, veth1, IFNAMSIZ);
}
snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
err = snprintf(veth2buf, sizeof(veth2buf), "vethXXXXXX");
if (err < 0 || (size_t)err >= sizeof(veth2buf))
return -1;
veth2 = lxc_mkifname(veth2buf);
if (!veth2)
goto out_delete;
......
......@@ -751,11 +751,9 @@ int lxc_init(const char *name, struct lxc_handler *handler)
TRACE("Set container state to \"STARTING\"");
/* Start of environment variable setup for hooks. */
if (name) {
ret = setenv("LXC_NAME", name, 1);
if (ret < 0)
SYSERROR("Failed to set environment variable: LXC_NAME=%s", name);
}
ret = setenv("LXC_NAME", name, 1);
if (ret < 0)
SYSERROR("Failed to set environment variable: LXC_NAME=%s", name);
if (conf->rcfile) {
ret = setenv("LXC_CONFIG_FILE", conf->rcfile, 1);
......
......@@ -87,8 +87,8 @@ is2big:
return -1;
}
static void print_usage(const struct option longopts[],
const struct lxc_arguments *a_args)
static void print_usage_exit(const struct option longopts[],
const struct lxc_arguments *a_args)
{
int i;
......@@ -134,13 +134,13 @@ static void print_usage(const struct option longopts[],
exit(0);
}
static void print_version()
static void print_version_exit()
{
printf("%s\n", lxc_get_version());
exit(0);
}
static void print_help(const struct lxc_arguments *args, int code)
static void print_help_exit(const struct lxc_arguments *args, int code)
{
fprintf(stderr, "\
Usage: %s %s\
......@@ -236,13 +236,13 @@ extern int lxc_arguments_parse(struct lxc_arguments *args, int argc,
return ret;
break;
case OPT_USAGE:
print_usage(args->options, args);
print_usage_exit(args->options, args);
case OPT_VERSION:
print_version();
print_version_exit();
case '?':
print_help(args, 1);
print_help_exit(args, 1);
case 'h':
print_help(args, 0);
print_help_exit(args, 0);
default:
if (args->parser) {
ret = args->parser(args, c, optarg);
......
......@@ -744,6 +744,7 @@ static char *mount_tmpfs(const char *oldname, const char *newname,
{
int ret, fd;
size_t len;
mode_t msk;
char *premount = NULL;
FILE *fp = NULL;
......@@ -773,7 +774,9 @@ static char *mount_tmpfs(const char *oldname, const char *newname,
if (ret < 0 || (size_t)ret >= len)
goto err_free;
msk = umask(0022);
fd = mkstemp(premount);
umask(msk);
if (fd < 0)
goto err_free;
......
......@@ -112,19 +112,19 @@ static void str_chomp(char *buf)
static void size_humanize(unsigned long long val, char *buf, size_t bufsz)
{
if (val > 1 << 30) {
snprintf(buf, bufsz, "%u.%2.2u GiB",
(unsigned int)(val >> 30),
(unsigned int)(val & ((1 << 30) - 1)) / 10737419);
(void)snprintf(buf, bufsz, "%u.%2.2u GiB",
(unsigned int)(val >> 30),
(unsigned int)(val & ((1 << 30) - 1)) / 10737419);
} else if (val > 1 << 20) {
unsigned int x = val + 5243; /* for rounding */
snprintf(buf, bufsz, "%u.%2.2u MiB",
x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
(void)snprintf(buf, bufsz, "%u.%2.2u MiB", x >> 20,
((x & ((1 << 20) - 1)) * 100) >> 20);
} else if (val > 1 << 10) {
unsigned int x = val + 5; /* for rounding */
snprintf(buf, bufsz, "%u.%2.2u KiB",
x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
(void)snprintf(buf, bufsz, "%u.%2.2u KiB", x >> 10,
((x & ((1 << 10) - 1)) * 100) >> 10);
} else {
snprintf(buf, bufsz, "%u bytes", (unsigned int)val);
(void)snprintf(buf, bufsz, "%u bytes", (unsigned int)val);
}
}
......@@ -172,7 +172,10 @@ static void print_net_stats(struct lxc_container *c)
/* XXX: tx and rx are reversed from the host vs container
* perspective, print them from the container perspective
*/
snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/rx_bytes", ifname);
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/rx_bytes", ifname);
if (rc < 0 || (size_t)rc >= sizeof(path))
return;
rc = lxc_read_from_file(path, buf, sizeof(buf));
if (rc > 0) {
str_chomp(buf);
......@@ -181,7 +184,10 @@ static void print_net_stats(struct lxc_container *c)
fflush(stdout);
}
snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/tx_bytes", ifname);
rc = snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/tx_bytes", ifname);
if (rc < 0 || (size_t)rc >= sizeof(path))
return;
rc = lxc_read_from_file(path, buf, sizeof(buf));
if (rc > 0) {
str_chomp(buf);
......
......@@ -568,8 +568,10 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
/* We want to remove all locks we create under
* /run/lxc/lock so we create a string pointing us to
* the lock path for the current container. */
if (ls_remove_lock(path, name, lockpath, &len_lockpath, true) == -1)
if (ls_remove_lock(path, name, lockpath, &len_lockpath, true) == -1) {
free(newpath);
goto put_and_next;
}
ls_get(m, size, args, newpath, l->name, lvl + 1, lockpath, len_lockpath, grps_must, grps_must_len);
free(newpath);
......@@ -817,6 +819,7 @@ static void ls_print_fancy_format(struct ls *l, struct lengths *lht,
strcasecmp(*s, "GROUPS") && strcasecmp(*s, "INTERFACE") &&
strcasecmp(*s, "IPV4") && strcasecmp(*s, "IPV6") &&
strcasecmp(*s, "UNPRIVILEGED")) {
lxc_free_array((void **)tmp, free);
fprintf(stderr, "Invalid key: %s\n", *s);
return;
}
......@@ -893,6 +896,8 @@ static void ls_print_fancy_format(struct ls *l, struct lengths *lht,
}
printf("\n");
}
lxc_free_array((void **)tmp, free);
}
static void ls_print_table(struct ls *l, struct lengths *lht,
......
......@@ -139,7 +139,7 @@ Options :\n\
static void stdin_tios_restore(void)
{
tcsetattr(0, TCSAFLUSH, &oldtios);
(void)tcsetattr(0, TCSAFLUSH, &oldtios);
fprintf(stderr, "\n");
}
......
......@@ -2411,8 +2411,11 @@ bool lxc_nic_exists(char *nic)
int lxc_make_tmpfile(char *template, bool rm)
{
int fd, ret;
mode_t msk;
msk = umask(0022);
fd = mkstemp(template);
umask(msk);
if (fd < 0)
return -1;
......
......@@ -149,13 +149,13 @@ void test_detect_ramfs_rootfs(void)
goto non_test_error;
}
fd1 = mkstemp(tmpf1);
fd1 = lxc_make_tmpfile(tmpf1, false);
if (fd1 < 0) {
lxc_error("%s\n", "Could not create temporary file.");
goto non_test_error;
}
fd2 = mkstemp(tmpf2);
fd2 = lxc_make_tmpfile(tmpf2, false);
if (fd2 < 0) {
lxc_error("%s\n", "Could not create temporary file.");
goto non_test_error;
......
......@@ -31,6 +31,7 @@
#include "confile_utils.h"
#include "lxc/state.h"
#include "lxctest.h"
#include "utils.h"
static int set_get_compare_clear_save_load(struct lxc_container *c,
const char *key, const char *value,
......@@ -302,7 +303,7 @@ int main(int argc, char *argv[])
char tmpf[] = "lxc-parse-config-file-XXXXXX";
char retval[4096] = {0};
fd = mkstemp(tmpf);
fd = lxc_make_tmpfile(tmpf, false);
if (fd < 0) {
lxc_error("%s\n", "Could not create temporary file");
exit(fret);
......
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