enter_namespaces(): Fix uid/gid mapping

This was not caught before because a test was missing, fprintf() without ferror()
didn't help, and calling code did not depend on uid maps so far.

Add tests.
这个提交包含在:
2022-12-26 16:38:17 +01:00
父节点 01c5cbf701
当前提交 618f223491
共有 2 个文件被更改,包括 135 次插入26 次删除

61
exile.c
查看文件

@ -942,6 +942,11 @@ static int enter_namespaces(int namespace_options)
{
if(namespace_options & EXILE_UNSHARE_USER)
{
uid_t current_uid = getuid();
gid_t current_gid = getgid();
char buf[1024] = {0};
int ret = unshare(CLONE_NEWUSER);
if(ret == -1)
{
@ -949,47 +954,51 @@ static int enter_namespaces(int namespace_options)
return ret;
}
uid_t current_uid = getuid();
gid_t current_gid = getgid();
int fd = open("/proc/self/setgroups", O_WRONLY);
if(fd == -1)
{
EXILE_LOG_ERROR("Failed to open /proc/self/setgroups for writing");
return -1;
}
int writesize = snprintf(buf, sizeof(buf), "deny");
int writeret = write(fd, buf, writesize);
if(writeret < 0 || writeret < writesize)
{
EXILE_LOG_ERROR("Failed to write to /proc/self/setgroups: %i (%s)\n", writeret, strerror(errno));
return -1;
}
close(fd);
FILE *fp = fopen("/proc/self/setgroups", "w");
if(fp == NULL)
fd = open("/proc/self/uid_map", O_WRONLY);
if(fd == -1)
{
EXILE_LOG_ERROR("fopen failed while trying to deny setgroups\n");
EXILE_LOG_ERROR("Failed to open /proc/self/uid_map for writing");
return -1;
}
if(fprintf(fp, "deny") < 0)
writesize = snprintf(buf, sizeof(buf), "0 %u 1\n", current_uid);
writeret = write(fd, buf, writesize);
if(writeret < 0 || writeret < writesize)
{
EXILE_LOG_ERROR("fprintf failed while trying to write setgroups\n");
EXILE_LOG_ERROR("Failed to write to /proc/self/uid_map: %i (%s)\n", writeret, strerror(errno));
return -1;
}
fclose(fp);
close(fd);
fp = fopen("/proc/self/uid_map", "w");
if(fp == NULL)
{
EXILE_LOG_ERROR("fopen failed while trying to write uid_map\n");
return -1;
}
if(fprintf(fp, "0 %i", current_uid) < 0)
{
EXILE_LOG_ERROR("fprintf failed while trying to write uid_map\n");
return -1;
}
fclose(fp);
fp = fopen("/proc/self/gid_map", "w");
if(fp == NULL)
fd = open("/proc/self/gid_map", O_WRONLY);
if(fd == -1)
{
EXILE_LOG_ERROR("fopen failed while trying to write gid_map\n");
EXILE_LOG_ERROR("Failed to open /proc/self/gid_map for writing");
return -1;
}
if(fprintf(fp, "0 %i", current_gid) < 0)
writesize = snprintf(buf, sizeof(buf), "0 %u 1\n", current_gid);
writeret = write(fd, buf, writesize);
if(writeret < 0 || writeret < writesize)
{
EXILE_LOG_ERROR("fprintf failed while trying to write gid_map\n");
EXILE_LOG_ERROR("Failed to write to /proc/self/gid_map: %i (%s)\n", writeret, strerror(errno));
return -1;
}
fclose(fp);
close(fd);
}
if(namespace_options & EXILE_UNSHARE_MOUNT)