[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] libxl: limit bootloader execution in restricted mode
commit 9c114178ffd700112e91f5ec66cf5151b9c9a8cc Author: Roger Pau Monne <roger.pau@xxxxxxxxxx> AuthorDate: Thu Sep 28 12:22:35 2023 +0200 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Wed Oct 11 06:36:50 2023 +0100 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> --- 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 73e2b3b611..bed8393473 100644 --- a/docs/man/xl.1.pod.in +++ b/docs/man/xl.1.pod.in @@ -1985,6 +1985,14 @@ compatibility reasons. If set takes precedence over L<xl.cfg(5)> B<bootloader_user> option. +=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 d732367fc0..279a9cdf91 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, @@ -296,6 +298,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); @@ -313,6 +316,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); @@ -374,6 +378,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]", @@ -635,6 +640,25 @@ static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op) LOGD(DEBUG, bl->domid, " bootloader arg: %s", *blarg); struct termios termattr; + const libxl_domain_build_info *info = bl->info; + + if (libxl_defbool_val(info->bootloader_restrict)) { + 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) { @@ -701,6 +725,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, @@ -717,6 +756,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 1219ff8dbd..d5732d1c37 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#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |