mirror of
https://github.com/ostreedev/ostree.git
synced 2025-02-21 05:57:45 +03:00
ostbuild: Also allow making directories read-only
This commit is contained in:
parent
a4b249e333
commit
fb5ecdac42
@ -65,6 +65,32 @@ fatal_errno (const char *message)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
typedef struct _BindMount BindMount;
|
||||
struct _BindMount {
|
||||
const char *source;
|
||||
const char *dest;
|
||||
|
||||
unsigned int readonly;
|
||||
|
||||
BindMount *next;
|
||||
};
|
||||
|
||||
static BindMount *
|
||||
reverse_bind_mount_list (BindMount *mount)
|
||||
{
|
||||
BindMount *prev = NULL;
|
||||
|
||||
while (mount)
|
||||
{
|
||||
BindMount *next = mount->next;
|
||||
mount->next = prev;
|
||||
prev = mount;
|
||||
mount = next;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char **argv)
|
||||
@ -74,10 +100,12 @@ main (int argc,
|
||||
const char *program;
|
||||
uid_t ruid, euid, suid;
|
||||
gid_t rgid, egid, sgid;
|
||||
int after_bind_arg_index;
|
||||
int i;
|
||||
int after_mount_arg_index;
|
||||
unsigned int n_mounts = 0;
|
||||
const unsigned int max_mounts = 50; /* Totally arbitrary... */
|
||||
char **program_argv;
|
||||
char **argv_iter;
|
||||
BindMount *bind_mounts = NULL;
|
||||
BindMount *bind_mount_iter;
|
||||
|
||||
if (argc <= 0)
|
||||
return 1;
|
||||
@ -89,22 +117,57 @@ main (int argc,
|
||||
if (argc < 1)
|
||||
fatal ("ROOTDIR argument must be specified");
|
||||
|
||||
after_bind_arg_index = 0;
|
||||
argv_iter = argv;
|
||||
while (after_bind_arg_index < argc
|
||||
&& strcmp (argv[after_bind_arg_index], "--bind") == 0)
|
||||
after_mount_arg_index = 0;
|
||||
while (after_mount_arg_index < argc)
|
||||
{
|
||||
if ((argc - after_bind_arg_index) < 3)
|
||||
fatal ("--bind takes two arguments");
|
||||
after_bind_arg_index += 3;
|
||||
argv_iter += 3;
|
||||
}
|
||||
const char *arg = argv[after_mount_arg_index];
|
||||
BindMount *mount = NULL;
|
||||
|
||||
if ((argc - after_bind_arg_index) < 2)
|
||||
fatal ("usage: %s [--bind SOURCE DEST] ROOTDIR PROGRAM ARGS...", argv0);
|
||||
chroot_dir = argv[after_bind_arg_index];
|
||||
program = argv[after_bind_arg_index+1];
|
||||
program_argv = argv + after_bind_arg_index + 1;
|
||||
if (n_mounts >= max_mounts)
|
||||
fatal ("Too many mounts (maximum of %u)", n_mounts);
|
||||
n_mounts++;
|
||||
|
||||
if (strcmp (arg, "--mount-bind") == 0)
|
||||
{
|
||||
if ((argc - after_mount_arg_index) < 3)
|
||||
fatal ("--mount-bind takes two arguments");
|
||||
|
||||
mount = malloc (sizeof (BindMount));
|
||||
mount->source = argv[after_mount_arg_index+1];
|
||||
mount->dest = argv[after_mount_arg_index+2];
|
||||
mount->readonly = 0;
|
||||
mount->next = bind_mounts;
|
||||
|
||||
bind_mounts = mount;
|
||||
after_mount_arg_index += 3;
|
||||
}
|
||||
else if (strcmp (arg, "--mount-readonly") == 0)
|
||||
{
|
||||
BindMount *mount;
|
||||
|
||||
if ((argc - after_mount_arg_index) < 2)
|
||||
fatal ("--mount-readonly takes one argument");
|
||||
|
||||
mount = malloc (sizeof (BindMount));
|
||||
mount->source = NULL;
|
||||
mount->dest = argv[after_mount_arg_index+1];
|
||||
mount->readonly = 1;
|
||||
mount->next = bind_mounts;
|
||||
|
||||
bind_mounts = mount;
|
||||
after_mount_arg_index += 2;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
bind_mounts = reverse_bind_mount_list (bind_mounts);
|
||||
|
||||
if ((argc - after_mount_arg_index) < 2)
|
||||
fatal ("usage: %s [--mount-readonly DIR] [--mount-bind SOURCE DEST] ROOTDIR PROGRAM ARGS...", argv0);
|
||||
chroot_dir = argv[after_mount_arg_index];
|
||||
program = argv[after_mount_arg_index+1];
|
||||
program_argv = argv + after_mount_arg_index + 1;
|
||||
|
||||
if (getresgid (&rgid, &egid, &sgid) < 0)
|
||||
fatal_errno ("getresgid");
|
||||
@ -145,19 +208,29 @@ main (int argc,
|
||||
fatal_errno ("mount(/, MS_PRIVATE | MS_REC)");
|
||||
|
||||
/* Now let's set up our bind mounts */
|
||||
for (i = 0; i < after_bind_arg_index; i += 3)
|
||||
for (bind_mount_iter = bind_mounts; bind_mount_iter; bind_mount_iter = bind_mount_iter->next)
|
||||
{
|
||||
const char *bind_arg = argv[0]; /* --bind */
|
||||
const char *bind_source = argv[i+1];
|
||||
const char *bind_target = argv[i+2];
|
||||
char *bind_abs_target;
|
||||
char *dest;
|
||||
|
||||
assert (strcmp (bind_arg, "--bind") == 0);
|
||||
asprintf (&dest, "%s%s", chroot_dir, bind_mount_iter->dest);
|
||||
|
||||
asprintf (&bind_abs_target, "%s%s", chroot_dir, bind_target);
|
||||
if (mount (bind_source, bind_abs_target, NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
|
||||
fatal_errno ("mount (MS_BIND)");
|
||||
free (bind_abs_target);
|
||||
if (bind_mount_iter->readonly)
|
||||
{
|
||||
if (mount (dest, dest,
|
||||
NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
|
||||
fatal_errno ("mount (MS_BIND)");
|
||||
if (mount (dest, dest,
|
||||
NULL, MS_BIND | MS_PRIVATE | MS_REMOUNT | MS_RDONLY, NULL) < 0)
|
||||
fatal_errno ("mount (MS_BIND | MS_RDONLY)");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (mount (bind_mount_iter->source, dest,
|
||||
NULL, MS_BIND | MS_PRIVATE, NULL) < 0)
|
||||
fatal_errno ("mount (MS_BIND)");
|
||||
}
|
||||
free (dest);
|
||||
}
|
||||
|
||||
/* Actually perform the chroot. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user