mount: nonmandatory mounts
This commit is contained in:
parent
f0cb243a89
commit
ec50c1346d
22
cmdline.c
22
cmdline.c
@ -226,10 +226,10 @@ void cmdlineLogParams(struct nsjconf_t *nsjconf)
|
||||
struct mounts_t *p;
|
||||
TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) {
|
||||
LOG_I
|
||||
("Mount point: src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s",
|
||||
("Mount point: src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s mandatory:%s",
|
||||
p->src ? p->src : "[NULL]", p->dst, p->fs_type ? p->fs_type : "[NULL]",
|
||||
mountFlagsToStr(p->flags), p->options ? p->options : "[NULL]",
|
||||
p->isDir ? "True" : "False");
|
||||
p->isDir ? "true" : "false", p->mandatory ? "true" : "false");
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -644,6 +644,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
p->options = "";
|
||||
p->fs_type = "";
|
||||
p->isDir = mountIsDir(optarg);
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
|
||||
} break;
|
||||
case 'B':{
|
||||
@ -654,6 +655,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
p->options = "";
|
||||
p->fs_type = "";
|
||||
p->isDir = mountIsDir(optarg);
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
|
||||
} break;
|
||||
case 'T':{
|
||||
@ -664,6 +666,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
p->options = cmdlineTmpfsSz;
|
||||
p->fs_type = "tmpfs";
|
||||
p->isDir = true;
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
|
||||
} break;
|
||||
case 'M':
|
||||
@ -749,6 +752,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
p->options = "";
|
||||
p->fs_type = "proc";
|
||||
p->isDir = true;
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
|
||||
}
|
||||
if (nsjconf->chroot != NULL) {
|
||||
@ -756,24 +760,26 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
p->src = nsjconf->chroot;
|
||||
p->dst = "/";
|
||||
p->flags = MS_BIND | MS_REC;
|
||||
p->options = "";
|
||||
p->fs_type = "";
|
||||
p->isDir = true;
|
||||
if (nsjconf->is_root_rw == false) {
|
||||
p->flags |= MS_RDONLY;
|
||||
}
|
||||
p->options = "";
|
||||
p->fs_type = "";
|
||||
p->isDir = true;
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
|
||||
} else {
|
||||
struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
|
||||
p->src = NULL;
|
||||
p->dst = "/";
|
||||
p->flags = 0;
|
||||
p->options = "";
|
||||
p->fs_type = "tmpfs";
|
||||
p->isDir = true;
|
||||
if (nsjconf->is_root_rw == false) {
|
||||
p->flags |= MS_RDONLY;
|
||||
}
|
||||
p->options = "";
|
||||
p->fs_type = "tmpfs";
|
||||
p->isDir = true;
|
||||
p->mandatory = true;
|
||||
TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
|
||||
}
|
||||
|
||||
|
1
common.h
1
common.h
@ -71,6 +71,7 @@ struct mounts_t {
|
||||
const char *options;
|
||||
uintptr_t flags;
|
||||
bool isDir;
|
||||
bool mandatory;
|
||||
TAILQ_ENTRY(mounts_t) pointers;
|
||||
};
|
||||
|
||||
|
4
config.c
4
config.c
@ -181,6 +181,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
|
||||
}
|
||||
}
|
||||
|
||||
nsjconf->mount_proc = njc->mount_proc;
|
||||
for (size_t i = 0; i < njc->n_mount; i++) {
|
||||
struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
|
||||
p->src = utilStrDup(njc->mount[i]->src);
|
||||
@ -200,11 +201,10 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
|
||||
p->isDir = true;
|
||||
}
|
||||
}
|
||||
p->mandatory = njc->mount[i]->mandatory;
|
||||
TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
|
||||
}
|
||||
|
||||
nsjconf->mount_proc = njc->mount_proc;
|
||||
|
||||
if (njc->seccomp_policy_file) {
|
||||
if ((nsjconf->kafel_file = fopen(njc->seccomp_policy_file, "rb")) == NULL) {
|
||||
PLOG_W("Couldn't open file with seccomp policy '%s'",
|
||||
|
@ -7,22 +7,26 @@
|
||||
#endif
|
||||
|
||||
#include "config.pb-c.h"
|
||||
void nsjail__id_map__init(Nsjail__IdMap * message) {
|
||||
void nsjail__id_map__init(Nsjail__IdMap * message)
|
||||
{
|
||||
static Nsjail__IdMap init_value = NSJAIL__ID_MAP__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
|
||||
size_t nsjail__id_map__get_packed_size(const Nsjail__IdMap * message) {
|
||||
size_t nsjail__id_map__get_packed_size(const Nsjail__IdMap * message)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__id_map__descriptor);
|
||||
return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
|
||||
}
|
||||
|
||||
size_t nsjail__id_map__pack(const Nsjail__IdMap * message, uint8_t * out) {
|
||||
size_t nsjail__id_map__pack(const Nsjail__IdMap * message, uint8_t * out)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__id_map__descriptor);
|
||||
return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
|
||||
}
|
||||
|
||||
size_t nsjail__id_map__pack_to_buffer(const Nsjail__IdMap * message, ProtobufCBuffer * buffer) {
|
||||
size_t nsjail__id_map__pack_to_buffer(const Nsjail__IdMap * message, ProtobufCBuffer * buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__id_map__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
|
||||
}
|
||||
@ -33,27 +37,32 @@ Nsjail__IdMap *nsjail__id_map__unpack
|
||||
protobuf_c_message_unpack(&nsjail__id_map__descriptor, allocator, len, data);
|
||||
}
|
||||
|
||||
void nsjail__id_map__free_unpacked(Nsjail__IdMap * message, ProtobufCAllocator * allocator) {
|
||||
void nsjail__id_map__free_unpacked(Nsjail__IdMap * message, ProtobufCAllocator * allocator)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__id_map__descriptor);
|
||||
protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
|
||||
}
|
||||
|
||||
void nsjail__mount_pt__init(Nsjail__MountPt * message) {
|
||||
void nsjail__mount_pt__init(Nsjail__MountPt * message)
|
||||
{
|
||||
static Nsjail__MountPt init_value = NSJAIL__MOUNT_PT__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
|
||||
size_t nsjail__mount_pt__get_packed_size(const Nsjail__MountPt * message) {
|
||||
size_t nsjail__mount_pt__get_packed_size(const Nsjail__MountPt * message)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
|
||||
return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
|
||||
}
|
||||
|
||||
size_t nsjail__mount_pt__pack(const Nsjail__MountPt * message, uint8_t * out) {
|
||||
size_t nsjail__mount_pt__pack(const Nsjail__MountPt * message, uint8_t * out)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
|
||||
return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
|
||||
}
|
||||
|
||||
size_t nsjail__mount_pt__pack_to_buffer(const Nsjail__MountPt * message, ProtobufCBuffer * buffer) {
|
||||
size_t nsjail__mount_pt__pack_to_buffer(const Nsjail__MountPt * message, ProtobufCBuffer * buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
|
||||
}
|
||||
@ -64,52 +73,62 @@ Nsjail__MountPt *nsjail__mount_pt__unpack
|
||||
protobuf_c_message_unpack(&nsjail__mount_pt__descriptor, allocator, len, data);
|
||||
}
|
||||
|
||||
void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator) {
|
||||
void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
|
||||
protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
|
||||
}
|
||||
|
||||
void nsjail__exe__init(Nsjail__Exe * message) {
|
||||
void nsjail__exe__init(Nsjail__Exe * message)
|
||||
{
|
||||
static Nsjail__Exe init_value = NSJAIL__EXE__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
|
||||
size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message) {
|
||||
size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__exe__descriptor);
|
||||
return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
|
||||
}
|
||||
|
||||
size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out) {
|
||||
size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__exe__descriptor);
|
||||
return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
|
||||
}
|
||||
|
||||
size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer) {
|
||||
size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__exe__descriptor);
|
||||
return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
|
||||
}
|
||||
|
||||
Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data) {
|
||||
Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data)
|
||||
{
|
||||
return (Nsjail__Exe *)
|
||||
protobuf_c_message_unpack(&nsjail__exe__descriptor, allocator, len, data);
|
||||
}
|
||||
|
||||
void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator) {
|
||||
void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__exe__descriptor);
|
||||
protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
|
||||
}
|
||||
|
||||
void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message) {
|
||||
void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message)
|
||||
{
|
||||
static Nsjail__NsJailConfig init_value = NSJAIL__NS_JAIL_CONFIG__INIT;
|
||||
*message = init_value;
|
||||
}
|
||||
|
||||
size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message) {
|
||||
size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__ns_jail_config__descriptor);
|
||||
return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
|
||||
}
|
||||
|
||||
size_t nsjail__ns_jail_config__pack(const Nsjail__NsJailConfig * message, uint8_t * out) {
|
||||
size_t nsjail__ns_jail_config__pack(const Nsjail__NsJailConfig * message, uint8_t * out)
|
||||
{
|
||||
assert(message->base.descriptor == &nsjail__ns_jail_config__descriptor);
|
||||
return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
|
||||
}
|
||||
@ -214,10 +233,12 @@ const ProtobufCMessageDescriptor nsjail__id_map__descriptor = {
|
||||
NULL, NULL, NULL /* reserved[123] */
|
||||
};
|
||||
|
||||
char nsjail__mount_pt__fstype__default_value[] = "";
|
||||
char nsjail__mount_pt__options__default_value[] = "";
|
||||
static const protobuf_c_boolean nsjail__mount_pt__is_bind__default_value = 0;
|
||||
static const protobuf_c_boolean nsjail__mount_pt__is_ro__default_value = 0;
|
||||
static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
|
||||
static const protobuf_c_boolean nsjail__mount_pt__mandatory__default_value = 1;
|
||||
static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[8] = {
|
||||
{
|
||||
"src",
|
||||
1,
|
||||
@ -250,7 +271,7 @@ static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
|
||||
0, /* quantifier_offset */
|
||||
offsetof(Nsjail__MountPt, fstype),
|
||||
NULL,
|
||||
NULL,
|
||||
&nsjail__mount_pt__fstype__default_value,
|
||||
0, /* flags */
|
||||
0, NULL, NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
@ -302,6 +323,18 @@ static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
|
||||
0, /* flags */
|
||||
0, NULL, NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"mandatory",
|
||||
8,
|
||||
PROTOBUF_C_LABEL_REQUIRED,
|
||||
PROTOBUF_C_TYPE_BOOL,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(Nsjail__MountPt, mandatory),
|
||||
NULL,
|
||||
&nsjail__mount_pt__mandatory__default_value,
|
||||
0, /* flags */
|
||||
0, NULL, NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
};
|
||||
|
||||
static const unsigned nsjail__mount_pt__field_indices_by_name[] = {
|
||||
@ -310,13 +343,14 @@ static const unsigned nsjail__mount_pt__field_indices_by_name[] = {
|
||||
4, /* field[4] = is_bind */
|
||||
6, /* field[6] = is_dir */
|
||||
5, /* field[5] = is_ro */
|
||||
7, /* field[7] = mandatory */
|
||||
3, /* field[3] = options */
|
||||
0, /* field[0] = src */
|
||||
};
|
||||
|
||||
static const ProtobufCIntRange nsjail__mount_pt__number_ranges[1 + 1] = {
|
||||
{1, 0},
|
||||
{0, 7}
|
||||
{0, 8}
|
||||
};
|
||||
|
||||
const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor = {
|
||||
@ -326,7 +360,7 @@ const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor = {
|
||||
"Nsjail__MountPt",
|
||||
"nsjail",
|
||||
sizeof(Nsjail__MountPt),
|
||||
7,
|
||||
8,
|
||||
nsjail__mount_pt__field_descriptors,
|
||||
nsjail__mount_pt__field_indices_by_name,
|
||||
1, nsjail__mount_pt__number_ranges,
|
||||
|
@ -101,11 +101,16 @@ struct _Nsjail__MountPt {
|
||||
*/
|
||||
protobuf_c_boolean has_is_dir;
|
||||
protobuf_c_boolean is_dir;
|
||||
/*
|
||||
* Should the sandboxing fail if we cannot mount this resource?
|
||||
*/
|
||||
protobuf_c_boolean mandatory;
|
||||
};
|
||||
extern char nsjail__mount_pt__fstype__default_value[];
|
||||
extern char nsjail__mount_pt__options__default_value[];
|
||||
#define NSJAIL__MOUNT_PT__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&nsjail__mount_pt__descriptor) \
|
||||
, NULL, NULL, NULL, nsjail__mount_pt__options__default_value, 0, 0, 0,0 }
|
||||
, NULL, NULL, nsjail__mount_pt__fstype__default_value, nsjail__mount_pt__options__default_value, 0, 0, 0,0, 1 }
|
||||
|
||||
struct _Nsjail__Exe {
|
||||
ProtobufCMessage base;
|
||||
|
@ -41,6 +41,8 @@ message MountPt
|
||||
/* Is it directory? If not specified an internal
|
||||
* heuristics will be used to determine that */
|
||||
optional bool is_dir = 7;
|
||||
/* Should the sandboxing fail if we cannot mount this resource? */
|
||||
required bool mandatory = 8 [default = true];
|
||||
}
|
||||
message Exe
|
||||
{
|
||||
@ -132,11 +134,11 @@ message NsJailConfig
|
||||
repeated IdMap uidmap = 41;
|
||||
repeated IdMap gidmap = 42;
|
||||
|
||||
/* Should /proc be mounted? One can also force this in the 'mount' */
|
||||
required bool mount_proc = 43 [ default = true ];
|
||||
/* Mount points inside the jail. See the description for 'msg MountPt'
|
||||
for more */
|
||||
repeated MountPt mount = 43;
|
||||
/* Should /proc be mounted? One can also force this in the 'mount' */
|
||||
required bool mount_proc = 44 [ default = true ];
|
||||
repeated MountPt mount = 44;
|
||||
|
||||
/* Kafel seccomp policy file or string.
|
||||
Homepage of the project: https://github.com/google/kafel */
|
||||
|
@ -25,7 +25,7 @@ rlimit_as: 128
|
||||
rlimit_core: 0
|
||||
rlimit_cpu: 10
|
||||
rlimit_fsize: 0
|
||||
rlimit_nofile: 5
|
||||
rlimit_nofile: 32
|
||||
rlimit_stack: 1
|
||||
|
||||
persona_addr_compat_layout: false
|
||||
@ -54,6 +54,8 @@ gidmap {
|
||||
count: 1
|
||||
}
|
||||
|
||||
mount_proc: false
|
||||
|
||||
mount {
|
||||
src: "/lib"
|
||||
dst: "/lib"
|
||||
@ -94,6 +96,15 @@ mount {
|
||||
dst: "/lib64"
|
||||
is_bind: true
|
||||
is_ro: true
|
||||
mandatory: false
|
||||
}
|
||||
|
||||
mount {
|
||||
src: "/lib32"
|
||||
dst: "/lib32"
|
||||
is_bind: true
|
||||
is_ro: true
|
||||
mandatory: false
|
||||
}
|
||||
|
||||
mount {
|
||||
@ -124,7 +135,12 @@ mount {
|
||||
is_ro: true
|
||||
}
|
||||
|
||||
mount_proc: false
|
||||
mount {
|
||||
src: "/nonexistent_777"
|
||||
dst: "/nonexistent_777"
|
||||
is_bind: true
|
||||
mandatory: false
|
||||
}
|
||||
|
||||
seccomp_string: "
|
||||
POLICY example {
|
||||
|
13
mount.c
13
mount.c
@ -159,14 +159,17 @@ static bool mountMount(struct nsjconf_t *nsjconf, struct mounts_t *mpt, const ch
|
||||
unsigned long flags = mpt->flags & ~(MS_RDONLY);
|
||||
if (mount(srcpath, dst, mpt->fs_type, flags, mpt->options) == -1) {
|
||||
if (errno == EACCES) {
|
||||
PLOG_E
|
||||
PLOG_W
|
||||
("mount('%s', '%s', type='%s') failed. Try fixing this problem by applying 'chmod o+x' to the '%s' directory and its ancestors",
|
||||
srcpath, dst, mpt->fs_type, nsjconf->chroot);
|
||||
srcpath, dst, mpt->fs_type ? mpt->fs_type : "[NULL]", nsjconf->chroot);
|
||||
} else {
|
||||
PLOG_E("mount('%s', '%s', type='%s') failed", srcpath, dst, mpt->fs_type);
|
||||
PLOG_W("mount('%s', '%s', type='%s') failed", srcpath, dst,
|
||||
mpt->fs_type ? mpt->fs_type : "[NULL]");
|
||||
}
|
||||
if (mpt->mandatory) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -193,9 +196,11 @@ static bool mountRemountRO(struct mounts_t *mpt)
|
||||
mountFlagsToStr(vfs.f_flag), mountFlagsToStr(new_flags));
|
||||
|
||||
if (mount(mpt->dst, mpt->dst, NULL, new_flags, 0) == -1) {
|
||||
PLOG_E("mount('%s', flags:%s)", mpt->dst, mountFlagsToStr(new_flags));
|
||||
PLOG_W("mount('%s', flags:%s)", mpt->dst, mountFlagsToStr(new_flags));
|
||||
if (mpt->mandatory) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user