You might also want to try using [configs/home-documents-with-xorg-no-net.cfg](https://github.com/google/nsjail/blob/master/configs/home-documents-with-xorg-no-net.cfg). You'll have to modify all referrences to _/home/jagger_ to whatever your home directory is, though. After that, you can use it as follows:
<pre>
-$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/evince /home/jagger/Documents/doc.pdf
-$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/geeqie /home/jagger/Documents/
-$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/gv /home/jagger/Documents/doc.pdf
+$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/evince /user/Documents/doc.pdf
+$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/geeqie /user/Documents/
+$ ./nsjail --config configs/home-documents-with-xorg-no-net.cfg -- /usr/bin/gv //user/Documents/doc.pdf
</pre>
***
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);
- p->dst = utilStrDup(njc->mount[i]->dst);
- p->fs_type = utilStrDup(njc->mount[i]->fstype);
- p->options = utilStrDup(njc->mount[i]->options);
- p->flags |= (njc->mount[i]->is_ro ? MS_RDONLY : 0);
- p->flags |= (njc->mount[i]->is_bind ? (MS_BIND | MS_REC) : 0);
- if (njc->mount[i]->has_is_dir) {
- p->isDir = njc->mount[i]->is_dir;
- } else {
- if (njc->mount[i]->src == NULL) {
- p->isDir = true;
- } else if (njc->mount[i]->is_bind) {
- p->isDir = mountIsDir(njc->mount[i]->src);
- } else {
- p->isDir = true;
- }
+ const char *src = njc->mount[i]->src;
+ const char *src_env = njc->mount[i]->prefix_src_env;
+ const char *dst = njc->mount[i]->dst;
+ const char *dst_env = njc->mount[i]->prefix_dst_env;
+ const char *fstype = njc->mount[i]->fstype;
+ const char *options = njc->mount[i]->options;
+
+ uintptr_t flags = njc->mount[i]->is_ro ? MS_RDONLY : 0;
+ flags |= njc->mount[i]->is_bind ? (MS_BIND | MS_REC) : 0;
+ bool mandatory = njc->mount[i]->mandatory;
+
+ const bool *isDir =
+ (njc->mount[i]->has_is_dir) ? (const bool *)&njc->mount[i]->is_dir : NULL;
+
+ if (mountAddMountPt
+ (nsjconf, src, dst, fstype, options, flags, isDir, mandatory, src_env,
+ dst_env) == false) {
+ LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
+ return false;
}
- p->mandatory = njc->mount[i]->mandatory;
- TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
}
if (njc->seccomp_policy_file) {
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 protobuf_c_boolean nsjail__mount_pt__mandatory__default_value = 1;
-static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[8] = {
+static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[10] = {
{
"src",
1,
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
- "dst",
+ "prefix_src_env",
2,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_STRING,
+ 0, /* quantifier_offset */
+ offsetof(Nsjail__MountPt, prefix_src_env),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0, NULL, NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "dst",
+ 3,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
+ {
+ "prefix_dst_env",
+ 4,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_STRING,
+ 0, /* quantifier_offset */
+ offsetof(Nsjail__MountPt, prefix_dst_env),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0, NULL, NULL /* reserved1,reserved2, etc */
+ },
{
"fstype",
- 3,
+ 5,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
},
{
"options",
- 4,
+ 6,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
},
{
"is_bind",
- 5,
+ 7,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_BOOL,
0, /* quantifier_offset */
},
{
"is_ro",
- 6,
+ 8,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_BOOL,
0, /* quantifier_offset */
},
{
"is_dir",
- 7,
+ 9,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BOOL,
offsetof(Nsjail__MountPt, has_is_dir),
},
{
"mandatory",
- 8,
+ 10,
PROTOBUF_C_LABEL_REQUIRED,
PROTOBUF_C_TYPE_BOOL,
0, /* quantifier_offset */
};
static const unsigned nsjail__mount_pt__field_indices_by_name[] = {
- 1, /* field[1] = dst */
- 2, /* field[2] = fstype */
- 4, /* field[4] = is_bind */
- 6, /* field[6] = is_dir */
- 5, /* field[5] = is_ro */
- 7, /* field[7] = mandatory */
- 3, /* field[3] = options */
+ 2, /* field[2] = dst */
+ 4, /* field[4] = fstype */
+ 6, /* field[6] = is_bind */
+ 8, /* field[8] = is_dir */
+ 7, /* field[7] = is_ro */
+ 9, /* field[9] = mandatory */
+ 5, /* field[5] = options */
+ 3, /* field[3] = prefix_dst_env */
+ 1, /* field[1] = prefix_src_env */
0, /* field[0] = src */
};
static const ProtobufCIntRange nsjail__mount_pt__number_ranges[1 + 1] = {
{1, 0},
- {0, 8}
+ {0, 10}
};
const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor = {
"Nsjail__MountPt",
"nsjail",
sizeof(Nsjail__MountPt),
- 8,
+ 10,
nsjail__mount_pt__field_descriptors,
nsjail__mount_pt__field_indices_by_name,
1, nsjail__mount_pt__number_ranges,
* Can be skipped for filesystems like 'proc'
*/
char *src;
+ /*
+ * Should 'src' path be prefixed with this envvar?
+ */
+ char *prefix_src_env;
+ /*
+ * Mount point inside jail
+ */
char *dst;
+ /*
+ * Should 'dst' path be prefixed with this envvar?
+ */
+ char *prefix_dst_env;
/*
* Can be empty for mount --bind mounts
*/
extern char nsjail__mount_pt__options__default_value[];
#define NSJAIL__MOUNT_PT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&nsjail__mount_pt__descriptor) \
- , NULL, NULL, nsjail__mount_pt__fstype__default_value, nsjail__mount_pt__options__default_value, 0, 0, 0,0, 1 }
+ , NULL, NULL, NULL, NULL, nsjail__mount_pt__fstype__default_value, nsjail__mount_pt__options__default_value, 0, 0, 0,0, 1 }
struct _Nsjail__Exe {
ProtobufCMessage base;
{
/* Can be skipped for filesystems like 'proc' */
optional string src = 1;
- required string dst = 2;
+ /* Should 'src' path be prefixed with this envvar? */
+ optional string prefix_src_env = 2;
+ /* Mount point inside jail */
+ required string dst = 3;
+ /* Should 'dst' path be prefixed with this envvar? */
+ optional string prefix_dst_env = 4;
/* Can be empty for mount --bind mounts */
- optional string fstype = 3 [ default = "" ];
+ optional string fstype = 5 [ default = "" ];
/* E.g. size=5000000 for 'tmpfs' */
- required string options = 4 [ default = "" ];
+ required string options = 6 [ default = "" ];
/* Is it 'mount --bind src dst' type of mount */
- required bool is_bind = 5 [ default = false ];
+ required bool is_bind = 7 [ default = false ];
/* It it RO mount */
- required bool is_ro = 6 [ default = false ];
+ required bool is_ro = 8 [ default = false ];
/* Is it directory? If not specified an internal
heuristics will be used to determine that */
- optional bool is_dir = 7;
+ optional bool is_dir = 9;
/* Should the sandboxing fail if we cannot mount this resource? */
- required bool mandatory = 8 [ default = true ];
+ required bool mandatory = 10 [ default = true ];
}
message Exe
{
name: "firefox-with-net"
description: "
-This policy allows to run firefox inside a jail. Access to the
-networking is permitted.
+This policy allows to run firefox inside a jail. Access to networking is
+permitted with thise setup (disable clone_newnet).
The only permitted home directory is $HOME/.mozilla and $HOME/Documents.
-The rest of available FS-resources are are system and X-related files.dires.
-You'll also have to change all references to /home/jagger to make them point
-to your local home directory.
+The rest of available FS-resources are system and X-related files/dirs.
-Run it as:
+Run as:
./nsjail --config configs/firefox-with-net.cfg
You can then go to https://uploadfiles.io/ and try to upload a file in order
-to see how your local directory (also, all system directories) look like
+to see how your local directory (also, all system directories) look like.
"
mode: ONCE
hostname: "FIREFOX"
-cwd: "/home/jagger"
+cwd: "/user"
time_limit: 0
-envar: "HOME=/home/jagger"
+envar: "HOME=/user"
envar: "DISPLAY=:0"
rlimit_as: 4096
}
mount {
- dst: "/home/jagger/"
+ dst: "/user"
fstype: "tmpfs"
is_ro: false
}
mount {
- src: "/home/jagger/Documents"
- dst: "/home/jagger/Documents"
+ prefix_src_env: "HOME"
+ src: "/Documents"
+ dst: "/user/Documents"
is_ro: false
is_bind: true
mandatory: false
}
mount {
- src: "/home/jagger/.mozilla"
- dst: "/home/jagger/.mozilla"
+ prefix_src_env: "HOME"
+ src: "/.mozilla"
+ dst: "/user/.mozilla"
is_bind: true
is_ro: false
mandatory: false
}
mount {
- dst: "/home/jagger/.cache"
+ dst: "/user/.cache"
fstype: "tmpfs"
is_ro: false
}
name: "documents-with-xorg"
description: "
-This policy allows to run many Xorg based tool, which are allowed
-to access $HOME/Documents directory only. Example of use would be:
+This policy allows to run many X-org based tool, which are allowed
+to access $HOME/Documents directory only. An example of use is:
./nsjail --config configs/documents-with-xorg.cfg -- \\
- /usr/bin/geeqie /home/jagger/Documents/
+ /usr/bin/geeqie /user/Documents/
-As nsjail configs don't allow to use variables or envvars, you'll have
-to modify paths referring to '/home/jagger' to whatever your home
-directory is. Also, this policy doesn't allow to access networking"
+What is more, this policy doesn't allow to access networking.
+"
mode: ONCE
hostname: "NSJAIL"
time_limit: 1000
envar: "DISPLAY=:0"
+envar: "HOME=/user"
rlimit_as: 512
rlimit_cpu: 1000
}
mount {
- src: "/home/jagger/Documents"
- dst: "/home/jagger/Documents"
- is_bind: true
+ dst: "/user"
+ fstype: "tmpfs"
+ is_ro: false
}
mount {
- dst: "/home/jagger/.cache"
- fstype: "tmpfs"
- is_ro: false
+ prefix_src_env: "HOME"
+ src: "/Documents"
+ dst: "/user/Documents"
+ is_bind: true
}
mount {
}
return false;
}
+
+bool mountAddMountPt(struct nsjconf_t * nsjconf, const char *src, const char *dst,
+ const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
+ bool mandatory, const char *src_env, const char *dst_env)
+{
+ struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
+
+ if (src_env) {
+ const char *e = getenv(src_env);
+ if (e == NULL) {
+ LOG_W("No such envvar:'%s'", src_env);
+ return false;
+ }
+ if (asprintf((char **)&p->src, "%s%s", e, src ? src : "") == -1) {
+ PLOG_W("asprintf() failed");
+ return false;
+ }
+ } else {
+ p->src = utilStrDup(src);
+ }
+
+ if (dst_env) {
+ const char *e = getenv(dst_env);
+ if (e == NULL) {
+ LOG_W("No such envvar:'%s'", dst_env);
+ return false;
+ }
+ if (asprintf((char **)&p->dst, "%s%s", e, dst ? dst : "") == -1) {
+ PLOG_W("asprintf() failed");
+ return false;
+ }
+ } else {
+ p->dst = utilStrDup(dst);
+ }
+
+ p->fs_type = utilStrDup(fstype);
+ p->options = utilStrDup(options);
+ p->flags = flags;
+ p->isDir = isDir;
+ p->mandatory = mandatory;
+
+ if (isDir) {
+ p->isDir = *isDir;
+ } else {
+ if (p->src == NULL) {
+ p->isDir = true;
+ } else if (p->flags & MS_BIND) {
+ p->isDir = mountIsDir(p->src);
+ } else {
+ p->isDir = true;
+ }
+ }
+
+ TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
+
+ return true;
+}
const char *mountFlagsToStr(uintptr_t flags);
bool mountIsDir(const char *path);
bool mountInitNs(struct nsjconf_t *nsjconf);
+bool mountAddMountPt(struct nsjconf_t *nsjconf, const char *src, const char *dst,
+ const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
+ bool mandatory, const char *src_env, const char *dst_env);
#endif /* NS_MOUNT_H */