conf: ease backports by carrying unused structs

parent d87de00d
......@@ -928,7 +928,9 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
goto cgroup_prune_tree;
}
if (conf->cgroup_meta.dir)
if (conf->cgroup_meta.monitor_pivot_dir)
pivot_path = must_make_path(conf->cgroup_meta.monitor_pivot_dir, CGROUP_PIVOT, NULL);
else if (conf->cgroup_meta.dir)
pivot_path = must_make_path(conf->cgroup_meta.dir, CGROUP_PIVOT, NULL);
else
pivot_path = must_make_path(CGROUP_PIVOT, NULL);
......
......@@ -2717,6 +2717,7 @@ struct lxc_conf *lxc_conf_init(void)
memset(&new->init_groups, 0, sizeof(lxc_groups_t));
memset(&new->cgroup_meta, 0, sizeof(struct lxc_cgroup));
memset(&new->ns_share, 0, sizeof(char *) * LXC_NS_MAX);
memset(&new->timens, 0, sizeof(struct timens_offsets));
seccomp_conf_init(new);
return new;
......@@ -3967,6 +3968,10 @@ void lxc_conf_free(struct lxc_conf *conf)
lxc_clear_apparmor_raw(conf);
lxc_clear_namespace(conf);
free(conf->cgroup_meta.dir);
free(conf->cgroup_meta.monitor_dir);
free(conf->cgroup_meta.monitor_pivot_dir);
free(conf->cgroup_meta.container_dir);
free(conf->cgroup_meta.namespace_dir);
free(conf->cgroup_meta.controllers);
free(conf->shmount.path_host);
free(conf->shmount.path_cont);
......
......@@ -65,6 +65,7 @@ struct lxc_cgroup {
char *controllers;
char *dir;
char *monitor_dir;
char *monitor_pivot_dir;
char *container_dir;
char *namespace_dir;
bool relative;
......@@ -286,6 +287,16 @@ struct bpf_devices {
struct lxc_list device_item;
};
struct timens_offsets {
/* Currently, either s_boot or ns_boot is set, but not both. */
int64_t s_boot;
int64_t ns_boot;
/* Currently, either s_monotonic or ns_monotonic is set, but not both. */
int64_t s_monotonic;
int64_t ns_monotonic;
};
struct lxc_conf {
/* Pointer to the name of the container. Do not free! */
const char *name;
......@@ -456,6 +467,8 @@ struct lxc_conf {
/* Absolute path (in the container) to the shared mount point */
char *path_cont;
} shmount;
struct timens_offsets timens;
};
__hidden extern int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf, size_t buf_size)
......
......@@ -82,6 +82,7 @@ __hidden extern FILE *fdopen_at(int dfd, const char *path, const char *mode,
unsigned int o_flags,
unsigned int resolve_flags);
__hidden extern FILE *fopen_cached(const char *path, const char *mode, void **caller_freed_buffer);
__hidden extern int timens_offset_write(clockid_t clk_id, int64_t s_offset, int64_t ns_offset);
__hidden extern bool exists_dir_at(int dir_fd, const char *path);
__hidden extern bool exists_file_at(int dir_fd, const char *path);
__hidden extern int open_at(int dfd, const char *path, unsigned int o_flags,
......
......@@ -45,6 +45,7 @@ const struct ns_info ns_info[LXC_NS_MAX] = {
[LXC_NS_IPC] = { "ipc", "ns/ipc", CLONE_NEWIPC, "CLONE_NEWIPC", "LXC_IPC_NS" },
[LXC_NS_NET] = { "net", "ns/net", CLONE_NEWNET, "CLONE_NEWNET", "LXC_NET_NS" },
[LXC_NS_CGROUP] = { "cgroup", "ns/cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP", "LXC_CGROUP_NS" },
[LXC_NS_TIME] = { "time", "ns/time", CLONE_NEWTIME, "CLONE_NEWTIME", "LXC_TIME_NS" },
};
int lxc_namespace_2_cloneflag(const char *namespace)
......
......@@ -17,6 +17,7 @@ typedef enum lxc_namespace_t {
LXC_NS_IPC = 4,
LXC_NS_NET = 5,
LXC_NS_CGROUP = 6,
LXC_NS_TIME = 7,
LXC_NS_MAX = 8
} lxc_namespace_t;
......
......@@ -1197,6 +1197,55 @@ static int do_start(void *data)
}
}
if (handler->ns_unshare_flags & CLONE_NEWTIME) {
ret = unshare(CLONE_NEWTIME);
if (ret < 0) {
if (errno != EINVAL) {
SYSERROR("Failed to unshare CLONE_NEWTIME");
goto out_warn_father;
}
handler->ns_clone_flags &= ~CLONE_NEWTIME;
SYSINFO("Kernel does not support CLONE_NEWTIME");
} else {
__do_close int timens_fd = -EBADF;
INFO("Unshared CLONE_NEWTIME");
if (handler->conf->timens.s_boot)
ret = timens_offset_write(CLOCK_BOOTTIME, handler->conf->timens.s_boot, 0);
else if (handler->conf->timens.ns_boot)
ret = timens_offset_write(CLOCK_BOOTTIME, 0, handler->conf->timens.ns_boot);
if (ret) {
SYSERROR("Failed to write CLONE_BOOTTIME offset");
goto out_warn_father;
}
TRACE("Wrote CLOCK_BOOTTIME offset");
if (handler->conf->timens.s_monotonic)
ret = timens_offset_write(CLOCK_MONOTONIC, handler->conf->timens.s_monotonic, 0);
else if (handler->conf->timens.ns_monotonic)
ret = timens_offset_write(CLOCK_MONOTONIC, 0, handler->conf->timens.ns_monotonic);
if (ret) {
SYSERROR("Failed to write CLONE_MONOTONIC offset");
goto out_warn_father;
}
TRACE("Wrote CLOCK_MONOTONIC offset");
timens_fd = open("/proc/self/ns/time_for_children", O_RDONLY | O_CLOEXEC);
if (timens_fd < 0) {
SYSERROR("Failed to open \"/proc/self/ns/time_for_children\"");
goto out_warn_father;
}
ret = setns(timens_fd, CLONE_NEWTIME);
if (ret) {
SYSERROR("Failed to setns(%d(\"/proc/self/ns/time_for_children\"))", timens_fd);
goto out_warn_father;
}
}
}
/* Add the requested environment variables to the current environment to
* allow them to be used by the various hooks, such as the start hook
* below.
......@@ -1434,6 +1483,8 @@ int resolve_clone_flags(struct lxc_handler *handler)
{
int i;
struct lxc_conf *conf = handler->conf;
bool wants_timens = conf->timens.s_boot || conf->timens.ns_boot ||
conf->timens.s_monotonic || conf->timens.ns_monotonic;
for (i = 0; i < LXC_NS_MAX; i++) {
if (conf->ns_keep) {
......@@ -1452,6 +1503,9 @@ int resolve_clone_flags(struct lxc_handler *handler)
if (i == LXC_NS_CGROUP && !cgns_supported())
continue;
if (i == LXC_NS_TIME && !wants_timens)
continue;
handler->ns_clone_flags |= ns_info[i].clone_flag;
}
......@@ -1462,6 +1516,13 @@ int resolve_clone_flags(struct lxc_handler *handler)
TRACE("Sharing %s namespace", ns_info[i].proc_name);
}
if (wants_timens && (conf->ns_keep & ns_info[LXC_NS_TIME].clone_flag))
return log_trace_errno(-1, EINVAL, "Requested to keep time namespace while also specifying offsets");
/* Deal with namespaces that are unshared. */
if (handler->ns_clone_flags & CLONE_NEWTIME)
handler->ns_unshare_flags |= CLONE_NEWTIME;
if (!pure_unified_layout(handler->cgroup_ops) && handler->ns_clone_flags & CLONE_NEWCGROUP)
handler->ns_unshare_flags |= CLONE_NEWCGROUP;
......@@ -1830,6 +1891,17 @@ static int lxc_spawn(struct lxc_handler *handler)
cgroup_ops->finalize(cgroup_ops);
TRACE("Finished setting up cgroups");
if (handler->ns_unshare_flags & CLONE_NEWTIME) {
/* Now we're ready to preserve the time namespace */
ret = lxc_try_preserve_namespace(handler, LXC_NS_TIME, "time");
if (ret < 0) {
if (ret != -ENOENT) {
SYSERROR("Failed to preserve time namespace");
goto out_delete_net;
}
}
}
/* Run any host-side start hooks */
ret = run_lxc_hooks(name, "start-host", conf, NULL);
if (ret < 0) {
......
......@@ -665,6 +665,51 @@ int lxc_safe_uint64(const char *numstr, uint64_t *converted, int base)
return 0;
}
int lxc_safe_int64_residual(const char *numstr, int64_t *converted, int base, char *residual,
size_t residual_len)
{
char *remaining = NULL;
int64_t u;
if (residual && residual_len == 0)
return ret_errno(EINVAL);
if (!residual && residual_len != 0)
return ret_errno(EINVAL);
while (isspace(*numstr))
numstr++;
errno = 0;
u = strtoll(numstr, &remaining, base);
if (errno == ERANGE && u == INT64_MAX)
return -ERANGE;
if (remaining == numstr)
return -EINVAL;
if (residual) {
size_t len = 0;
if (*remaining == '\0') {
memset(residual, 0, residual_len);
goto out;
}
len = strlen(remaining);
if (len >= residual_len)
return -EINVAL;
memcpy(residual, remaining, len);
} else if (*remaining != '\0') {
return -EINVAL;
}
out:
*converted = u;
return 0;
}
int lxc_safe_int(const char *numstr, int *converted)
{
char *err = NULL;
......
......@@ -74,6 +74,8 @@ __hidden extern int lxc_safe_long(const char *numstr, long int *converted);
__hidden extern int lxc_safe_long_long(const char *numstr, long long int *converted);
__hidden extern int lxc_safe_ulong(const char *numstr, unsigned long *converted);
__hidden extern int lxc_safe_uint64(const char *numstr, uint64_t *converted, int base);
__hidden extern int lxc_safe_int64_residual(const char *numstr, int64_t *converted, int base,
char *residual, size_t residual_len);
/* Handles B, kb, MB, GB. Detects overflows and reports -ERANGE. */
__hidden extern int parse_byte_size_string(const char *s, int64_t *converted);
......
......@@ -1844,6 +1844,18 @@ int fix_stdio_permissions(uid_t uid)
return fret;
}
bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res)
{
if (base > 0 && base > (INT64_MAX / mult))
return false;
if (base < 0 && base < (INT64_MIN / mult))
return false;
*res = base * mult;
return true;
}
int print_r(int fd, const char *path)
{
__do_close int dfd = -EBADF, dfd_dup = -EBADF;
......
......@@ -237,6 +237,8 @@ static inline bool gid_valid(gid_t gid)
return gid != LXC_INVALID_GID;
}
__hidden extern bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res);
__hidden extern int safe_mount_beneath(const char *beneath, const char *src, const char *dst,
const char *fstype, unsigned int flags, const void *data);
__hidden extern int safe_mount_beneath_at(int beneat_fd, const char *src, const char *dst,
......
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