Compare commits
3 Commits
01c5cbf701
...
7b859d0aed
Author | SHA1 | Date | |
---|---|---|---|
7b859d0aed | |||
5cd0a36ced | |||
618f223491 |
68
exile.c
68
exile.c
@ -942,6 +942,11 @@ static int enter_namespaces(int namespace_options)
|
|||||||
{
|
{
|
||||||
if(namespace_options & EXILE_UNSHARE_USER)
|
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);
|
int ret = unshare(CLONE_NEWUSER);
|
||||||
if(ret == -1)
|
if(ret == -1)
|
||||||
{
|
{
|
||||||
@ -949,47 +954,51 @@ static int enter_namespaces(int namespace_options)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t current_uid = getuid();
|
int fd = open("/proc/self/setgroups", O_WRONLY);
|
||||||
gid_t current_gid = getgid();
|
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");
|
fd = open("/proc/self/uid_map", O_WRONLY);
|
||||||
if(fp == NULL)
|
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;
|
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;
|
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");
|
fd = open("/proc/self/gid_map", O_WRONLY);
|
||||||
if(fp == NULL)
|
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;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(namespace_options & EXILE_UNSHARE_MOUNT)
|
if(namespace_options & EXILE_UNSHARE_MOUNT)
|
||||||
@ -1879,13 +1888,6 @@ char *exile_launch_get(struct exile_launch_params *launch_params, size_t *n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(stream);
|
fclose(stream);
|
||||||
int seek = fseek(stream, 0, SEEK_SET);
|
|
||||||
if(seek == -1)
|
|
||||||
{
|
|
||||||
EXILE_LOG_ERROR("fseek failed\n");
|
|
||||||
close(launch_result.read_fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
close(launch_result.read_fd);
|
close(launch_result.read_fd);
|
||||||
*n = size;
|
*n = size;
|
||||||
return result;
|
return result;
|
||||||
|
100
test.c
100
test.c
@ -661,6 +661,104 @@ int test_clone3_nosys()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int do_test_nsuidmap(const char *path, const char *firstfield, const char *secondfield, const char *thirdfield)
|
||||||
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
FILE *fp = fopen(path, "r");
|
||||||
|
|
||||||
|
int ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
while(ret != -1 && strlen(line) == 1 && *line == ' ')
|
||||||
|
ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
if(ret == -1)
|
||||||
|
{
|
||||||
|
LOG("getdelim() failed to read a line from %s\n", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
line[ret-1] = '\0';
|
||||||
|
if(strcmp(line, firstfield) != 0)
|
||||||
|
{
|
||||||
|
LOG("Invalid value for first entry in map: Expected: %s, was: %s\n", firstfield, line);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
while(ret != -1 && strlen(line) == 1 && *line == ' ')
|
||||||
|
ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
if(ret == -1)
|
||||||
|
{
|
||||||
|
LOG("getdelim() failed to read a line from map\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
line[ret-1] = '\0';
|
||||||
|
|
||||||
|
if(strcmp(line, secondfield) != 0)
|
||||||
|
{
|
||||||
|
LOG("Invalid value for second entry in map: Expected: %s, was: %s\n", secondfield, line);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
while(ret != -1 && strlen(line) == 1 && *line == ' ')
|
||||||
|
ret = getdelim(&line, &n, ' ', fp);
|
||||||
|
if(ret == -1)
|
||||||
|
{
|
||||||
|
LOG("getdelim() failed to read a line from uid_map\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
line[ret-1] = '\0';
|
||||||
|
if(strcmp(line, thirdfield) != 0)
|
||||||
|
{
|
||||||
|
LOG("Invalid value for second entry in map: Expected: %s, was: %s\n", thirdfield, line);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_unshare_user()
|
||||||
|
{
|
||||||
|
char uidstr[64];
|
||||||
|
snprintf(uidstr, sizeof(uidstr), "%u", getuid());
|
||||||
|
|
||||||
|
char gidstr[64];
|
||||||
|
snprintf(gidstr, sizeof(gidstr), "%u", getgid());
|
||||||
|
|
||||||
|
struct exile_policy *policy = exile_init_policy();
|
||||||
|
policy->namespace_options = EXILE_UNSHARE_USER;
|
||||||
|
xexile_enable_policy(policy);
|
||||||
|
|
||||||
|
if(do_test_nsuidmap("/proc/self/uid_map", "0", uidstr, "1") != 0)
|
||||||
|
{
|
||||||
|
LOG("/proc/self/uid_map failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(do_test_nsuidmap("/proc/self/gid_map", "0", gidstr, "1") != 0)
|
||||||
|
{
|
||||||
|
LOG("/proc/self/gid_map failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen("/proc/self/setgroups", "r");
|
||||||
|
|
||||||
|
char buffer[4096] = { 0 };
|
||||||
|
fread(buffer, sizeof(buffer), 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if(strcmp(buffer, "deny\n") != 0)
|
||||||
|
{
|
||||||
|
LOG("/proc/self/setgroups does not contain 'deny'\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct dispatcher
|
struct dispatcher
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
@ -689,6 +787,8 @@ struct dispatcher dispatchers[] = {
|
|||||||
{ "launch-get", &test_launch_get},
|
{ "launch-get", &test_launch_get},
|
||||||
{ "vow_from_str", &test_vows_from_str},
|
{ "vow_from_str", &test_vows_from_str},
|
||||||
{ "clone3_nosys", &test_clone3_nosys},
|
{ "clone3_nosys", &test_clone3_nosys},
|
||||||
|
{ "unshare-user", &test_unshare_user},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
3
test.sh
3
test.sh
@ -52,7 +52,8 @@ runtest()
|
|||||||
|
|
||||||
echo -n "Running $testname... "
|
echo -n "Running $testname... "
|
||||||
#exit $? to suppress shell message like "./test.sh: line 18: pid Bad system call"
|
#exit $? to suppress shell message like "./test.sh: line 18: pid Bad system call"
|
||||||
(./$testbin "$testname" || exit $?) 2>&1 | tee 1>/dev/null -a "${test_log_file}"
|
(./$testbin "$testname" || exit $?) >> "${test_log_file}" 2>&1
|
||||||
|
|
||||||
ret=$?
|
ret=$?
|
||||||
SUCCESS="no"
|
SUCCESS="no"
|
||||||
if [ $ret -eq 0 ] ; then
|
if [ $ret -eq 0 ] ; then
|
||||||
|
Loading…
Reference in New Issue
Block a user