Skip to content

Commit

Permalink
Merge pull request #659 from smcv/issue657
Browse files Browse the repository at this point in the history
Handle EINTR on blocking I/O

Reviewed-by: swick
  • Loading branch information
smcv authored Oct 8, 2024
2 parents 2a55242 + 0c96465 commit 5dab8b8
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 34 deletions.
2 changes: 1 addition & 1 deletion bind-mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ bind_mount (int proc_fd,
if (resolved_dest == NULL)
return BIND_MOUNT_ERROR_REALPATH_DEST;

dest_fd = open (resolved_dest, O_PATH | O_CLOEXEC);
dest_fd = TEMP_FAILURE_RETRY (open (resolved_dest, O_PATH | O_CLOEXEC));
if (dest_fd < 0)
{
if (failing_path != NULL)
Expand Down
35 changes: 13 additions & 22 deletions bubblewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,6 @@
#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */
#endif

#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(expression) \
(__extension__ \
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
__result; }))
#endif

/* We limit the size of a tmpfs to half the architecture's address space,
* to avoid hitting arbitrary limits in the kernel.
* For example, on at least one x86_64 machine, the actual limit seems to be
Expand Down Expand Up @@ -599,7 +590,7 @@ do_init (int event_fd, pid_t initial_pid)

for (lock = lock_files; lock != NULL; lock = lock->next)
{
int fd = open (lock->path, O_RDONLY | O_CLOEXEC);
int fd = TEMP_FAILURE_RETRY (open (lock->path, O_RDONLY | O_CLOEXEC));
if (fd == -1)
die_with_error ("Unable to open lock file %s", lock->path);

Expand All @@ -610,7 +601,7 @@ do_init (int event_fd, pid_t initial_pid)
.l_len = 0
};

if (fcntl (fd, F_SETLK, &l) < 0)
if (TEMP_FAILURE_RETRY (fcntl (fd, F_SETLK, &l)) < 0)
die_with_error ("Unable to lock file %s", lock->path);

/* Keep fd open to hang on to lock */
Expand All @@ -627,7 +618,7 @@ do_init (int event_fd, pid_t initial_pid)
pid_t child;
int status;

child = wait (&status);
child = TEMP_FAILURE_RETRY (wait (&status));
if (child == initial_pid)
{
initial_exit_status = propagate_exit_status (status);
Expand All @@ -638,7 +629,7 @@ do_init (int event_fd, pid_t initial_pid)
int res UNUSED;

val = initial_exit_status + 1;
res = write (event_fd, &val, 8);
res = TEMP_FAILURE_RETRY (write (event_fd, &val, 8));
/* Ignore res, if e.g. the parent died and closed event_fd
we don't want to error out here */
}
Expand Down Expand Up @@ -1062,10 +1053,10 @@ privileged_op (int privileged_op_socket,
if (arg2 != NULL)
strcpy ((char *) buffer + arg2_offset, arg2);

if (write (privileged_op_socket, buffer, buffer_size) != (ssize_t)buffer_size)
if (TEMP_FAILURE_RETRY (write (privileged_op_socket, buffer, buffer_size)) != (ssize_t)buffer_size)
die ("Can't write to privileged_op_socket");

if (read (privileged_op_socket, buffer, 1) != 1)
if (TEMP_FAILURE_RETRY (read (privileged_op_socket, buffer, 1)) != 1)
die ("Can't read from privileged_op_socket");

return;
Expand Down Expand Up @@ -2649,7 +2640,7 @@ namespace_ids_read (pid_t pid)
NsInfo *info;

dir = xasprintf ("%d/ns", pid);
ns_fd = openat (proc_fd, dir, O_PATH);
ns_fd = TEMP_FAILURE_RETRY (openat (proc_fd, dir, O_PATH));

if (ns_fd < 0)
die_with_error ("open /proc/%s/ns failed", dir);
Expand Down Expand Up @@ -2870,7 +2861,7 @@ main (int argc,

/* We need to read stuff from proc during the pivot_root dance, etc.
Lets keep a fd to it open */
proc_fd = open ("/proc", O_PATH);
proc_fd = TEMP_FAILURE_RETRY (open ("/proc", O_PATH));
if (proc_fd == -1)
die_with_error ("Can't open /proc");

Expand Down Expand Up @@ -3037,7 +3028,7 @@ main (int argc,

/* Let child run now that the uid maps are set up */
val = 1;
res = write (child_wait_fd, &val, 8);
res = TEMP_FAILURE_RETRY (write (child_wait_fd, &val, 8));
/* Ignore res, if e.g. the child died and closed child_wait_fd we don't want to error out here */
close (child_wait_fd);

Expand Down Expand Up @@ -3204,12 +3195,12 @@ main (int argc,
op = read_priv_sec_op (unpriv_socket, buffer, sizeof (buffer),
&flags, &perms, &size_arg, &arg1, &arg2);
privileged_op (-1, op, flags, perms, size_arg, arg1, arg2);
if (write (unpriv_socket, buffer, 1) != 1)
if (TEMP_FAILURE_RETRY (write (unpriv_socket, buffer, 1)) != 1)
die ("Can't write to op_socket");
}
while (op != PRIV_SEP_OP_DONE);

waitpid (child, &status, 0);
TEMP_FAILURE_RETRY (waitpid (child, &status, 0));
/* Continue post setup */
}
}
Expand All @@ -3233,7 +3224,7 @@ main (int argc,
* We're aiming to make /newroot the real root, and get rid of /oldroot. To do
* that we need a temporary place to store it before we can unmount it.
*/
{ cleanup_fd int oldrootfd = open ("/", O_DIRECTORY | O_RDONLY);
{ cleanup_fd int oldrootfd = TEMP_FAILURE_RETRY (open ("/", O_DIRECTORY | O_RDONLY));
if (oldrootfd < 0)
die_with_error ("can't open /");
if (chdir ("/newroot") != 0)
Expand Down Expand Up @@ -3281,7 +3272,7 @@ main (int argc,
{
cleanup_fd int sysctl_fd = -1;

sysctl_fd = openat (proc_fd, "sys/user/max_user_namespaces", O_WRONLY);
sysctl_fd = TEMP_FAILURE_RETRY (openat (proc_fd, "sys/user/max_user_namespaces", O_WRONLY));

if (sysctl_fd < 0)
die_with_error ("cannot open /proc/sys/user/max_user_namespaces");
Expand Down
6 changes: 3 additions & 3 deletions network.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ rtnl_send_request (int rtnl_fd,
struct sockaddr_nl dst_addr = { AF_NETLINK, 0 };
ssize_t sent;

sent = sendto (rtnl_fd, (void *) header, header->nlmsg_len, 0,
(struct sockaddr *) &dst_addr, sizeof (dst_addr));
sent = TEMP_FAILURE_RETRY (sendto (rtnl_fd, (void *) header, header->nlmsg_len, 0,
(struct sockaddr *) &dst_addr, sizeof (dst_addr)));
if (sent < 0)
return -1;

Expand All @@ -71,7 +71,7 @@ rtnl_read_reply (int rtnl_fd,

while (1)
{
received = recv (rtnl_fd, buffer, sizeof (buffer), 0);
received = TEMP_FAILURE_RETRY (recv (rtnl_fd, buffer, sizeof (buffer), 0));
if (received < 0)
return -1;

Expand Down
16 changes: 8 additions & 8 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ fdwalk (int proc_fd, int (*cb)(void *data,
int res = 0;
DIR *d;

dfd = openat (proc_fd, "self/fd", O_DIRECTORY | O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY);
dfd = TEMP_FAILURE_RETRY (openat (proc_fd, "self/fd", O_DIRECTORY | O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY));
if (dfd == -1)
return res;

Expand Down Expand Up @@ -459,7 +459,7 @@ write_file_at (int dirfd,
bool res;
int errsv;

fd = openat (dirfd, path, O_RDWR | O_CLOEXEC, 0);
fd = TEMP_FAILURE_RETRY (openat (dirfd, path, O_RDWR | O_CLOEXEC, 0));
if (fd == -1)
return -1;

Expand All @@ -484,7 +484,7 @@ create_file (const char *path,
int res;
int errsv;

fd = creat (path, mode);
fd = TEMP_FAILURE_RETRY (creat (path, mode));
if (fd == -1)
return -1;

Expand Down Expand Up @@ -565,11 +565,11 @@ copy_file (const char *src_path,
int res;
int errsv;

sfd = open (src_path, O_CLOEXEC | O_RDONLY);
sfd = TEMP_FAILURE_RETRY (open (src_path, O_CLOEXEC | O_RDONLY));
if (sfd == -1)
return -1;

dfd = creat (dst_path, mode);
dfd = TEMP_FAILURE_RETRY (creat (dst_path, mode));
if (dfd == -1)
{
errsv = errno;
Expand Down Expand Up @@ -646,7 +646,7 @@ load_file_at (int dirfd,
char *data;
int errsv;

fd = openat (dirfd, path, O_CLOEXEC | O_RDONLY);
fd = TEMP_FAILURE_RETRY (openat (dirfd, path, O_CLOEXEC | O_RDONLY));
if (fd == -1)
return NULL;

Expand Down Expand Up @@ -777,7 +777,7 @@ send_pid_on_socket (int socket)
cred->uid = geteuid ();
cred->gid = getegid ();

if (sendmsg (socket, &msg, 0) < 0)
if (TEMP_FAILURE_RETRY (sendmsg (socket, &msg, 0)) < 0)
die_with_error ("Can't send pid");
}

Expand Down Expand Up @@ -808,7 +808,7 @@ read_pid_from_socket (int socket)
msg.msg_control = control_buf_rcv;
msg.msg_controllen = control_len_rcv;

if (recvmsg (socket, &msg, 0) < 0)
if (TEMP_FAILURE_RETRY (recvmsg (socket, &msg, 0)) < 0)
die_with_error ("Can't read pid from socket");

if (msg.msg_controllen <= 0)
Expand Down
9 changes: 9 additions & 0 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@
#define FALSE 0
typedef int bool;

#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(expression) \
(__extension__ \
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
__result; }))
#endif

#define PIPE_READ_END 0
#define PIPE_WRITE_END 1

Expand Down

0 comments on commit 5dab8b8

Please sign in to comment.