mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-14 20:26:41 +00:00
Merge pull request #2508 from brauner/2018-08-04/cap_fixes
macro: add new macro header, caps: bugfixes, log: bugfixes
This commit is contained in:
commit
1a64ff41a1
@ -16,6 +16,7 @@ noinst_HEADERS = attach.h \
|
|||||||
log.h \
|
log.h \
|
||||||
lxc.h \
|
lxc.h \
|
||||||
lxclock.h \
|
lxclock.h \
|
||||||
|
macro.h \
|
||||||
monitor.h \
|
monitor.h \
|
||||||
namespace.h \
|
namespace.h \
|
||||||
start.h \
|
start.h \
|
||||||
@ -99,6 +100,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
|
|||||||
lxccontainer.c lxccontainer.h \
|
lxccontainer.c lxccontainer.h \
|
||||||
lxclock.c lxclock.h \
|
lxclock.c lxclock.h \
|
||||||
lxcseccomp.h \
|
lxcseccomp.h \
|
||||||
|
macro.h \
|
||||||
mainloop.c mainloop.h \
|
mainloop.c mainloop.h \
|
||||||
namespace.c namespace.h \
|
namespace.c namespace.h \
|
||||||
nl.c nl.h \
|
nl.c nl.h \
|
||||||
@ -342,6 +344,7 @@ init_lxc_static_SOURCES = cmd/lxc_init.c \
|
|||||||
error.c error.h \
|
error.c error.h \
|
||||||
initutils.c initutils.h \
|
initutils.c initutils.h \
|
||||||
log.c log.h \
|
log.c log.h \
|
||||||
|
macro.h \
|
||||||
namespace.c namespace.h \
|
namespace.c namespace.h \
|
||||||
parse.c parse.h
|
parse.c parse.h
|
||||||
|
|
||||||
|
136
src/lxc/caps.c
136
src/lxc/caps.c
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "caps.h"
|
#include "caps.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
lxc_log_define(caps, lxc);
|
lxc_log_define(caps, lxc);
|
||||||
|
|
||||||
@ -66,51 +67,52 @@ lxc_log_define(caps, lxc);
|
|||||||
int lxc_caps_down(void)
|
int lxc_caps_down(void)
|
||||||
{
|
{
|
||||||
cap_t caps;
|
cap_t caps;
|
||||||
int ret;
|
int ret = -1;
|
||||||
|
|
||||||
/* when we are run as root, we don't want to play
|
/* When we are root, we don't want to play with capabilities. */
|
||||||
* with the capabilities */
|
|
||||||
if (!getuid())
|
if (!getuid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
caps = cap_get_proc();
|
caps = cap_get_proc();
|
||||||
if (!caps) {
|
if (!caps) {
|
||||||
SYSERROR("Failed to cap_get_proc");
|
SYSERROR("Failed to retrieve capabilities");
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cap_clear_flag(caps, CAP_EFFECTIVE);
|
ret = cap_clear_flag(caps, CAP_EFFECTIVE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SYSERROR("Failed to cap_clear_flag");
|
SYSERROR("Failed to clear effective capabilities");
|
||||||
goto out;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cap_set_proc(caps);
|
ret = cap_set_proc(caps);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SYSERROR("Failed to cap_set_proc");
|
SYSERROR("Failed to change effective capabilities");
|
||||||
goto out;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
ret = 0;
|
||||||
|
|
||||||
|
on_error:
|
||||||
cap_free(caps);
|
cap_free(caps);
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_caps_up(void)
|
int lxc_caps_up(void)
|
||||||
{
|
{
|
||||||
cap_t caps;
|
cap_t caps;
|
||||||
cap_value_t cap;
|
cap_value_t cap;
|
||||||
int ret;
|
int ret = -1;
|
||||||
|
|
||||||
/* when we are run as root, we don't want to play
|
/* When we are root, we don't want to play with capabilities. */
|
||||||
* with the capabilities */
|
|
||||||
if (!getuid())
|
if (!getuid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
caps = cap_get_proc();
|
caps = cap_get_proc();
|
||||||
if (!caps) {
|
if (!caps) {
|
||||||
SYSERROR("Failed to cap_get_proc");
|
SYSERROR("Failed to retrieve capabilities");
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
|
for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
|
||||||
@ -119,30 +121,34 @@ int lxc_caps_up(void)
|
|||||||
ret = cap_get_flag(caps, cap, CAP_PERMITTED, &flag);
|
ret = cap_get_flag(caps, cap, CAP_PERMITTED, &flag);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (errno == EINVAL) {
|
if (errno == EINVAL) {
|
||||||
INFO("Last supported cap was %d", cap-1);
|
INFO("Last supported cap was %d", cap - 1);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
SYSERROR("Failed to cap_get_flag");
|
SYSERROR("Failed to retrieve setting for "
|
||||||
goto out;
|
"permitted capability %d", cap - 1);
|
||||||
|
goto on_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag);
|
ret = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SYSERROR("Failed to cap_set_flag");
|
SYSERROR("Failed to set effective capability %d", cap - 1);
|
||||||
goto out;
|
goto on_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = cap_set_proc(caps);
|
ret = cap_set_proc(caps);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
SYSERROR("Failed to cap_set_proc");
|
SYSERROR("Failed to change effective capabilities");
|
||||||
goto out;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
ret = 0;
|
||||||
|
|
||||||
|
on_error:
|
||||||
cap_free(caps);
|
cap_free(caps);
|
||||||
return 0;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lxc_ambient_caps_up(void)
|
int lxc_ambient_caps_up(void)
|
||||||
@ -153,7 +159,7 @@ int lxc_ambient_caps_up(void)
|
|||||||
int last_cap = CAP_LAST_CAP;
|
int last_cap = CAP_LAST_CAP;
|
||||||
char *cap_names = NULL;
|
char *cap_names = NULL;
|
||||||
|
|
||||||
/* When we are run as root, we don't want to play with the capabilities. */
|
/* When we are root, we don't want to play with capabilities. */
|
||||||
if (!getuid())
|
if (!getuid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -220,7 +226,7 @@ int lxc_ambient_caps_down(void)
|
|||||||
cap_t caps;
|
cap_t caps;
|
||||||
cap_value_t cap;
|
cap_value_t cap;
|
||||||
|
|
||||||
/* When we are run as root, we don't want to play with the capabilities. */
|
/* When we are root, we don't want to play with capabilities. */
|
||||||
if (!getuid())
|
if (!getuid())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -257,79 +263,84 @@ out:
|
|||||||
|
|
||||||
int lxc_caps_init(void)
|
int lxc_caps_init(void)
|
||||||
{
|
{
|
||||||
uid_t uid = getuid();
|
uid_t euid, uid;
|
||||||
gid_t gid = getgid();
|
|
||||||
uid_t euid = geteuid();
|
|
||||||
|
|
||||||
if (!uid) {
|
uid = getuid();
|
||||||
INFO("command is run as 'root'");
|
if (!uid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
euid = geteuid();
|
||||||
if (uid && !euid) {
|
if (uid && !euid) {
|
||||||
INFO("command is run as setuid root (uid : %d)", uid);
|
int ret;
|
||||||
|
gid_t gid;
|
||||||
|
|
||||||
if (prctl(PR_SET_KEEPCAPS, 1)) {
|
INFO("Command is run as setuid root (uid: %d)", uid);
|
||||||
SYSERROR("Failed to 'PR_SET_KEEPCAPS'");
|
|
||||||
|
ret = prctl(PR_SET_KEEPCAPS, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
SYSERROR("Failed to set PR_SET_KEEPCAPS");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setresgid(gid, gid, gid)) {
|
gid = getgid();
|
||||||
SYSERROR("Failed to change gid to '%d'", gid);
|
ret = setresgid(gid, gid, gid);
|
||||||
|
if (ret < 0) {
|
||||||
|
SYSERROR("Failed to change rgid, egid, and sgid to %d", gid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setresuid(uid, uid, uid)) {
|
ret = setresuid(uid, uid, uid);
|
||||||
SYSERROR("Failed to change uid to '%d'", uid);
|
if (ret < 0) {
|
||||||
|
SYSERROR("Failed to change ruid, euid, and suid to %d", uid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lxc_caps_up()) {
|
ret = lxc_caps_up();
|
||||||
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to restore capabilities");
|
SYSERROR("Failed to restore capabilities");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uid == euid)
|
if (uid == euid)
|
||||||
INFO("command is run as user '%d'", uid);
|
INFO("Command is run with uid %d", uid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _real_caps_last_cap(void)
|
static int _real_caps_last_cap(void)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd, result = -1;
|
||||||
int result = -1;
|
|
||||||
|
|
||||||
/* try to get the maximum capability over the kernel
|
/* Try to get the maximum capability over the kernel interface
|
||||||
* interface introduced in v3.2 */
|
* introduced in v3.2.
|
||||||
fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY);
|
*/
|
||||||
|
fd = open("/proc/sys/kernel/cap_last_cap", O_RDONLY | O_CLOEXEC);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
char buf[32];
|
ssize_t n;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int n;
|
char buf[LXC_NUMSTRLEN64 + 1];
|
||||||
|
|
||||||
again:
|
again:
|
||||||
n = read(fd, buf, 31);
|
n = read(fd, buf, LXC_NUMSTRLEN64);
|
||||||
if (n < 0 && errno == EINTR) {
|
if (n < 0 && errno == EINTR) {
|
||||||
goto again;
|
goto again;
|
||||||
} else if (n >= 0) {
|
} else if (n >= 0) {
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
result = strtol(buf, &ptr, 10);
|
result = strtol(buf, &ptr, 10);
|
||||||
if (!ptr || (*ptr != '\0' && *ptr != '\n') || errno != 0)
|
if (!ptr || (*ptr != '\0' && *ptr != '\n') || errno != 0)
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
/* try to get it manually by trying to get the status of
|
|
||||||
* each capability indiviually from the kernel */
|
|
||||||
if (result < 0) {
|
|
||||||
int cap = 0;
|
int cap = 0;
|
||||||
|
|
||||||
|
/* Try to get it manually by trying to get the status of each
|
||||||
|
* capability individually from the kernel.
|
||||||
|
*/
|
||||||
while (prctl(PR_CAPBSET_READ, cap) >= 0)
|
while (prctl(PR_CAPBSET_READ, cap) >= 0)
|
||||||
cap++;
|
cap++;
|
||||||
|
|
||||||
@ -356,7 +367,7 @@ static bool lxc_cap_is_set(cap_t caps, cap_value_t cap, cap_flag_t flag)
|
|||||||
|
|
||||||
ret = cap_get_flag(caps, cap, flag, &flagval);
|
ret = cap_get_flag(caps, cap, flag, &flagval);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to perform cap_get_flag()");
|
SYSERROR("Failed to retrieve current setting for capability %d", cap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +376,7 @@ static bool lxc_cap_is_set(cap_t caps, cap_value_t cap, cap_flag_t flag)
|
|||||||
|
|
||||||
bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag)
|
bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag)
|
||||||
{
|
{
|
||||||
#if LIBCAP_SUPPORTS_FILE_CAPABILITIES
|
#if LIBCAP_SUPPORTS_FILE_CAPABILITIES
|
||||||
bool cap_is_set;
|
bool cap_is_set;
|
||||||
cap_t caps;
|
cap_t caps;
|
||||||
|
|
||||||
@ -377,7 +388,7 @@ bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag)
|
|||||||
* case errno will be set to ENODATA.
|
* case errno will be set to ENODATA.
|
||||||
*/
|
*/
|
||||||
if (errno != ENODATA)
|
if (errno != ENODATA)
|
||||||
SYSERROR("Failed to perform cap_get_file()");
|
SYSERROR("Failed to retrieve capabilities for file %s", path);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -385,10 +396,10 @@ bool lxc_file_cap_is_set(const char *path, cap_value_t cap, cap_flag_t flag)
|
|||||||
cap_is_set = lxc_cap_is_set(caps, cap, flag);
|
cap_is_set = lxc_cap_is_set(caps, cap, flag);
|
||||||
cap_free(caps);
|
cap_free(caps);
|
||||||
return cap_is_set;
|
return cap_is_set;
|
||||||
#else
|
#else
|
||||||
errno = ENODATA;
|
errno = ENODATA;
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag)
|
bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag)
|
||||||
@ -398,7 +409,7 @@ bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag)
|
|||||||
|
|
||||||
caps = cap_get_proc();
|
caps = cap_get_proc();
|
||||||
if (!caps) {
|
if (!caps) {
|
||||||
SYSERROR("Failed to perform cap_get_proc()");
|
SYSERROR("Failed to retrieve capabilities");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,5 +417,4 @@ bool lxc_proc_cap_is_set(cap_value_t cap, cap_flag_t flag)
|
|||||||
cap_free(caps);
|
cap_free(caps);
|
||||||
return cap_is_set;
|
return cap_is_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -384,30 +384,28 @@ struct lxc_log_category lxc_log_category_lxc = {
|
|||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int build_dir(const char *name)
|
static int build_dir(const char *name)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
char *e, *n, *p;
|
char *e, *n, *p;
|
||||||
|
|
||||||
/* Make copy of string since we'll be modifying it. */
|
/* Make copy of the string since we'll be modifying it. */
|
||||||
n = strdup(name);
|
n = strdup(name);
|
||||||
if (!n) {
|
if (!n)
|
||||||
ERROR("Out of memory while creating directory '%s'", name);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
e = &n[strlen(n)];
|
e = &n[strlen(n)];
|
||||||
for (p = n+1; p < e; p++) {
|
for (p = n + 1; p < e; p++) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (*p != '/')
|
if (*p != '/')
|
||||||
continue;
|
continue;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
if (access(n, F_OK)) {
|
ret = lxc_unpriv(mkdir(n, 0755));
|
||||||
ret = lxc_unpriv(mkdir(n, 0755));
|
if (ret && errno != EEXIST) {
|
||||||
if (ret && errno != EEXIST) {
|
SYSERROR("Failed to create directory %s", n);
|
||||||
SYSERROR("Failed to create directory '%s'", n);
|
free(n);
|
||||||
free(n);
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = '/';
|
*p = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,9 +419,8 @@ static int log_open(const char *name)
|
|||||||
int fd;
|
int fd;
|
||||||
int newfd;
|
int newfd;
|
||||||
|
|
||||||
fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY |
|
fd = lxc_unpriv(open(name, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0666));
|
||||||
O_APPEND | O_CLOEXEC, 0666));
|
if (fd < 0) {
|
||||||
if (fd == -1) {
|
|
||||||
SYSERROR("Failed to open log file \"%s\"", name);
|
SYSERROR("Failed to open log file \"%s\"", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -431,7 +428,7 @@ static int log_open(const char *name)
|
|||||||
if (fd > 2)
|
if (fd > 2)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
newfd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
newfd = fcntl(fd, F_DUPFD_CLOEXEC, STDERR_FILENO);
|
||||||
if (newfd == -1)
|
if (newfd == -1)
|
||||||
SYSERROR("Failed to dup log fd %d", fd);
|
SYSERROR("Failed to dup log fd %d", fd);
|
||||||
|
|
||||||
@ -448,15 +445,17 @@ static int log_open(const char *name)
|
|||||||
static char *build_log_path(const char *name, const char *lxcpath)
|
static char *build_log_path(const char *name, const char *lxcpath)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int len, ret, use_dir;
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
bool use_dir;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#if USE_CONFIGPATH_LOGS
|
#if USE_CONFIGPATH_LOGS
|
||||||
use_dir = 1;
|
use_dir = true;
|
||||||
#else
|
#else
|
||||||
use_dir = 0;
|
use_dir = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -469,7 +468,7 @@ static char *build_log_path(const char *name, const char *lxcpath)
|
|||||||
*/
|
*/
|
||||||
len = strlen(name) + 6; /* 6 == '/' + '.log' + '\0' */
|
len = strlen(name) + 6; /* 6 == '/' + '.log' + '\0' */
|
||||||
if (lxcpath)
|
if (lxcpath)
|
||||||
use_dir = 1;
|
use_dir = true;
|
||||||
else
|
else
|
||||||
lxcpath = LOGPATH;
|
lxcpath = LOGPATH;
|
||||||
|
|
||||||
@ -486,7 +485,7 @@ static char *build_log_path(const char *name, const char *lxcpath)
|
|||||||
ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name);
|
ret = snprintf(p, len, "%s/%s/%s.log", lxcpath, name, name);
|
||||||
else
|
else
|
||||||
ret = snprintf(p, len, "%s/%s.log", lxcpath, name);
|
ret = snprintf(p, len, "%s/%s.log", lxcpath, name);
|
||||||
if (ret < 0 || ret >= len) {
|
if (ret < 0 || (size_t)ret >= len) {
|
||||||
free(p);
|
free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -494,7 +493,7 @@ static char *build_log_path(const char *name, const char *lxcpath)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void lxc_log_close(void)
|
void lxc_log_close(void)
|
||||||
{
|
{
|
||||||
closelog();
|
closelog();
|
||||||
|
|
||||||
@ -562,12 +561,13 @@ static int _lxc_log_set_file(const char *name, const char *lxcpath, int create_d
|
|||||||
ERROR("Could not build log path");
|
ERROR("Could not build log path");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = __lxc_log_set_file(logfile, create_dirs);
|
ret = __lxc_log_set_file(logfile, create_dirs);
|
||||||
free(logfile);
|
free(logfile);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int lxc_log_syslog(int facility)
|
int lxc_log_syslog(int facility)
|
||||||
{
|
{
|
||||||
struct lxc_log_appender *appender;
|
struct lxc_log_appender *appender;
|
||||||
|
|
||||||
@ -595,7 +595,7 @@ extern int lxc_log_syslog(int facility)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void lxc_log_enable_syslog(void)
|
inline void lxc_log_enable_syslog(void)
|
||||||
{
|
{
|
||||||
syslog_enable = 1;
|
syslog_enable = 1;
|
||||||
}
|
}
|
||||||
@ -605,13 +605,13 @@ extern void lxc_log_enable_syslog(void)
|
|||||||
* Called from lxc front-end programs (like lxc-create, lxc-start) to
|
* Called from lxc front-end programs (like lxc-create, lxc-start) to
|
||||||
* initalize the log defaults.
|
* initalize the log defaults.
|
||||||
*/
|
*/
|
||||||
extern int lxc_log_init(struct lxc_log *log)
|
int lxc_log_init(struct lxc_log *log)
|
||||||
{
|
{
|
||||||
int lxc_priority = LXC_LOG_LEVEL_ERROR;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
int lxc_priority = LXC_LOG_LEVEL_ERROR;
|
||||||
|
|
||||||
if (lxc_log_fd != -1) {
|
if (lxc_log_fd != -1) {
|
||||||
WARN("lxc_log_init called with log already initialized");
|
WARN("Log already initialized");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,6 +637,7 @@ extern int lxc_log_init(struct lxc_log *log)
|
|||||||
if (log->file) {
|
if (log->file) {
|
||||||
if (strcmp(log->file, "none") == 0)
|
if (strcmp(log->file, "none") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = __lxc_log_set_file(log->file, 1);
|
ret = __lxc_log_set_file(log->file, 1);
|
||||||
lxc_log_use_global_fd = 1;
|
lxc_log_use_global_fd = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -679,7 +680,7 @@ extern int lxc_log_init(struct lxc_log *log)
|
|||||||
* happens after processing command line arguments, which override the .conf
|
* happens after processing command line arguments, which override the .conf
|
||||||
* settings. So only set the level if previously unset.
|
* settings. So only set the level if previously unset.
|
||||||
*/
|
*/
|
||||||
extern int lxc_log_set_level(int *dest, int level)
|
int lxc_log_set_level(int *dest, int level)
|
||||||
{
|
{
|
||||||
if (level < 0 || level >= LXC_LOG_LEVEL_NOTSET) {
|
if (level < 0 || level >= LXC_LOG_LEVEL_NOTSET) {
|
||||||
ERROR("Invalid log priority %d", level);
|
ERROR("Invalid log priority %d", level);
|
||||||
@ -690,15 +691,16 @@ extern int lxc_log_set_level(int *dest, int level)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int lxc_log_get_level(void)
|
inline int lxc_log_get_level(void)
|
||||||
{
|
{
|
||||||
return lxc_log_category_lxc.priority;
|
return lxc_log_category_lxc.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool lxc_log_has_valid_level(void)
|
bool lxc_log_has_valid_level(void)
|
||||||
{
|
{
|
||||||
int log_level = lxc_log_get_level();
|
int log_level;
|
||||||
|
|
||||||
|
log_level = lxc_log_get_level();
|
||||||
if (log_level < 0 || log_level >= LXC_LOG_LEVEL_NOTSET)
|
if (log_level < 0 || log_level >= LXC_LOG_LEVEL_NOTSET)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -710,42 +712,40 @@ extern bool lxc_log_has_valid_level(void)
|
|||||||
* happens after processing command line arguments, which override the .conf
|
* happens after processing command line arguments, which override the .conf
|
||||||
* settings. So only set the file if previously unset.
|
* settings. So only set the file if previously unset.
|
||||||
*/
|
*/
|
||||||
extern int lxc_log_set_file(int *fd, const char *fname)
|
int lxc_log_set_file(int *fd, const char *fname)
|
||||||
{
|
{
|
||||||
if (*fd != -1) {
|
if (*fd >= 0) {
|
||||||
close(*fd);
|
close(*fd);
|
||||||
*fd = -1;
|
*fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build_dir(fname)) {
|
if (build_dir(fname))
|
||||||
SYSERROR("Failed to create dir for log file \"%s\"", fname);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
*fd = log_open(fname);
|
*fd = log_open(fname);
|
||||||
if (*fd == -1)
|
if (*fd < 0)
|
||||||
return -errno;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char *lxc_log_get_file(void)
|
inline const char *lxc_log_get_file(void)
|
||||||
{
|
{
|
||||||
return log_fname;
|
return log_fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void lxc_log_set_prefix(const char *prefix)
|
inline void lxc_log_set_prefix(const char *prefix)
|
||||||
{
|
{
|
||||||
/* We don't care if thte prefix is truncated. */
|
/* We don't care if thte prefix is truncated. */
|
||||||
(void)strlcpy(log_prefix, prefix, sizeof(log_prefix));
|
(void)strlcpy(log_prefix, prefix, sizeof(log_prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char *lxc_log_get_prefix(void)
|
inline const char *lxc_log_get_prefix(void)
|
||||||
{
|
{
|
||||||
return log_prefix;
|
return log_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void lxc_log_options_no_override()
|
inline void lxc_log_options_no_override()
|
||||||
{
|
{
|
||||||
lxc_quiet_specified = 1;
|
lxc_quiet_specified = 1;
|
||||||
lxc_loglevel_specified = 1;
|
lxc_loglevel_specified = 1;
|
||||||
|
139
src/lxc/macro.h
Normal file
139
src/lxc/macro.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LXC_MACRO_H
|
||||||
|
#define __LXC_MACRO_H
|
||||||
|
|
||||||
|
/* Define __S_ISTYPE if missing from the C library. */
|
||||||
|
#ifndef __S_ISTYPE
|
||||||
|
#define __S_ISTYPE(mode, mask) (((mode)&S_IFMT) == (mask))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBCAP
|
||||||
|
#ifndef CAP_SETFCAP
|
||||||
|
#define CAP_SETFCAP 31
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CAP_MAC_OVERRIDE
|
||||||
|
#define CAP_MAC_OVERRIDE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CAP_MAC_ADMIN
|
||||||
|
#define CAP_MAC_ADMIN 33
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PR_CAPBSET_DROP
|
||||||
|
#define PR_CAPBSET_DROP 24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LO_FLAGS_AUTOCLEAR
|
||||||
|
#define LO_FLAGS_AUTOCLEAR 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CAP_SETUID
|
||||||
|
#define CAP_SETUID 7
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CAP_SETGID
|
||||||
|
#define CAP_SETGID 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* needed for cgroup automount checks, regardless of whether we
|
||||||
|
* have included linux/capability.h or not */
|
||||||
|
#ifndef CAP_SYS_ADMIN
|
||||||
|
#define CAP_SYS_ADMIN 21
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CGROUP_SUPER_MAGIC
|
||||||
|
#define CGROUP_SUPER_MAGIC 0x27e0eb
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CGROUP2_SUPER_MAGIC
|
||||||
|
#define CGROUP2_SUPER_MAGIC 0x63677270
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Useful macros */
|
||||||
|
/* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
|
||||||
|
#define LXC_NUMSTRLEN64 21
|
||||||
|
#define LXC_LINELEN 4096
|
||||||
|
#define LXC_IDMAPLEN 4096
|
||||||
|
#define LXC_MAX_BUFFER 4096
|
||||||
|
/* /proc/ = 6
|
||||||
|
* +
|
||||||
|
* <pid-as-str> = LXC_NUMSTRLEN64
|
||||||
|
* +
|
||||||
|
* /fd/ = 4
|
||||||
|
* +
|
||||||
|
* <fd-as-str> = LXC_NUMSTRLEN64
|
||||||
|
* +
|
||||||
|
* \0 = 1
|
||||||
|
*/
|
||||||
|
#define LXC_PROC_PID_FD_LEN (6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1)
|
||||||
|
|
||||||
|
/* loop devices */
|
||||||
|
#ifndef LO_FLAGS_AUTOCLEAR
|
||||||
|
#define LO_FLAGS_AUTOCLEAR 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LOOP_CTL_GET_FREE
|
||||||
|
#define LOOP_CTL_GET_FREE 0x4C82
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* memfd_create() */
|
||||||
|
#ifndef MFD_CLOEXEC
|
||||||
|
#define MFD_CLOEXEC 0x0001U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MFD_ALLOW_SEALING
|
||||||
|
#define MFD_ALLOW_SEALING 0x0002U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BUILD_BUG_ON - break compile if a condition is true.
|
||||||
|
* @condition: the condition which the compiler should know is false.
|
||||||
|
*
|
||||||
|
* If you have some code which relies on certain constants being equal, or
|
||||||
|
* other compile-time-evaluated condition, you should use BUILD_BUG_ON to
|
||||||
|
* detect if someone changes it.
|
||||||
|
*
|
||||||
|
* The implementation uses gcc's reluctance to create a negative array, but
|
||||||
|
* gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
|
||||||
|
* to inline functions). So as a fallback we use the optimizer; if it can't
|
||||||
|
* prove the condition is false, it will cause a link error on the undefined
|
||||||
|
* "__build_bug_on_failed". This error message can be harder to track down
|
||||||
|
* though, hence the two different methods.
|
||||||
|
*/
|
||||||
|
#ifndef __OPTIMIZE__
|
||||||
|
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
||||||
|
#else
|
||||||
|
extern int __build_bug_on_failed;
|
||||||
|
#define BUILD_BUG_ON(condition) \
|
||||||
|
do { \
|
||||||
|
((void)sizeof(char[1 - 2*!!(condition)])); \
|
||||||
|
if (condition) __build_bug_on_failed = 1; \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define lxc_iterate_parts(__iterator, __splitme, __separators) \
|
||||||
|
for (char *__p = NULL, *__it = strtok_r(__splitme, __separators, &__p); \
|
||||||
|
(__iterator = __it); \
|
||||||
|
__iterator = __it = strtok_r(NULL, __separators, &__p))
|
||||||
|
|
||||||
|
#endif /* __LXC_MACRO_H */
|
117
src/lxc/utils.h
117
src/lxc/utils.h
@ -45,73 +45,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "initutils.h"
|
#include "initutils.h"
|
||||||
|
#include "macro.h"
|
||||||
/* Define __S_ISTYPE if missing from the C library. */
|
|
||||||
#ifndef __S_ISTYPE
|
|
||||||
#define __S_ISTYPE(mode, mask) (((mode)&S_IFMT) == (mask))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_LIBCAP
|
|
||||||
#ifndef CAP_SETFCAP
|
|
||||||
#define CAP_SETFCAP 31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CAP_MAC_OVERRIDE
|
|
||||||
#define CAP_MAC_OVERRIDE 32
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CAP_MAC_ADMIN
|
|
||||||
#define CAP_MAC_ADMIN 33
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PR_CAPBSET_DROP
|
|
||||||
#define PR_CAPBSET_DROP 24
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LO_FLAGS_AUTOCLEAR
|
|
||||||
#define LO_FLAGS_AUTOCLEAR 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CAP_SETUID
|
|
||||||
#define CAP_SETUID 7
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CAP_SETGID
|
|
||||||
#define CAP_SETGID 6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* needed for cgroup automount checks, regardless of whether we
|
|
||||||
* have included linux/capability.h or not */
|
|
||||||
#ifndef CAP_SYS_ADMIN
|
|
||||||
#define CAP_SYS_ADMIN 21
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CGROUP_SUPER_MAGIC
|
|
||||||
#define CGROUP_SUPER_MAGIC 0x27e0eb
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CGROUP2_SUPER_MAGIC
|
|
||||||
#define CGROUP2_SUPER_MAGIC 0x63677270
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Useful macros */
|
|
||||||
/* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
|
|
||||||
#define LXC_NUMSTRLEN64 21
|
|
||||||
#define LXC_LINELEN 4096
|
|
||||||
#define LXC_IDMAPLEN 4096
|
|
||||||
#define LXC_MAX_BUFFER 4096
|
|
||||||
/* /proc/ = 6
|
|
||||||
* +
|
|
||||||
* <pid-as-str> = LXC_NUMSTRLEN64
|
|
||||||
* +
|
|
||||||
* /fd/ = 4
|
|
||||||
* +
|
|
||||||
* <fd-as-str> = LXC_NUMSTRLEN64
|
|
||||||
* +
|
|
||||||
* \0 = 1
|
|
||||||
*/
|
|
||||||
#define LXC_PROC_PID_FD_LEN (6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1)
|
|
||||||
|
|
||||||
/* returns 1 on success, 0 if there were any failures */
|
/* returns 1 on success, 0 if there were any failures */
|
||||||
extern int lxc_rmdir_onedev(const char *path, const char *exclude);
|
extern int lxc_rmdir_onedev(const char *path, const char *exclude);
|
||||||
@ -265,24 +199,6 @@ static inline int signalfd(int fd, const sigset_t *mask, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* loop devices */
|
|
||||||
#ifndef LO_FLAGS_AUTOCLEAR
|
|
||||||
#define LO_FLAGS_AUTOCLEAR 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LOOP_CTL_GET_FREE
|
|
||||||
#define LOOP_CTL_GET_FREE 0x4C82
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* memfd_create() */
|
|
||||||
#ifndef MFD_CLOEXEC
|
|
||||||
#define MFD_CLOEXEC 0x0001U
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MFD_ALLOW_SEALING
|
|
||||||
#define MFD_ALLOW_SEALING 0x0002U
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_MEMFD_CREATE
|
#ifndef HAVE_MEMFD_CREATE
|
||||||
static inline int memfd_create(const char *name, unsigned int flags) {
|
static inline int memfd_create(const char *name, unsigned int flags) {
|
||||||
#ifndef __NR_memfd_create
|
#ifndef __NR_memfd_create
|
||||||
@ -359,32 +275,6 @@ extern struct lxc_popen_FILE *lxc_popen(const char *command);
|
|||||||
*/
|
*/
|
||||||
extern int lxc_pclose(struct lxc_popen_FILE *fp);
|
extern int lxc_pclose(struct lxc_popen_FILE *fp);
|
||||||
|
|
||||||
/**
|
|
||||||
* BUILD_BUG_ON - break compile if a condition is true.
|
|
||||||
* @condition: the condition which the compiler should know is false.
|
|
||||||
*
|
|
||||||
* If you have some code which relies on certain constants being equal, or
|
|
||||||
* other compile-time-evaluated condition, you should use BUILD_BUG_ON to
|
|
||||||
* detect if someone changes it.
|
|
||||||
*
|
|
||||||
* The implementation uses gcc's reluctance to create a negative array, but
|
|
||||||
* gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
|
|
||||||
* to inline functions). So as a fallback we use the optimizer; if it can't
|
|
||||||
* prove the condition is false, it will cause a link error on the undefined
|
|
||||||
* "__build_bug_on_failed". This error message can be harder to track down
|
|
||||||
* though, hence the two different methods.
|
|
||||||
*/
|
|
||||||
#ifndef __OPTIMIZE__
|
|
||||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
|
||||||
#else
|
|
||||||
extern int __build_bug_on_failed;
|
|
||||||
#define BUILD_BUG_ON(condition) \
|
|
||||||
do { \
|
|
||||||
((void)sizeof(char[1 - 2*!!(condition)])); \
|
|
||||||
if (condition) __build_bug_on_failed = 1; \
|
|
||||||
} while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wait on a child we forked
|
* wait on a child we forked
|
||||||
*/
|
*/
|
||||||
@ -620,9 +510,4 @@ extern int lxc_set_death_signal(int signal);
|
|||||||
extern int fd_cloexec(int fd, bool cloexec);
|
extern int fd_cloexec(int fd, bool cloexec);
|
||||||
extern int recursive_destroy(char *dirname);
|
extern int recursive_destroy(char *dirname);
|
||||||
|
|
||||||
#define lxc_iterate_parts(__iterator, __splitme, __separators) \
|
|
||||||
for (char *__p = NULL, *__it = strtok_r(__splitme, __separators, &__p); \
|
|
||||||
(__iterator = __it); \
|
|
||||||
__iterator = __it = strtok_r(NULL, __separators, &__p))
|
|
||||||
|
|
||||||
#endif /* __LXC_UTILS_H */
|
#endif /* __LXC_UTILS_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user