Skip to content

Commit

Permalink
CA-383491: Invoke pygrub in depriv mode
Browse files Browse the repository at this point in the history
Instruct pygrub to drop its privileges

Signed-off-by: Alejandro Vallejo <[email protected]>
  • Loading branch information
Alejandro Vallejo authored and psafont committed Oct 11, 2023
1 parent 291d3fe commit f54fbf3
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ install:
install -D ./scripts/common.py $(DESTDIR)/$(LIBEXECDIR)/common.py
install -D ./scripts/igmp_query_injector.py $(DESTDIR)/$(LIBEXECDIR)/igmp_query_injector.py
install -D ./scripts/qemu-wrapper $(DESTDIR)/$(QEMU_WRAPPER_DIR)/qemu-wrapper
install -D ./scripts/pygrub-wrapper $(DESTDIR)/$(QEMU_WRAPPER_DIR)/pygrub-wrapper
DESTDIR=$(DESTDIR) SBINDIR=$(SBINDIR) QEMU_WRAPPER_DIR=$(QEMU_WRAPPER_DIR) LIBEXECDIR=$(LIBEXECDIR) ETCDIR=$(ETCDIR) ./scripts/make-custom-xenopsd.conf

uninstall:
Expand All @@ -70,5 +71,6 @@ uninstall:
rm -f $(DESTDIR)/$(LIBEXECDIR)/common.py*
rm -f $(DESTDIR)/$(LIBEXECDIR)/igmp_query_injector.py*
rm -f $(DESTDIR)/$(QEMU_WRAPPER_DIR)/qemu-wrapper
rm -f $(DESTDIR)/$(QEMU_WRAPPER_DIR)/pygrub-wrapper

.DEFAULT_GOAL := release
7 changes: 4 additions & 3 deletions lib/bootloader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ exception Error_from_bootloader of string
type t = {kernel_path: string; initrd_path: string option; kernel_args: string}

(** Helper function to generate a bootloader commandline *)
let command bootloader q pv_bootloader_args image vm_uuid =
let command bootloader q pv_bootloader_args image vm_uuid domid =
(* Let's not do anything fancy while parsing the pv_bootloader_args string: no
escaping of spaces or quotes for now *)
let pv_bootloader_args =
Expand All @@ -77,6 +77,7 @@ let command bootloader q pv_bootloader_args image vm_uuid =
[
["--output-format=simple"]
; q
; [Printf.sprintf "--domid=%d" domid]
; (* --vm is unnecessary for pygrub and not supported upstream *)
pv_bootloader_args
; image
Expand Down Expand Up @@ -221,11 +222,11 @@ let sanity_check_path p =
(** Extract the default kernel using the -q option *)
let extract (task : Xenops_task.task_handle) ~bootloader ~disk
?(legacy_args = "") ?(extra_args = "") ?(pv_bootloader_args = "")
~vm:vm_uuid () =
~vm:vm_uuid ~domid:domid () =
(* Without this path, pygrub will fail: *)
Unixext.mkdir_rec "/var/run/xend/boot" 0o0755 ;
let bootloader_path, cmdline =
command bootloader true pv_bootloader_args disk vm_uuid
command bootloader true pv_bootloader_args disk vm_uuid domid
in
debug "Bootloader commandline: %s %s\n" bootloader_path
(String.concat " " cmdline) ;
Expand Down
1 change: 1 addition & 0 deletions lib/bootloader.mli
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ val extract :
-> ?extra_args:string
-> ?pv_bootloader_args:string
-> vm:string
-> domid:int
-> unit
-> t
(** Extract the default kernel from the disk *)
Expand Down
2 changes: 1 addition & 1 deletion lib/resources.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ let rmmod = ref "/usr/sbin/rmmod"

let hvmloader = ref "hvmloader"

let pygrub = ref "pygrub"
let pygrub = ref "pygrub-wrapper"

let eliloader = ref "eliloader"

Expand Down
1 change: 1 addition & 0 deletions scripts/make-custom-xenopsd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ qemu-dm-wrapper=${LIBEXECDIR}/qemu-dm-wrapper
setup-vif-rules=${LIBEXECDIR}/setup-vif-rules
sockets-group=$group
qemu-wrapper=${QEMU_WRAPPER_DIR}/qemu-wrapper
pygrub-wrapper=${QEMU_WRAPPER_DIR}/pygrub-wrapper
disable-logging-for=http
# Workaround xenopsd bug #45
Expand Down
49 changes: 49 additions & 0 deletions scripts/pygrub-wrapper
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#! /usr/bin/python
#
# Copyright (C) 2023 Cloud Software Group
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; version 2.1 only. with the special
# exception on linking described in file LICENSE.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.

from __future__ import print_function
import pwd, subprocess, sys
import grp, os, stat

cmd = ["pygrub"]

# Get the usage string. We can't use check_output() because the exit status isn't 0
pygrub_usage = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1]

with_depriv = False
for arg in sys.argv[1:]:
# Catch the synthetic --domid argument and turn it into --runas
argname_domid = "--domid="
if arg.startswith(argname_domid):
if "[--runas=]" not in pygrub_usage:
# Skip depriv if pygrub doesn't support it
continue
with_depriv = True
domid = int(arg[len(argname_domid):])
uid = pwd.getpwnam('qemu_base').pw_uid + domid
cmd += ["--runas=" + str(uid)]

# Set group permissions on the disk so a depriv pygrub can read it
disk = sys.argv[-1]
gid = grp.getgrnam('disk').gr_gid
disk_stat = os.stat(disk)
os.chown(disk, uid, gid)
os.chmod(disk, disk_stat.st_mode | stat.S_IRGRP)
else:
cmd += [arg]

if 'PYGRUB_FORCE_DEPRIV' in os.environ.keys() and not with_depriv:
raise RuntimeError("Trying to run pygrub as root: %s" % pygrub_usage)

sys.exit(subprocess.call(cmd))
4 changes: 2 additions & 2 deletions xc/xenops_server_xen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2106,7 +2106,7 @@ module VM = struct
Bootloader.extract task ~bootloader:i.bootloader
~legacy_args:i.legacy_args ~extra_args:i.extra_args
~pv_bootloader_args:i.bootloader_args ~disk:dev
~vm:vm.Vm.id ()
~vm:vm.Vm.id ~domid:domid ()
in
kernel_to_cleanup := Some b ;
let builder_spec_info =
Expand Down Expand Up @@ -2150,7 +2150,7 @@ module VM = struct
Bootloader.extract task ~bootloader:i.bootloader
~legacy_args:i.legacy_args ~extra_args:i.extra_args
~pv_bootloader_args:i.bootloader_args ~disk:dev
~vm:vm.Vm.id ()
~vm:vm.Vm.id ~domid:domid ()
in
kernel_to_cleanup := Some b ;
let builder_spec_info =
Expand Down

0 comments on commit f54fbf3

Please sign in to comment.