public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
* [PATCH] contrib/apparmor: Split profile into abstractions, use them
@ 2023-02-27 16:38 Stefano Brivio
  0 siblings, 0 replies; only message in thread
From: Stefano Brivio @ 2023-02-27 16:38 UTC (permalink / raw)
  To: passt-dev; +Cc: Andrea Bolognani

One day, libvirt might actually support running passt to provide
guest connectivity. Should libvirtd (or virtqemud) start passt, it
will need to access socket and PID files in specific locations, and
passt needs to accept SIGTERM in case QEMU fails to start after passt
is already started.

To make this more convenient, split the current profile into two
abstractions, for passt and for pasta, so that external programmes
can include the bits they need (and especially not include the pasta
abstraction if they only need to start passt), plus whatever specific
adaptation is needed.

For stand-alone usage of passt and pasta, the 'passt' profile simply
includes both abstractions, plus rules to create and access PID and
capture files in default or reasonable ($HOME) locations.

Tested on Debian with libvirt 9.0.0 together with a local fix to start
passt as intended, namely libvirt commit c0efdbdb9f66 ("qemu_passt:
Avoid double daemonizing passt"). This is an example of how the
libvirtd profile (or virtqemud abstraction, or virtqemud profile) can
use this:

  # support for passt network back-end
  /usr/bin/passt Cx -> passt,
  profile passt {
    /usr/bin/passt r,

    owner @{run}/user/[0-9]*/libvirt/qemu/run/passt/* rw,
    signal (receive) set=("term") peer=/usr/sbin/libvirtd,
    signal (receive) set=("term") peer=libvirtd,

    include if exists <abstractions/passt>
  }

translated:

- when executing /usr/bin/passt, switch to the subprofile "passt"
  (not the "discrete", i.e. stand-alone profile), described below.
  Scrub the environment (e.g. LD_PRELOAD is dropped)

- in the "passt" subprofile:

  - allow reading the binary

  - allow read and write access to PID and socket files

  - make passt accept SIGTERM from /usr/sbin/libvirtd, and
    libvirtd peer names

  - include anything else that's needed by passt itself

Suggested-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 contrib/apparmor/abstractions/passt | 47 ++++++++++++++++++++
 contrib/apparmor/abstractions/pasta | 35 +++++++++++++++
 contrib/apparmor/usr.bin.passt      | 67 +++--------------------------
 3 files changed, 89 insertions(+), 60 deletions(-)
 create mode 100644 contrib/apparmor/abstractions/passt
 create mode 100644 contrib/apparmor/abstractions/pasta

diff --git a/contrib/apparmor/abstractions/passt b/contrib/apparmor/abstractions/passt
new file mode 100644
index 0000000..000e3db
--- /dev/null
+++ b/contrib/apparmor/abstractions/passt
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+# PASST - Plug A Simple Socket Transport
+#  for qemu/UNIX domain socket mode
+#
+# PASTA - Pack A Subtle Tap Abstraction
+#  for network namespace/tap device mode
+#
+# contrib/apparmor/abstractions/passt - Abstraction for passt(1)
+#
+# Copyright (c) 2022 Red Hat GmbH
+# Author: Stefano Brivio <sbrivio@redhat.com>
+
+  abi <abi/3.0>,
+
+  include <abstractions/base>
+
+  # Alternatively: include <abstractions/nameservice>
+  @{etc_ro}/resolv.conf			r,	# get_dns(), conf.c
+
+  capability net_bind_service,			# isolation.c, conf.c
+  capability setuid,
+  capability setgid,
+  capability sys_admin,
+  capability setpcap,
+  capability net_admin,
+  capability sys_ptrace,
+
+  /					r,	# isolate_prefork(), isolation.c
+  mount		""	-> "/",
+  mount		""	-> "/tmp/",
+  pivot_root	"/tmp/" -> "/tmp/",
+  umount	"/",
+
+  network netlink raw,				# nl_sock_init_do(), netlink.c
+
+  network inet stream,				# tcp.c
+  network inet6 stream,
+
+  network inet dgram,				# udp.c
+  network inet6 dgram,
+
+  network unix stream,				# tap.c
+
+  network unix dgram,				# __openlog(), log.c
+
+  /usr/bin/passt.avx2			ix,	# arch_avx2_exec(), arch.c
diff --git a/contrib/apparmor/abstractions/pasta b/contrib/apparmor/abstractions/pasta
new file mode 100644
index 0000000..7d802ac
--- /dev/null
+++ b/contrib/apparmor/abstractions/pasta
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+# PASST - Plug A Simple Socket Transport
+#  for qemu/UNIX domain socket mode
+#
+# PASTA - Pack A Subtle Tap Abstraction
+#  for network namespace/tap device mode
+#
+# contrib/apparmor/abstractions/pasta - Abstraction for pasta(1)
+#
+# Copyright (c) 2022 Red Hat GmbH
+# Author: Stefano Brivio <sbrivio@redhat.com>
+
+  abi <abi/3.0>,
+
+  include <abstractions/passt>
+
+  @{PROC}/net/tcp			r,	# procfs_scan_listen(), util.c
+  @{PROC}/net/tcp6			r,
+  @{PROC}/net/udp			r,
+  @{PROC}/net/udp6			r,
+
+  @{run}/user/@{uid}/netns/*		r,	# pasta_open_ns(), pasta.c
+
+  @{PROC}/[0-9]*/ns/net			r,	# pasta_wait_for_ns(),
+  @{PROC}/[0-9]*/ns/user		r,	# conf_pasta_ns()
+
+  /dev/net/tun				rw,	# tap_ns_tun(), tap.c
+
+  owner @{PROC}/@{pid}/gid_map		w,	# pasta_start_ns(), conf_ugid()
+  owner @{PROC}/@{pid}/setgroups	w,
+  owner @{PROC}/@{pid}/uid_map		rw,
+
+  owner @{PROC}/sys/net/ipv4/ping_group_range w, # pasta_spawn_cmd(), pasta.c
+  /{usr/,}bin/**			Ux,
diff --git a/contrib/apparmor/usr.bin.passt b/contrib/apparmor/usr.bin.passt
index 96b61ef..7433d01 100644
--- a/contrib/apparmor/usr.bin.passt
+++ b/contrib/apparmor/usr.bin.passt
@@ -16,73 +16,20 @@ abi <abi/3.0>,
 include <tunables/global>
 
 profile passt /usr/bin/passt{,.avx2} flags=(attach_disconnected) {
-  ### Common rules for passt and pasta
-
-  include <abstractions/base>
-
-  # Alternatively: include <abstractions/nameservice>
-  @{etc_ro}/resolv.conf			r,	# get_dns(), conf.c
-
-  capability net_bind_service,			# isolation.c, conf.c
-  capability setuid,
-  capability setgid,
-  capability sys_admin,
-  capability setpcap,
-  capability net_admin,
-  capability sys_ptrace,
-
-  /					r,	# isolate_prefork(), isolation.c
-  mount		""	-> "/",
-  mount		""	-> "/tmp/",
-  pivot_root	"/tmp/" -> "/tmp/",
-  umount	"/",
-
-  network netlink raw,				# nl_sock_init_do(), netlink.c
-
-  network inet stream,				# tcp.c
-  network inet6 stream,
-
-  network inet dgram,				# udp.c
-  network inet6 dgram,
-
-  network unix stream,				# tap.c
-
-  network unix dgram,				# __openlog(), log.c
-
-  # Alternatively: include <abstractions/user-tmp>
-  owner /tmp/**				w,	# tap_sock_unix_init(), pcap(),
-						# write_pidfile(),
-						# logfile_init()
-
-  owner @{HOME}/**			w,	# pcap(), write_pidfile()
-
-  /usr/bin/passt.avx2			ix,	# arch_avx2_exec(), arch.c
-
-
-  ### Rules for pasta
-  ###
   ### TODO: AppArmor doesn't give us the chance to attach a separate profile
   ### depending on the executable symlink. That's possible with SELinux. Two
   ### alternatives: implement that in AppArmor, or consider aa_change_hat(2).
   ### With this, rules for passt(1) could be restricted significantly. Note that
   ### the attach_disconnected flag is not needed for passt(1).
 
-  @{PROC}/net/tcp			r,	# procfs_scan_listen(), util.c
-  @{PROC}/net/tcp6			r,
-  @{PROC}/net/udp			r,
-  @{PROC}/net/udp6			r,
-
-  @{run}/user/@{uid}/netns/*		r,	# pasta_open_ns(), pasta.c
+  include <abstractions/passt>
 
-  @{PROC}/[0-9]*/ns/net			r,	# pasta_wait_for_ns(),
-  @{PROC}/[0-9]*/ns/user		r,	# conf_pasta_ns()
-
-  /dev/net/tun				rw,	# tap_ns_tun(), tap.c
+  # Alternatively: include <abstractions/user-tmp>
+  owner /tmp/**				w,	# tap_sock_unix_init(), pcap(),
+						# write_pidfile(),
+						# logfile_init()
 
-  owner @{PROC}/@{pid}/gid_map		w,	# pasta_start_ns(), conf_ugid()
-  owner @{PROC}/@{pid}/setgroups	w,
-  owner @{PROC}/@{pid}/uid_map		rw,
+  owner @{HOME}/**			w,	# pcap(), write_pidfile()
 
-  owner @{PROC}/sys/net/ipv4/ping_group_range w, # pasta_spawn_cmd(), pasta.c
-  /{usr/,}bin/**			Ux,
+  include <abstractions/pasta>
 }
-- 
@@ -16,73 +16,20 @@ abi <abi/3.0>,
 include <tunables/global>
 
 profile passt /usr/bin/passt{,.avx2} flags=(attach_disconnected) {
-  ### Common rules for passt and pasta
-
-  include <abstractions/base>
-
-  # Alternatively: include <abstractions/nameservice>
-  @{etc_ro}/resolv.conf			r,	# get_dns(), conf.c
-
-  capability net_bind_service,			# isolation.c, conf.c
-  capability setuid,
-  capability setgid,
-  capability sys_admin,
-  capability setpcap,
-  capability net_admin,
-  capability sys_ptrace,
-
-  /					r,	# isolate_prefork(), isolation.c
-  mount		""	-> "/",
-  mount		""	-> "/tmp/",
-  pivot_root	"/tmp/" -> "/tmp/",
-  umount	"/",
-
-  network netlink raw,				# nl_sock_init_do(), netlink.c
-
-  network inet stream,				# tcp.c
-  network inet6 stream,
-
-  network inet dgram,				# udp.c
-  network inet6 dgram,
-
-  network unix stream,				# tap.c
-
-  network unix dgram,				# __openlog(), log.c
-
-  # Alternatively: include <abstractions/user-tmp>
-  owner /tmp/**				w,	# tap_sock_unix_init(), pcap(),
-						# write_pidfile(),
-						# logfile_init()
-
-  owner @{HOME}/**			w,	# pcap(), write_pidfile()
-
-  /usr/bin/passt.avx2			ix,	# arch_avx2_exec(), arch.c
-
-
-  ### Rules for pasta
-  ###
   ### TODO: AppArmor doesn't give us the chance to attach a separate profile
   ### depending on the executable symlink. That's possible with SELinux. Two
   ### alternatives: implement that in AppArmor, or consider aa_change_hat(2).
   ### With this, rules for passt(1) could be restricted significantly. Note that
   ### the attach_disconnected flag is not needed for passt(1).
 
-  @{PROC}/net/tcp			r,	# procfs_scan_listen(), util.c
-  @{PROC}/net/tcp6			r,
-  @{PROC}/net/udp			r,
-  @{PROC}/net/udp6			r,
-
-  @{run}/user/@{uid}/netns/*		r,	# pasta_open_ns(), pasta.c
+  include <abstractions/passt>
 
-  @{PROC}/[0-9]*/ns/net			r,	# pasta_wait_for_ns(),
-  @{PROC}/[0-9]*/ns/user		r,	# conf_pasta_ns()
-
-  /dev/net/tun				rw,	# tap_ns_tun(), tap.c
+  # Alternatively: include <abstractions/user-tmp>
+  owner /tmp/**				w,	# tap_sock_unix_init(), pcap(),
+						# write_pidfile(),
+						# logfile_init()
 
-  owner @{PROC}/@{pid}/gid_map		w,	# pasta_start_ns(), conf_ugid()
-  owner @{PROC}/@{pid}/setgroups	w,
-  owner @{PROC}/@{pid}/uid_map		rw,
+  owner @{HOME}/**			w,	# pcap(), write_pidfile()
 
-  owner @{PROC}/sys/net/ipv4/ping_group_range w, # pasta_spawn_cmd(), pasta.c
-  /{usr/,}bin/**			Ux,
+  include <abstractions/pasta>
 }
-- 
2.39.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-27 16:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-27 16:38 [PATCH] contrib/apparmor: Split profile into abstractions, use them Stefano Brivio

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).