Start using virtmgr for running VMs

Split virtualizationservice policy into rules that should remain with
the global service and rules that now apply to virtmgr - a child process
of the client that runs the VM on its behalf.

The virtualizationservice domain remains responsible for:
 * allocating CIDs (access to props)
 * creating temporary VM directories (virtualization_data_file, chown)
 * receiving tombstones from VMs
 * pushing atoms to statsd
 * removing memlock rlimit from virtmgr

The new virtualizationmanager domain becomes responsible for:
 * executing crosvm
 * creating vsock connections, handling callbacks
 * preparing APEXes
 * pushing ramdumps to tombstoned
 * collecting stats for telemetry atoms

The `virtualizationservice_use` macro is changed to allow client domains
to transition to the virtmgr domain upon executing it as their child,
and to allow communication over UDS.

Clients are not allowed to communicate with virtualizationservice via
Binder, only virtmgr is now allowed to do that.

Bug: 250685929
Test: atest -p packages/modules/Virtualization:avf-presubmit
Change-Id: Iefdccd908fc28e5d8c6f4566290e79ed88ade70b
This commit is contained in:
David Brazdil 2022-12-15 13:38:42 +00:00
parent d09a14baee
commit 55d808c28c
10 changed files with 131 additions and 94 deletions

View file

@ -1,5 +1,5 @@
(/.*)? u:object_r:system_file:s0
/bin/crosvm u:object_r:crosvm_exec:s0
/bin/fd_server u:object_r:fd_server_exec:s0
/bin/virtmgr u:object_r:virtmgr_exec:s0
/bin/virtmgr u:object_r:virtualizationmanager_exec:s0
/bin/virtualizationservice u:object_r:virtualizationservice_exec:s0

View file

