Skip to content

Commit 1f125c1

Browse files
committed
Add command-pid member to --json-status-fd
In cases where bwrap runs its own additional PID 1 process (e.g. --unshare-pid), child-pid is the PID of that process, not the PID of the user-specified COMMAND. This is inconvenient as the user might want to send e.g. SIGTERM to the command to give it a chance to exit gracefully. Closes #553
1 parent 9286389 commit 1f125c1

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

bubblewrap.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,6 +2630,7 @@ main (int argc,
26302630
int clone_flags;
26312631
char *old_cwd = NULL;
26322632
pid_t pid;
2633+
pid_t command_pid;
26332634
int event_fd = -1;
26342635
int child_wait_fd = -1;
26352636
int setup_finished_pipe[] = {-1, -1};
@@ -2641,6 +2642,7 @@ main (int argc,
26412642
int res UNUSED;
26422643
cleanup_free char *args_data UNUSED = NULL;
26432644
int intermediate_pids_sockets[2] = {-1, -1};
2645+
int command_pid_sockets[2] = {-1, -1};
26442646

26452647
/* Handle --version early on before we try to acquire/drop
26462648
* any capabilities so it works in a build environment;
@@ -2872,6 +2874,14 @@ main (int argc,
28722874
create_pid_socketpair (intermediate_pids_sockets);
28732875
}
28742876

2877+
/* Sometimes we spawn command as immediate child, sometimes we run pid 1, sometimes there are more intermediate pids...
2878+
* For simplicity, get pid just before exec'ing command to get the real pid.
2879+
**/
2880+
if (opt_json_status_fd != -1)
2881+
{
2882+
create_pid_socketpair (command_pid_sockets);
2883+
}
2884+
28752885
pid = raw_clone (clone_flags, NULL);
28762886
if (pid == -1)
28772887
{
@@ -2961,6 +2971,16 @@ main (int argc,
29612971
/* Ignore res, if e.g. the child died and closed child_wait_fd we don't want to error out here */
29622972
close (child_wait_fd);
29632973

2974+
close (command_pid_sockets[1]);
2975+
command_pid = read_pid_from_socket (command_pid_sockets[0]);
2976+
close (command_pid_sockets[0]);
2977+
2978+
if (opt_json_status_fd != -1)
2979+
{
2980+
cleanup_free char *output = xasprintf ("{ \"command-pid\": %i }\n", command_pid);
2981+
dump_info (opt_json_status_fd, output, TRUE);
2982+
}
2983+
29642984
return monitor_child (event_fd, pid, setup_finished_pipe[0]);
29652985
}
29662986

@@ -3319,6 +3339,13 @@ main (int argc,
33193339

33203340
__debug__ (("launch executable %s\n", argv[0]));
33213341

3342+
if (opt_json_status_fd != -1)
3343+
{
3344+
close (command_pid_sockets[0]);
3345+
send_pid_on_socket (command_pid_sockets[1]);
3346+
close (command_pid_sockets[1]);
3347+
}
3348+
33223349
if (proc_fd != -1)
33233350
close (proc_fd);
33243351

bwrap.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,17 +439,25 @@
439439
Multiple JSON documents are written to <arg choice="plain">FD</arg>,
440440
one per line (<ulink url="https://jsonlines.org/">"JSON lines" format</ulink>).
441441
Each line is a single JSON object.
442+
</para><para>
442443
After <command>bwrap</command> has started the child process inside the sandbox,
443444
it writes an object with a <literal>child-pid</literal> member to the
444445
<option>--json-status-fd</option> (this duplicates the older <option>--info-fd</option>).
445446
The corresponding value is the process ID of the child process in the pid namespace from
446447
which <command>bwrap</command> was run.
447448
If available, the namespace IDs are also included in the object with the <literal>child-pid</literal>;
448449
again, this duplicates the older <option>--info-fd</option>.
450+
</para><para>
451+
Just before COMMAND is exec'ed, the process writes its process ID with a <literal>command-pid</literal>
452+
member. This process ID is the PID of COMMAND, and it might not match <literal>child-pid</literal>
453+
mentioned above if <command>bwrap</command> runs additional pid 1 process(e.g. when using
454+
<option>--unshare-pid</option>).
455+
</para><para>
449456
When the child process inside the sandbox exits, <command>bwrap</command> writes an object
450457
with an exit-code member, and then closes the <option>--json-status-fd</option>. The value
451458
corresponding to <literal>exit-code</literal> is the exit status of the child, in the usual
452459
shell encoding (n if it exited normally with status n, or 128+n if it was killed by signal n).
460+
</para><para>
453461
Other members may be added to those objects in future versions of <command>bwrap</command>,
454462
and other JSON objects may be added before or after the current objects, so readers must
455463
ignore members and objects that they do not understand.

0 commit comments

Comments
 (0)