return r;
}
+struct generic_userns_exec_data {
+ struct cgfsng_handler_data *d;
+ struct lxc_conf *conf;
+ uid_t origuid; /* target uid in parent namespace */
+ char *path;
+};
+
static int rmdir_wrapper(void *data)
{
- char *path = data;
+ struct generic_userns_exec_data *arg = data;
+ uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid;
+ gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid;
- if (setresgid(0,0,0) < 0)
+ if (setresgid(nsgid, nsgid, nsgid) < 0)
SYSERROR("Failed to setgid to 0");
- if (setresuid(0,0,0) < 0)
+ if (setresuid(nsuid, nsuid, nsuid) < 0)
SYSERROR("Failed to setuid to 0");
if (setgroups(0, NULL) < 0)
SYSERROR("Failed to clear groups");
- return cgroup_rmdir(path);
+ return cgroup_rmdir(arg->path);
}
void recursive_destroy(char *path, struct lxc_conf *conf)
{
int r;
+ struct generic_userns_exec_data wrap;
+
+ wrap.origuid = 0;
+ wrap.d = NULL;
+ wrap.path = path;
+ wrap.conf = conf;
+
if (conf && !lxc_list_empty(&conf->id_map))
- r = userns_exec_1(conf, rmdir_wrapper, path, "rmdir_wrapper");
+ r = userns_exec_1(conf, rmdir_wrapper, &wrap, "rmdir_wrapper");
else
r = cgroup_rmdir(path);
*/
static int chown_cgroup_wrapper(void *data)
{
- struct chown_data *arg = data;
- uid_t destuid;
int i;
+ uid_t destuid;
+ struct generic_userns_exec_data *arg = data;
+ uid_t nsuid = (arg->conf->root_nsuid_map != NULL) ? 0 : arg->conf->init_uid;
+ gid_t nsgid = (arg->conf->root_nsgid_map != NULL) ? 0 : arg->conf->init_gid;
- if (setresgid(0,0,0) < 0)
+ if (setresgid(nsgid, nsgid, nsgid) < 0)
SYSERROR("Failed to setgid to 0");
- if (setresuid(0,0,0) < 0)
+ if (setresuid(nsuid, nsuid, nsuid) < 0)
SYSERROR("Failed to setuid to 0");
if (setgroups(0, NULL) < 0)
SYSERROR("Failed to clear groups");
for (i = 0; hierarchies[i]; i++) {
char *fullpath, *path = hierarchies[i]->fullcgpath;
- if (chown(path, destuid, 0) < 0) {
+ if (chown(path, destuid, nsgid) < 0) {
SYSERROR("Error chowning %s to %d", path, (int) destuid);
return -1;
}
* insists on doing)
*/
fullpath = must_make_path(path, "tasks", NULL);
- if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+ if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
strerror(errno));
if (chmod(fullpath, 0664) < 0)
continue;
fullpath = must_make_path(path, "cgroup.subtree_control", NULL);
- if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+ if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
strerror(errno));
if (chmod(fullpath, 0664) < 0)
free(fullpath);
fullpath = must_make_path(path, "cgroup.threads", NULL);
- if (chown(fullpath, destuid, 0) < 0 && errno != ENOENT)
+ if (chown(fullpath, destuid, nsgid) < 0 && errno != ENOENT)
WARN("Failed chowning %s to %d: %s", fullpath, (int) destuid,
strerror(errno));
if (chmod(fullpath, 0664) < 0)
static bool cgfsng_chown(void *hdata, struct lxc_conf *conf)
{
struct cgfsng_handler_data *d = hdata;
- struct chown_data wrap;
+ struct generic_userns_exec_data wrap;
if (!d)
return false;
if (lxc_list_empty(&conf->id_map))
return true;
- wrap.d = d;
wrap.origuid = geteuid();
+ wrap.path = NULL;
+ wrap.d = d;
+ wrap.conf = conf;
if (userns_exec_1(conf, chown_cgroup_wrapper, &wrap,
"chown_cgroup_wrapper") < 0) {
* Return true if id was found, false otherwise.
*/
bool get_mapped_rootid(struct lxc_conf *conf, enum idtype idtype,
- unsigned long *val)
+ unsigned long *val)
{
struct lxc_list *it;
struct id_map *map;
+ unsigned nsid;
+
+ if (idtype == ID_TYPE_UID)
+ nsid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid;
+ else
+ nsid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid;
lxc_list_for_each(it, &conf->id_map) {
map = it->elem;
if (map->idtype != idtype)
continue;
- if (map->nsid != 0)
+ if (map->nsid != nsid)
continue;
*val = map->hostid;
return true;
}
+
return false;
}
struct id_map *map;
char c = '1';
int ret = -1, status = -1;
+ uid_t nsuid = (conf->root_nsuid_map != NULL) ? 0 : conf->init_uid;
+ gid_t nsgid = (conf->root_nsgid_map != NULL) ? 0 : conf->init_gid;
struct lxc_list *idmap = NULL, *tmplist = NULL;
struct id_map *container_root_uid = NULL, *container_root_gid = NULL,
*host_uid_map = NULL, *host_gid_map = NULL;
/* Find container root mappings. */
euid = geteuid();
- container_root_uid = mapped_nsid_add(conf, 0, ID_TYPE_UID);
+ container_root_uid = mapped_nsid_add(conf, nsuid, ID_TYPE_UID);
if (!container_root_uid) {
DEBUG("Failed to find mapping for container root uid %d", 0);
goto on_error;
host_uid_map = container_root_uid;
egid = getegid();
- container_root_gid = mapped_nsid_add(conf, 0, ID_TYPE_GID);
+ container_root_gid = mapped_nsid_add(conf, nsgid, ID_TYPE_GID);
if (!container_root_gid) {
DEBUG("Failed to find mapping for container root gid %d", 0);
goto on_error;