QEMU running under Xen doesn't need mount or IPC functionality.
Create and enter separate namespaces for each of these before
executing QEMU, so that in the event that other restrictions fail, the
process won't be able to even name system mount points or exsting
non-file-based IPC descriptors to attempt to attack them.
Unsharing is something a process can only do to itself (it would
seem); so add an os-specific "dm_preexec_restrict()" hook just before
we exec() the device model.
Also add checks to depriv-process-checker.sh to verify that dm is
running in a new namespace (or at least, a different one than the
caller).
Suggested-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
Changes since v4:
- Fix function prototype for netbsd code
Changes since v3:
- Fix some more style issues
Changes since v2:
- Return an error rather than calling exit()
- Use LOGE() and print to the current stderr fd, rather than
printing to the new stderr fd via write()
- Use r for external return values rather than rc.
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Anthony Perard <anthony.perard@citrix.com>
'''Tested''': Not tested
-## Restrictions / improvements still to do
-
-This lists potential restrictions still to do. It is meant to be
-listed in order of ease of implementation, with low-hanging fruit
-first.
-
## Namespaces for unused functionality (Linux only)
'''Description''': QEMU doesn't use the functionality associated with
[qemu-namespaces]: https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg04723.html
+# Restrictions / improvements still to do
+
+This lists potential restrictions still to do. It is meant to be
+listed in order of ease of implementation, with low-hanging fruit
+first.
+
### Basic RLIMITs
'''Description''': A number of limits on the resources that a given
goto out_close;
if (!rc) { /* inner child */
setsid();
+ if (libxl_defbool_val(b_info->dm_restrict)) {
+ rc = libxl__local_dm_preexec_restrict(gc);
+ if (rc)
+ _exit(-1);
+ }
libxl__exec(gc, null, logfile_w, logfile_w, dm, args, envs);
}
{
return ERROR_NI;
}
+
+int libxl__local_dm_preexec_restrict(libxl__gc *gc)
+{
+ return 0;
+}
_hidden void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state*);
+/*
+ * Called after forking but before executing the local devicemodel.
+ */
+_hidden int libxl__local_dm_preexec_restrict(libxl__gc *gc);
+
/* Stubdom device models. */
typedef struct {
return err;
}
+int libxl__local_dm_preexec_restrict(libxl__gc *gc)
+{
+ int r;
+
+ /* Unshare mount and IPC namespaces. These are unused by QEMU. */
+ r = unshare(CLONE_NEWNS | CLONE_NEWIPC);
+ if (r) {
+ LOGE(ERROR, "libxl: Mount and IPC namespace unfailed");
+ return ERROR_FAIL;
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
{
return ERROR_NI;
}
+
+int libxl__local_dm_preexec_restrict(libxl__gc *gc)
+{
+ return 0;
+}