Skip to content

Commit f54fbf3

Browse files
Alejandro Vallejopsafont
authored andcommitted
CA-383491: Invoke pygrub in depriv mode
Instruct pygrub to drop its privileges Signed-off-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
1 parent 291d3fe commit f54fbf3

File tree

7 files changed

+60
-6
lines changed

7 files changed

+60
-6
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ install:
4444
install -D ./scripts/common.py $(DESTDIR)/$(LIBEXECDIR)/common.py
4545
install -D ./scripts/igmp_query_injector.py $(DESTDIR)/$(LIBEXECDIR)/igmp_query_injector.py
4646
install -D ./scripts/qemu-wrapper $(DESTDIR)/$(QEMU_WRAPPER_DIR)/qemu-wrapper
47+
install -D ./scripts/pygrub-wrapper $(DESTDIR)/$(QEMU_WRAPPER_DIR)/pygrub-wrapper
4748
DESTDIR=$(DESTDIR) SBINDIR=$(SBINDIR) QEMU_WRAPPER_DIR=$(QEMU_WRAPPER_DIR) LIBEXECDIR=$(LIBEXECDIR) ETCDIR=$(ETCDIR) ./scripts/make-custom-xenopsd.conf
4849

4950
uninstall:
@@ -70,5 +71,6 @@ uninstall:
7071
rm -f $(DESTDIR)/$(LIBEXECDIR)/common.py*
7172
rm -f $(DESTDIR)/$(LIBEXECDIR)/igmp_query_injector.py*
7273
rm -f $(DESTDIR)/$(QEMU_WRAPPER_DIR)/qemu-wrapper
74+
rm -f $(DESTDIR)/$(QEMU_WRAPPER_DIR)/pygrub-wrapper
7375

7476
.DEFAULT_GOAL := release

lib/bootloader.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ exception Error_from_bootloader of string
5959
type t = {kernel_path: string; initrd_path: string option; kernel_args: string}
6060

6161
(** Helper function to generate a bootloader commandline *)
62-
let command bootloader q pv_bootloader_args image vm_uuid =
62+
let command bootloader q pv_bootloader_args image vm_uuid domid =
6363
(* Let's not do anything fancy while parsing the pv_bootloader_args string: no
6464
escaping of spaces or quotes for now *)
6565
let pv_bootloader_args =
@@ -77,6 +77,7 @@ let command bootloader q pv_bootloader_args image vm_uuid =
7777
[
7878
["--output-format=simple"]
7979
; q
80+
; [Printf.sprintf "--domid=%d" domid]
8081
; (* --vm is unnecessary for pygrub and not supported upstream *)
8182
pv_bootloader_args
8283
; image
@@ -221,11 +222,11 @@ let sanity_check_path p =
221222
(** Extract the default kernel using the -q option *)
222223
let extract (task : Xenops_task.task_handle) ~bootloader ~disk
223224
?(legacy_args = "") ?(extra_args = "") ?(pv_bootloader_args = "")
224-
~vm:vm_uuid () =
225+
~vm:vm_uuid ~domid:domid () =
225226
(* Without this path, pygrub will fail: *)
226227
Unixext.mkdir_rec "/var/run/xend/boot" 0o0755 ;
227228
let bootloader_path, cmdline =
228-
command bootloader true pv_bootloader_args disk vm_uuid
229+
command bootloader true pv_bootloader_args disk vm_uuid domid
229230
in
230231
debug "Bootloader commandline: %s %s\n" bootloader_path
231232
(String.concat " " cmdline) ;

lib/bootloader.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ val extract :
3838
-> ?extra_args:string
3939
-> ?pv_bootloader_args:string
4040
-> vm:string
41+
-> domid:int
4142
-> unit
4243
-> t
4344
(** Extract the default kernel from the disk *)

lib/resources.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ let rmmod = ref "/usr/sbin/rmmod"
2828

2929
let hvmloader = ref "hvmloader"
3030

31-
let pygrub = ref "pygrub"
31+
let pygrub = ref "pygrub-wrapper"
3232

3333
let eliloader = ref "eliloader"
3434

scripts/make-custom-xenopsd.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ qemu-dm-wrapper=${LIBEXECDIR}/qemu-dm-wrapper
4646
setup-vif-rules=${LIBEXECDIR}/setup-vif-rules
4747
sockets-group=$group
4848
qemu-wrapper=${QEMU_WRAPPER_DIR}/qemu-wrapper
49+
pygrub-wrapper=${QEMU_WRAPPER_DIR}/pygrub-wrapper
4950
5051
disable-logging-for=http
5152
# Workaround xenopsd bug #45

scripts/pygrub-wrapper

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#! /usr/bin/python
2+
#
3+
# Copyright (C) 2023 Cloud Software Group
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU Lesser General Public License as published
7+
# by the Free Software Foundation; version 2.1 only. with the special
8+
# exception on linking described in file LICENSE.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Lesser General Public License for more details.
14+
15+
from __future__ import print_function
16+
import pwd, subprocess, sys
17+
import grp, os, stat
18+
19+
cmd = ["pygrub"]
20+
21+
# Get the usage string. We can't use check_output() because the exit status isn't 0
22+
pygrub_usage = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[1]
23+
24+
with_depriv = False
25+
for arg in sys.argv[1:]:
26+
# Catch the synthetic --domid argument and turn it into --runas
27+
argname_domid = "--domid="
28+
if arg.startswith(argname_domid):
29+
if "[--runas=]" not in pygrub_usage:
30+
# Skip depriv if pygrub doesn't support it
31+
continue
32+
with_depriv = True
33+
domid = int(arg[len(argname_domid):])
34+
uid = pwd.getpwnam('qemu_base').pw_uid + domid
35+
cmd += ["--runas=" + str(uid)]
36+
37+
# Set group permissions on the disk so a depriv pygrub can read it
38+
disk = sys.argv[-1]
39+
gid = grp.getgrnam('disk').gr_gid
40+
disk_stat = os.stat(disk)
41+
os.chown(disk, uid, gid)
42+
os.chmod(disk, disk_stat.st_mode | stat.S_IRGRP)
43+
else:
44+
cmd += [arg]
45+
46+
if 'PYGRUB_FORCE_DEPRIV' in os.environ.keys() and not with_depriv:
47+
raise RuntimeError("Trying to run pygrub as root: %s" % pygrub_usage)
48+
49+
sys.exit(subprocess.call(cmd))

xc/xenops_server_xen.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,7 +2106,7 @@ module VM = struct
21062106
Bootloader.extract task ~bootloader:i.bootloader
21072107
~legacy_args:i.legacy_args ~extra_args:i.extra_args
21082108
~pv_bootloader_args:i.bootloader_args ~disk:dev
2109-
~vm:vm.Vm.id ()
2109+
~vm:vm.Vm.id ~domid:domid ()
21102110
in
21112111
kernel_to_cleanup := Some b ;
21122112
let builder_spec_info =
@@ -2150,7 +2150,7 @@ module VM = struct
21502150
Bootloader.extract task ~bootloader:i.bootloader
21512151
~legacy_args:i.legacy_args ~extra_args:i.extra_args
21522152
~pv_bootloader_args:i.bootloader_args ~disk:dev
2153-
~vm:vm.Vm.id ()
2153+
~vm:vm.Vm.id ~domid:domid ()
21542154
in
21552155
kernel_to_cleanup := Some b ;
21562156
let builder_spec_info =

0 commit comments

Comments
 (0)