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.
*/
#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