@ -95,9 +95,9 @@ neverallow appdomain system_server:udp_socket {
# Exception for crash_dump to allow for app crash reporting.
# Exception for renderscript binaries (/system/bin/bcc, /system/bin/ld.mc)
# to allow renderscript to create privileged executable files.
# Exception for virtmgr to allow running VMs as child processes.
# Exception for virtualizationmanager to allow running VMs as child processes.
neverallow { appdomain -shell userdebug_or_eng(`-su') }
{ domain -appdomain -crash_dump -rs -virtmgr }:process { transition };
{ domain -appdomain -crash_dump -rs -virtualizationmanager }:process { transition };
neverallow { appdomain -shell userdebug_or_eng(`-su') }
{ domain -appdomain }:process { dyntransition };

View file

@ -14,10 +14,10 @@ neverallowxperm { domain -crosvm } kvm_device:chr_file ioctl ~{ KVM_CHECK_EXTENS
tmpfs_domain(crosvm)
# Let crosvm receive file descriptors from VirtualizationService.
allow crosvm virtualizationservice:fd use;
allow crosvm virtualizationmanager:fd use;
# Allow sending VirtualizationService the failure reason from the VM via pipe.
allow crosvm virtualizationservice:fifo_file write;
allow crosvm virtualizationmanager:fifo_file write;
# Let crosvm read the composite disk images (virtualizationservice_data_file), APEXes
# (staging_data_file), APKs (apk_data_file and shell_data_file where the latter is for test apks in
@ -36,11 +36,14 @@ allow crosvm {
# Allow searching the directory where the composite disk images are.
allow crosvm virtualizationservice_data_file:dir search;
# Allow crosvm to mlock guest memory.
allow crosvm self:capability ipc_lock;
# Let crosvm access its control socket as created by VS.
# read, write, getattr: listener socket polling
# accept: listener socket accepting new connection
# Note that the open permission is not given as the socket is passed by FD.
allow crosvm virtualizationservice:unix_stream_socket { accept read write getattr getopt };
allow crosvm virtualizationmanager:unix_stream_socket { accept read write getattr getopt };
# Let crosvm open test artifacts under /data/local/tmp with file path. (e.g. custom pvmfw.img)
userdebug_or_eng(`
@ -110,9 +113,9 @@ neverallow crosvm {
-shell_data_file
}:file read;
# Only virtualizationservice can run crosvm
# Only virtualizationmanager can run crosvm
neverallow {
domain
-crosvm
-virtualizationservice
-virtualizationmanager
} crosvm_exec:file no_x_file_perms;

View file

@ -290,7 +290,7 @@ neverallow {
-apexd
-installd
-priv_app
-virtualizationservice
-virtualizationmanager
} staging_data_file:dir *;
neverallow {
domain
@ -303,7 +303,7 @@ neverallow {
-installd
-priv_app
-shell
-virtualizationservice
-virtualizationmanager
-crosvm
} staging_data_file:file *;
neverallow { domain -init -system_server -installd} staging_data_file:dir no_w_dir_perms;

View file

@ -91,7 +91,9 @@ type odsign_data_file, file_type, data_file_type, core_data_file_type;
type odsign_metrics_file, file_type, data_file_type, core_data_file_type;
# /data/misc/virtualizationservice
type virtualizationservice_data_file, file_type, data_file_type, core_data_file_type;
# The type needs to be mlstrustedobject to allow for being accessed from
# virtualizationmanager, which runs at a more constrained MLS level.
type virtualizationservice_data_file, file_type, data_file_type, core_data_file_type, mlstrustedobject;
# /data/system/environ
type environ_system_data_file, file_type, data_file_type, core_data_file_type;
@ -100,7 +102,9 @@ type environ_system_data_file, file_type, data_file_type, core_data_file_type;
type bootanim_data_file, file_type, data_file_type, core_data_file_type;
# /dev/kvm
type kvm_device, dev_type;
# The type needs to be mlstrustedobject to allow for being accessed from
# crosvm, which runs at a more constrained MLS level.
type kvm_device, dev_type, mlstrustedobject;
# /apex/com.android.virt/bin/fd_server
type fd_server_exec, system_file_type, exec_type, file_type;

View file

@ -19,6 +19,9 @@ userdebug_or_eng(`
# Put the perfetto command into its domain so it is the same on user, userdebug and eng.
domain_auto_trans(su, perfetto_exec, perfetto)
# Put the virtmgr command into its domain.
domain_auto_trans(su, virtualizationmanager_exec, virtualizationmanager)
# su is also permissive to permit setenforce.
permissive su;

View file

@ -1,8 +0,0 @@
# Domain for a child process that manages virtual machines on behalf of its parent.
type virtmgr, domain, coredomain;
type virtmgr_exec, system_file_type, exec_type, file_type;
# Allow virtmgr to communicate use, read and write over the adb connection.
allow virtmgr adbd:fd use;
allow virtmgr adbd:unix_stream_socket { read write };

View file

@ -0,0 +1,73 @@
# Domain for a child process that manages virtual machines on behalf of its parent.
type virtualizationmanager, domain, coredomain;
type virtualizationmanager_exec, system_file_type, exec_type, file_type;
# Allow virtualizationmanager to communicate use, read and write over the adb connection.
allow virtualizationmanager adbd:fd use;
allow virtualizationmanager adbd:unix_stream_socket { read write };
# Let the virtualizationmanager domain use Binder.
binder_use(virtualizationmanager)
# Let virtualizationmanager find and communicate with virtualizationservice.
allow virtualizationmanager virtualization_service:service_manager find;
binder_call(virtualizationmanager, virtualizationservice)
# Allow calling into the system server to find native services. "permission_service" to check
# permissions, and "package_native" for staged apex info.
binder_call(virtualizationmanager, system_server)
allow virtualizationmanager { package_native_service permission_service }:service_manager find;
# When virtualizationmanager execs a file with the crosvm_exec label, run it in the crosvm domain.
domain_auto_trans(virtualizationmanager, crosvm_exec, crosvm)
# Let virtualizationmanager kill crosvm.
allow virtualizationmanager crosvm:process sigkill;
# Let virtualizationmanager create files inside virtualizationservice's temporary directories.
allow virtualizationmanager virtualizationservice_data_file:dir rw_dir_perms;
allow virtualizationmanager virtualizationservice_data_file:{ file sock_file } create_file_perms;
# Let virtualizationmanager read and write files from its various clients, but not open them
# directly as they must be passed over Binder by the client.
allow virtualizationmanager apk_data_file:file { getattr read };
# Write access is needed for mutable partitions like instance.img
allow virtualizationmanager {
app_data_file
apex_compos_data_file
privapp_data_file
}:file { getattr read write };
# shell_data_file is used for automated tests and manual debugging.
allow virtualizationmanager shell_data_file:file { getattr read write };
# Allow virtualizationmanager to read apex-info-list.xml and access the APEX files listed there.
allow virtualizationmanager apex_info_file:file r_file_perms;
allow virtualizationmanager apex_data_file:dir search;
allow virtualizationmanager staging_data_file:file r_file_perms;
allow virtualizationmanager staging_data_file:dir search;
# Run derive_classpath in our domain
allow virtualizationmanager derive_classpath_exec:file rx_file_perms;
allow virtualizationmanager apex_mnt_dir:dir r_dir_perms;
# Ignore harmless denials on /proc/self/fd
dontaudit virtualizationmanager self:dir write;
# Let virtualizationmanager to accept vsock connection from the guest VMs
allow virtualizationmanager self:vsock_socket { create_socket_perms_no_ioctl listen accept };
# Allow virtualizationmanager to inspect all hypervisor capabilities.
get_prop(virtualizationmanager, hypervisor_prop)
get_prop(virtualizationmanager, hypervisor_restricted_prop)
# Allow virtualizationmanager service to talk to tombstoned to push guest ramdumps
unix_socket_connect(virtualizationmanager, tombstoned_crash, tombstoned)
# Append ramdumps to tombstone files passed as fds from tombstoned
allow virtualizationmanager tombstone_data_file:file { append getattr };
allow virtualizationmanager tombstoned:fd use;
# Allow reading files under /proc/[crosvm pid]/, for collecting CPU & memory usage inside VM.
r_dir_file(virtualizationmanager, crosvm);

View file

@ -1,80 +1,45 @@
type virtualizationservice, domain, coredomain;
type virtualizationservice_exec, system_file_type, exec_type, file_type;
# The domain needs to be a 'mlstrustedsubject' to change the memlock rlimit of
# the virtualizationmanager domain running at a more constrained MLS level.
typeattribute virtualizationservice mlstrustedsubject;
# When init runs a file labelled with virtualizationservice_exec, run it in the
# virtualizationservice domain.
init_daemon_domain(virtualizationservice)
# Let the virtualizationservice domain use Binder.
binder_use(virtualizationservice)
# ... and host a binder service
binder_service(virtualizationservice)
# Allow calling into the system server so that it can check permissions.
binder_call(virtualizationservice, system_server)
allow virtualizationservice permission_service:service_manager find;
# Allow virtualizationservice to access "package_native" service for staged apex info.
allow virtualizationservice package_native_service:service_manager find;
# Let the virtualizationservice domain register the virtualization_service with ServiceManager.
add_service(virtualizationservice, virtualization_service)
# When virtualizationservice execs a file with the crosvm_exec label, run it in the crosvm domain.
domain_auto_trans(virtualizationservice, crosvm_exec, crosvm)
# Let virtualizationservice (and specifically its children) mlock VM memory and page tables.
# Let virtualizationservice remove memlock rlimit of virtualizationmanager. This is necessary
# to mlock VM memory and page tables.
allow virtualizationservice self:capability sys_resource;
allow virtualizationservice virtualizationmanager:process setrlimit;
# Let virtualizationservice kill crosvm.
allow virtualizationservice crosvm:process sigkill;
# Let virtualizationservice set the owner of a VM's temporary directory.
allow virtualizationservice self:capability chown;
# Let virtualizationservice access its data directory.
allow virtualizationservice virtualizationservice_data_file:file create_file_perms;
# Let virtualizationservice create and delete temporary directories of VMs. To remove old
# directories, it needs the permission to unlink the files created by virtualizationmanager.
allow virtualizationservice virtualizationservice_data_file:dir create_dir_perms;
# Let virtualizationservice manage crosvm control sockets.
allow virtualizationservice virtualizationservice_data_file:sock_file create_file_perms;
allow virtualizationservice virtualizationservice_data_file:{ file sock_file } unlink;
# Allow to use fd (e.g. /dev/pts/0) inherited from adbd so that we can redirect output from
# crosvm to the console
allow virtualizationservice adbd:fd use;
allow virtualizationservice adbd:unix_stream_socket { read write };
# Let virtualizationservice read and write files from its various clients, but not open them
# directly as they must be passed over Binder by the client.
allow virtualizationservice apk_data_file:file { getattr read };
# Write access is needed for mutable partitions like instance.img
allow virtualizationservice {
app_data_file
apex_compos_data_file
privapp_data_file
}:file { getattr read write };
# shell_data_file is used for automated tests and manual debugging.
allow virtualizationservice shell_data_file:file { getattr read write };
# Allow virtualizationservice to read apex-info-list.xml and access the APEX files listed there.
allow virtualizationservice apex_info_file:file r_file_perms;
allow virtualizationservice apex_data_file:dir search;
allow virtualizationservice staging_data_file:file r_file_perms;
allow virtualizationservice staging_data_file:dir search;
# Run derive_classpath in our domain
allow virtualizationservice derive_classpath_exec:file rx_file_perms;
allow virtualizationservice apex_mnt_dir:dir r_dir_perms;
# Ignore harmless denials on /proc/self/fd
dontaudit virtualizationservice self:dir write;
# Let virtualizationservice to accept vsock connection from the guest VMs
# Let virtualizationservice to accept vsock connection from the guest VMs to singleton services
# such as the guest tombstone server.
allow virtualizationservice self:vsock_socket { create_socket_perms_no_ioctl listen accept };
# Allow virtualizationservice to read/write its own sysprop. Only the process can do so.
set_prop(virtualizationservice, virtualizationservice_prop)
# Allow virtualizationservice to inspect all hypervisor capabilities.
get_prop(virtualizationservice, hypervisor_prop)
get_prop(virtualizationservice, hypervisor_restricted_prop)
# Allow writing stats to statsd
unix_socket_send(virtualizationservice, statsdw, statsd)
@ -85,9 +50,6 @@ unix_socket_connect(virtualizationservice, tombstoned_crash, tombstoned)
allow virtualizationservice tombstone_data_file:file { append getattr };
allow virtualizationservice tombstoned:fd use;
# Allow reading files under /proc/[crosvm pid]/, for collecting CPU & memory usage inside VM.
r_dir_file(virtualizationservice, crosvm);
neverallow {
domain
-init
@ -97,5 +59,12 @@ neverallow {
neverallow {
domain
-init
-virtualizationmanager
-virtualizationservice
} virtualizationservice_data_file:file { open create };
neverallow virtualizationservice {
domain
-virtualizationmanager
-virtualizationservice
}:process setrlimit;

View file

@ -183,32 +183,25 @@ neverallow $1 ~$1_userfaultfd:anon_inode *;
####################################
# virtualizationservice_use(domain)
# Allow domain to create and communicate with a virtual machine using
# virtualizationservice.
# virtualizationservice and virtualizationmanager.
define(`virtualizationservice_use', `
allow $1 virtualization_service:service_manager find;
# Let the client call virtualizationservice.
binder_call($1, virtualizationservice)
# Let virtualizationservice call back to the client.
binder_call(virtualizationservice, $1)
# Transition to virtmgr when the client executes it.
domain_auto_trans($1, virtmgr_exec, virtmgr)
# Allow virtmgr to communicate over UDS with the client.
allow virtmgr $1:unix_stream_socket { getattr read write };
# Allow virtmgr and the client to signal each other using pipes.
allow virtmgr $1:fifo_file { getattr read write };
# Let the client pass file descriptors to virtualizationservice/virtmgr and on
# to crosvm
allow { virtualizationservice virtmgr crosvm } $1:fd use;
# Transition to virtualizationmanager when the client executes it.
domain_auto_trans($1, virtualizationmanager_exec, virtualizationmanager)
# Allow virtualizationmanager to communicate over UDS with the client.
allow { virtualizationmanager crosvm } $1:unix_stream_socket { getattr read write };
# Let the client pass file descriptors to virtualizationmanager and on to crosvm.
allow { virtualizationmanager crosvm } $1:fd use;
# Let the client use file descriptors created by virtualizationmanager.
allow $1 virtualizationmanager:fd use;
# Allow piping console log to the client
allow { virtualizationservice crosvm } $1:fifo_file { getattr write};
# Allow client to read/write vsock created by virtualizationservice to
# communicate with the VM that it created. Notice that we do not grant
# permission to create a vsock; the client can only connect to VMs
# that it owns.
allow $1 virtualizationservice:vsock_socket { getattr getopt read write };
allow { virtualizationmanager crosvm } $1:fifo_file { getattr read write };
# Allow client to read/write vsock created by virtualizationmanager to communicate with the VM
# that it created. Notice that we do not grant permission to create a vsock;
# the client can only connect to VMs that it owns.
allow $1 virtualizationmanager:vsock_socket { getattr getopt read write };
# Allow client to inspect hypervisor capabilities
get_prop($1, hypervisor_prop)
# Allow client to read (but not open) the crashdump provided by virtualizationservice
# Allow client to read (but not open) the crashdump provided by virtualizationmanager
allow $1 virtualizationservice_data_file:file { getattr read };
')