-
Notifications
You must be signed in to change notification settings - Fork 273
Add an option to use private (instead of slave) propagation for bind mounts. #522
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -241,7 +241,6 @@ parse_mountinfo (int proc_fd, | |
| int max_id; | ||
| unsigned int n_lines; | ||
| int root; | ||
|
|
||
| mountinfo = load_file_at (proc_fd, "self/mountinfo"); | ||
| if (mountinfo == NULL) | ||
| die_with_error ("Can't open /proc/self/mountinfo"); | ||
|
|
@@ -376,6 +375,7 @@ parse_mountinfo (int proc_fd, | |
|
|
||
| bind_mount_result | ||
| bind_mount (int proc_fd, | ||
| int p_priv, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like it should be a rather than or |
||
| const char *src, | ||
| const char *dest, | ||
| bind_option_t options) | ||
|
|
@@ -391,10 +391,12 @@ bind_mount (int proc_fd, | |
| cleanup_free char *kernel_case_combination = NULL; | ||
| cleanup_fd int dest_fd = -1; | ||
| int i; | ||
|
|
||
| int current_propagation = 0; | ||
| if (p_priv == 1) | ||
| current_propagation = MS_PRIVATE; | ||
| if (src) | ||
| { | ||
| if (mount (src, dest, NULL, MS_SILENT | MS_BIND | (recursive ? MS_REC : 0), NULL) != 0) | ||
| if (mount (src, dest, NULL, MS_SILENT | MS_BIND | current_propagation | (recursive ? MS_REC : 0), NULL) != 0) | ||
| return BIND_MOUNT_ERROR_MOUNT; | ||
| } | ||
|
|
||
|
|
@@ -436,7 +438,7 @@ bind_mount (int proc_fd, | |
| new_flags = current_flags | (devices ? 0 : MS_NODEV) | MS_NOSUID | (readonly ? MS_RDONLY : 0); | ||
| if (new_flags != current_flags && | ||
| mount ("none", resolved_dest, | ||
| NULL, MS_SILENT | MS_BIND | MS_REMOUNT | new_flags, NULL) != 0) | ||
| NULL, MS_SILENT | MS_BIND | MS_REMOUNT | new_flags | current_propagation, NULL) != 0) | ||
| return BIND_MOUNT_ERROR_REMOUNT_DEST; | ||
|
|
||
| /* We need to work around the fact that a bind mount does not apply the flags, so we need to manually | ||
|
|
@@ -451,7 +453,7 @@ bind_mount (int proc_fd, | |
| new_flags = current_flags | (devices ? 0 : MS_NODEV) | MS_NOSUID | (readonly ? MS_RDONLY : 0); | ||
| if (new_flags != current_flags && | ||
| mount ("none", mount_tab[i].mountpoint, | ||
| NULL, MS_SILENT | MS_BIND | MS_REMOUNT | new_flags, NULL) != 0) | ||
| NULL, MS_SILENT | MS_BIND | MS_REMOUNT | new_flags | current_propagation, NULL) != 0) | ||
| { | ||
| /* If we can't read the mountpoint we can't remount it, but that should | ||
| be safe to ignore because its not something the user can access. */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,6 +85,7 @@ int opt_userns_block_fd = -1; | |
| int opt_info_fd = -1; | ||
| int opt_json_status_fd = -1; | ||
| int opt_seccomp_fd = -1; | ||
| int opt_propagation = 0; | ||
| const char *opt_sandbox_hostname = NULL; | ||
| char *opt_args_data = NULL; /* owned */ | ||
| int opt_userns_fd = -1; | ||
|
|
@@ -331,6 +332,7 @@ usage (int ecode, FILE *out) | |
| " --symlink SRC DEST Create symlink at DEST with target SRC\n" | ||
| " --seccomp FD Load and use seccomp rules from FD (not repeatable)\n" | ||
| " --add-seccomp-fd FD Load and use seccomp rules from FD (repeatable)\n" | ||
| " --private Set mount propagation to private\n" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if |
||
| " --block-fd FD Block on FD until some data to read is available\n" | ||
| " --userns-block-fd FD Block on FD until the user namespace is ready\n" | ||
| " --info-fd FD Write information about the running container to FD\n" | ||
|
|
@@ -1070,7 +1072,7 @@ privileged_op (int privileged_op_socket, | |
| break; | ||
|
|
||
| case PRIV_SEP_OP_REMOUNT_RO_NO_RECURSIVE: | ||
| bind_result = bind_mount (proc_fd, NULL, arg2, BIND_READONLY); | ||
| bind_result = bind_mount (proc_fd, opt_propagation, NULL, arg2, BIND_READONLY); | ||
|
|
||
| if (bind_result != BIND_MOUNT_SUCCESS) | ||
| die_with_bind_result (bind_result, errno, | ||
|
|
@@ -1081,7 +1083,7 @@ privileged_op (int privileged_op_socket, | |
| case PRIV_SEP_OP_BIND_MOUNT: | ||
| /* We always bind directories recursively, otherwise this would let us | ||
| access files that are otherwise covered on the host */ | ||
| bind_result = bind_mount (proc_fd, arg1, arg2, BIND_RECURSIVE | flags); | ||
| bind_result = bind_mount (proc_fd, opt_propagation, arg1, arg2, BIND_RECURSIVE | flags); | ||
|
|
||
| if (bind_result != BIND_MOUNT_SUCCESS) | ||
| die_with_bind_result (bind_result, errno, | ||
|
|
@@ -2149,6 +2151,8 @@ parse_args_recurse (int *argcp, | |
| argv += 1; | ||
| argc -= 1; | ||
| } | ||
| else if (strcmp (arg, "--private") == 0) | ||
| opt_propagation = 1; | ||
| else if (strcmp (arg, "--add-seccomp-fd") == 0) | ||
| { | ||
| int the_fd; | ||
|
|
@@ -2956,7 +2960,12 @@ main (int argc, | |
| /* Mark everything as slave, so that we still | ||
| * receive mounts from the real root, but don't | ||
| * propagate mounts to the real root. */ | ||
| if (mount (NULL, "/", NULL, MS_SILENT | MS_SLAVE | MS_REC, NULL) < 0) | ||
| int current_propagation; | ||
| if (opt_propagation == 0) | ||
| current_propagation = MS_SLAVE; | ||
| else | ||
| current_propagation = MS_PRIVATE; | ||
| if (mount (NULL, "/", NULL, MS_SILENT | current_propagation | MS_REC, NULL) < 0) | ||
| die_with_error ("Failed to make / slave"); | ||
|
|
||
| /* Create a tmpfs which we will use as / in the namespace */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't adjust whitespace in locations that you're not otherwise editing.
This blank line is intentional: bubblewrap is mostly written in a C89 style where variable declarations must come before statements, and when writing in that style it's common to have an empty line between the last variable declaration and the first statement.