[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen stable-4.15] libxl: limit bootloader execution in restricted mode
commit c84412457d3507816b5f8e988a9c8dcc4010e984 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:57:07 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 96e6fb1c32..8f056450a7 100644 --- a/docs/man/xl.1.pod.in +++ b/docs/man/xl.1.pod.in @@ -2007,6 +2007,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 97d9bf4ddc..3ca6463e5f 100644 --- a/tools/libs/light/libxl_bootloader.c +++ b/tools/libs/light/libxl_bootloader.c @@ -34,6 +34,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, @@ -301,6 +303,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); @@ -318,6 +321,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); @@ -379,6 +383,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]", @@ -641,6 +646,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; @@ -706,6 +730,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, @@ -722,6 +761,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 8415d1feed..a9581289f4 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -103,6 +103,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 @@ -3738,6 +3739,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.15
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |