mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 13:58:22 +00:00
Merge tests: fix userns setns opening pipe order
setns tests part of the userns could fail if the parent process opened the child pipe to write it was done before the child opened the pipe with read permissions. From the fifo(7) man page: A process can open a FIFO in nonblocking mode. In this case, opening for read‐only succeeds even if no one has opened on the write side yet and opening for write‐only fails with ENXIO (no such device or address) unless the other end has already been opened. Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com> MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1093 Approved-by: John Johansen <john@jjmx.net> Merged-by: John Johansen <john@jjmx.net>
This commit is contained in:
@@ -58,6 +58,7 @@ int userns_setns(char *client, char *pipename)
|
||||
{
|
||||
int userns, exit_status, ret;
|
||||
char *parentpipe = NULL, *childpipe = NULL;
|
||||
int parentpipefd;
|
||||
|
||||
if (get_pipes(pipename, &parentpipe, &childpipe) == -1) {
|
||||
fprintf(stderr, "FAIL - failed to allocate pipes\n");
|
||||
@@ -81,7 +82,14 @@ int userns_setns(char *client, char *pipename)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_from_pipe(parentpipe) == -1) { // wait for child to unshare
|
||||
parentpipefd = open_read_pipe(parentpipe);
|
||||
if (parentpipefd == -1) {
|
||||
fprintf(stderr, "FAIL - couldn't open parent pipe\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_from_pipe(parentpipefd) == -1) { // wait for child to unshare
|
||||
fprintf(stderr, "FAIL - parent could not read from pipe\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
|
@@ -15,16 +15,26 @@ int get_pipes(const char *pipename, char **parentpipe, char **childpipe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_from_pipe(char *pipename)
|
||||
int open_read_pipe(char *pipename)
|
||||
{
|
||||
int fd, ret;
|
||||
int fd;
|
||||
fd = open(pipename, O_RDONLY | O_NONBLOCK);
|
||||
if (fd == -1) {
|
||||
perror("FAIL - open read pipe");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int read_from_pipe(int fd)
|
||||
{
|
||||
int ret;
|
||||
char buf;
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
|
||||
fd = open(pipename, O_RDONLY | O_NONBLOCK);
|
||||
if (fd == -1) {
|
||||
perror("FAIL - open read pipe");
|
||||
fprintf(stderr, "FAIL - invalid read fd\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -59,7 +69,7 @@ int write_to_pipe(char *pipename)
|
||||
|
||||
fd = open(pipename, O_WRONLY | O_NONBLOCK);
|
||||
if (fd == -1) {
|
||||
perror("FAIL - open write pipe");
|
||||
fprintf(stderr, "FAIL - open write pipe %s - %m\n", pipename);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
close(fd);
|
||||
|
@@ -13,6 +13,7 @@ int main(int argc, char *argv[])
|
||||
int ret;
|
||||
char *pipename = "/tmp/userns_pipe";
|
||||
char *parentpipe = NULL, *childpipe = NULL;
|
||||
int childpipefd;
|
||||
|
||||
if (argc > 1)
|
||||
pipename = argv[1];
|
||||
@@ -26,6 +27,13 @@ int main(int argc, char *argv[])
|
||||
if (mkfifo(childpipe, 0666) == -1)
|
||||
perror("FAIL - setns child mkfifo");
|
||||
|
||||
childpipefd = open_read_pipe(childpipe);
|
||||
if (childpipefd == -1) {
|
||||
fprintf(stderr, "FAIL - couldn't open child pipe\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (unshare(CLONE_NEWUSER) == -1) {
|
||||
perror("FAIL - unshare");
|
||||
ret = EXIT_FAILURE;
|
||||
@@ -37,7 +45,7 @@ int main(int argc, char *argv[])
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
}
|
||||
if (read_from_pipe(childpipe) == -1) { // wait for parent tell child can finish
|
||||
if (read_from_pipe(childpipefd) == -1) { // wait for parent tell child can finish
|
||||
fprintf(stderr, "FAIL - child could not read from pipe\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto out;
|
||||
|
Reference in New Issue
Block a user