[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.17] libxl: limit bootloader execution in restricted mode
commit 46d00dbf4c22b28910f73f66a03e5cabe50b5395 Author: Roger Pau Monne <roger.pau@xxxxxxxxxx> AuthorDate: Thu Sep 28 12:22:35 2023 +0200 Commit: Roger Pau Monne <roger.pau@xxxxxxxxxx> CommitDate: Fri Sep 29 15:54:00 2023 +0200 libxl: limit bootloader execution in restricted mode Introduce a timeout for bootloader execution when running in restricted mode. Allow overwriting the default time out with an environment provided value. This is part of XSA-443 / CVE-2023-34325 Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Reviewed-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> (cherry picked from commit 9c114178ffd700112e91f5ec66cf5151b9c9a8cc) --- docs/man/xl.1.pod.in | 8 ++++++++ tools/libs/light/libxl_bootloader.c | 40 +++++++++++++++++++++++++++++++++++++ tools/libs/light/libxl_internal.h | 2 ++ 3 files changed, 50 insertions(+) diff --git a/docs/man/xl.1.pod.in b/docs/man/xl.1.pod.in index 4831e12242..c3eb6570ab 100644 --- a/docs/man/xl.1.pod.in +++ b/docs/man/xl.1.pod.in @@ -1988,6 +1988,14 @@ NOTE: Each domain MUST have a SEPARATE username. See docs/features/qemu-deprivilege.pandoc for more information. +=item LIBXL_BOOTLOADER_TIMEOUT + +Timeout in seconds for bootloader execution when running in restricted mode. +Otherwise the build time default in LIBXL_BOOTLOADER_TIMEOUT will be used. + +If defined the value must be an unsigned integer between 0 and INT_MAX, +otherwise behavior is undefined. Setting to 0 disables the timeout. + =back =head1 SEE ALSO diff --git a/tools/libs/light/libxl_bootloader.c b/tools/libs/light/libxl_bootloader.c index 23c0ef3e89..ee26d08f37 100644 --- a/tools/libs/light/libxl_bootloader.c +++ b/tools/libs/light/libxl_bootloader.c @@ -30,6 +30,8 @@ static void bootloader_keystrokes_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int rc, int onwrite, int errnoval); static void bootloader_display_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int rc, int onwrite, int errnoval); +static void bootloader_timeout(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs, int rc); static void bootloader_domaindeath(libxl__egc*, libxl__domaindeathcheck *dc, int rc); static void bootloader_finished(libxl__egc *egc, libxl__ev_child *child, @@ -297,6 +299,7 @@ void libxl__bootloader_init(libxl__bootloader_state *bl) bl->ptys[0].master = bl->ptys[0].slave = 0; bl->ptys[1].master = bl->ptys[1].slave = 0; libxl__ev_child_init(&bl->child); + libxl__ev_time_init(&bl->time); libxl__domaindeathcheck_init(&bl->deathcheck); bl->keystrokes.ao = bl->ao; libxl__datacopier_init(&bl->keystrokes); bl->display.ao = bl->ao; libxl__datacopier_init(&bl->display); @@ -314,6 +317,7 @@ static void bootloader_cleanup(libxl__egc *egc, libxl__bootloader_state *bl) libxl__domaindeathcheck_stop(gc,&bl->deathcheck); libxl__datacopier_kill(&bl->keystrokes); libxl__datacopier_kill(&bl->display); + libxl__ev_time_deregister(gc, &bl->time); for (i=0; i<2; i++) { libxl__carefd_close(bl->ptys[i].master); libxl__carefd_close(bl->ptys[i].slave); @@ -375,6 +379,7 @@ static void bootloader_stop(libxl__egc *egc, libxl__datacopier_kill(&bl->keystrokes); libxl__datacopier_kill(&bl->display); + libxl__ev_time_deregister(gc, &bl->time); if (libxl__ev_child_inuse(&bl->child)) { r = kill(bl->child.pid, SIGTERM); if (r) LOGED(WARN, bl->domid, "%sfailed to kill bootloader [%lu]", @@ -637,6 +642,25 @@ static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op) struct termios termattr; + if (getenv("LIBXL_BOOTLOADER_RESTRICT") || + getenv("LIBXL_BOOTLOADER_USER")) { + const char *timeout_env = getenv("LIBXL_BOOTLOADER_TIMEOUT"); + int timeout = timeout_env ? atoi(timeout_env) + : LIBXL_BOOTLOADER_TIMEOUT; + + if (timeout) { + /* Set execution timeout */ + rc = libxl__ev_time_register_rel(ao, &bl->time, + bootloader_timeout, + timeout * 1000); + if (rc) { + LOGED(ERROR, bl->domid, + "unable to register timeout for bootloader execution"); + goto out; + } + } + } + pid_t pid = libxl__ev_child_fork(gc, &bl->child, bootloader_finished); if (pid == -1) { rc = ERROR_FAIL; @@ -702,6 +726,21 @@ static void bootloader_display_copyfail(libxl__egc *egc, libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, display); bootloader_copyfail(egc, "bootloader output", bl, 1, rc,onwrite,errnoval); } +static void bootloader_timeout(libxl__egc *egc, libxl__ev_time *ev, + const struct timeval *requested_abs, int rc) +{ + libxl__bootloader_state *bl = CONTAINER_OF(ev, *bl, time); + STATE_AO_GC(bl->ao); + + libxl__ev_time_deregister(gc, &bl->time); + + assert(libxl__ev_child_inuse(&bl->child)); + LOGD(ERROR, bl->domid, "killing bootloader because of timeout"); + + libxl__ev_child_kill_deregister(ao, &bl->child, SIGKILL); + + bootloader_callback(egc, bl, rc); +} static void bootloader_domaindeath(libxl__egc *egc, libxl__domaindeathcheck *dc, @@ -718,6 +757,7 @@ static void bootloader_finished(libxl__egc *egc, libxl__ev_child *child, STATE_AO_GC(bl->ao); int rc; + libxl__ev_time_deregister(gc, &bl->time); libxl__datacopier_kill(&bl->keystrokes); libxl__datacopier_kill(&bl->display); diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index f1e3a9a15b..d05783617f 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -102,6 +102,7 @@ #define LIBXL_QMP_CMD_TIMEOUT 10 #define LIBXL_STUBDOM_START_TIMEOUT 30 #define LIBXL_QEMU_BODGE_TIMEOUT 2 +#define LIBXL_BOOTLOADER_TIMEOUT 120 #define LIBXL_XENCONSOLE_LIMIT 1048576 #define LIBXL_XENCONSOLE_PROTOCOL "vt100" #define LIBXL_MAXMEM_CONSTANT 1024 @@ -3744,6 +3745,7 @@ struct libxl__bootloader_state { libxl__openpty_state openpty; libxl__openpty_result ptys[2]; /* [0] is for bootloader */ libxl__ev_child child; + libxl__ev_time time; libxl__domaindeathcheck deathcheck; int nargs, argsspace; const char **args; -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.17
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |