# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
# SPDX-License-Identifier: GPL-2.0-only

abi <abi/4.0>,

include <tunables/global>

@{exec_path} = @{bin}/pacman
profile pacman @{exec_path} flags=(attach_disconnected) {
  include <abstractions/base>
  include <abstractions/consoles>
  include <abstractions/disks-read>
  include <abstractions/nameservice-strict>
  include <abstractions/ssl_certs>

  capability audit_write,
  capability chown,
  capability dac_override,
  capability dac_read_search,
  capability fowner,
  capability fsetid,
  capability kill,
  capability mknod,
  capability net_admin,
  capability setfcap,
  capability setgid,
  capability setuid,
  capability sys_chroot,
  capability sys_ptrace,
  capability sys_resource,

  network inet stream,
  network inet6 stream,
  network inet dgram,
  network inet6 dgram,
  network netlink raw,
  network unix stream,

  ptrace read,

  signal send,
  signal receive set=winch peer=makepkg//sudo,

  @{exec_path} mrix,

  @{bin}/gpg{,2}      rCx -> gpg,
  @{bin}/gpgconf      rCx -> gpg,
  @{bin}/gpgsm        rCx -> gpg,

  # Pacman hooks & install scripts
  @{sh_path}                         rix,
  @{coreutils_path}                  rix,
  @{bin}/appstreamcli                rPx,
  @{bin}/arch-audit                  rPx,
  @{bin}/archlinux-java              rPx,
  @{bin}/bootctl                     rPx,
  @{bin}/cert-sync                   rPx,
  @{bin}/checkrebuild                rPUx,
  @{bin}/dconf                       rPx,
  @{bin}/dot                         rix,
  @{bin}/fc-cache{,-32}              rPx,
  @{bin}/filecap                     rix,
  @{bin}/gdbus                       rix,
  @{bin}/gdk-pixbuf-query-loaders    rPx,
  @{bin}/getent                      rix,
  @{bin}/gettext                     rix,
  @{bin}/ghc-pkg-@{version}          rix,
  @{bin}/gio-querymodules            rPx,
  @{bin}/glib-compile-schemas        rPx,
  @{bin}/groupadd                    rPx,
  @{bin}/gtk-query-immodules-{2,3}.0 rPx,
  @{bin}/gtk{,4}-update-icon-cache   rPx,
  @{bin}/iconvconfig                 rix,
  @{bin}/install-catalog             rPx,
  @{bin}/install-info                rPx,
  @{bin}/iscsi-iname                 rix,
  @{bin}/journalctl                  rPx,
  @{bin}/killall                     rix,
  @{bin}/ldconfig                    rix,
  @{bin}/locale-gen                  rPx,
  @{bin}/mkinitcpio                  rPx,
  @{bin}/needrestart                 rPx,
  @{bin}/pacdiff                     rPx,
  @{bin}/pacman-key                  rPx,
  @{bin}/perl                        rix,
  @{bin}/pkgfile                     rPUx,
  @{bin}/pkill                       rix,
  @{bin}/rsync                       rix,
  @{bin}/sbctl                       rPx,
  @{bin}/setcap                      rix,
  @{bin}/setfacl                     rix,
  @{bin}/sysctl                      rPx,
  @{bin}/systemctl                   rCx -> systemctl,
  @{bin}/systemd-*                   rPx,
  @{bin}/tput                        rix,
  @{bin}/update-ca-trust             rPx,
  @{bin}/update-desktop-database     rPx,
  @{bin}/update-grub                 rPx,
  @{bin}/update-mime-database        rPx,
  @{bin}/vercmp                      rix,
  @{bin}/which                       rix,
  @{bin}/xmlcatalog                  rix,
  @{lib}/systemd/systemd-*           rPx,
  @{lib}/ghc-@{version}/bin/ghc-pkg-@{version} rix,
  @{lib}/vlc/vlc-cache-gen           rPx,
  /opt/Mullvad*/resources/mullvad-setup  rPx,
  /usr/share/code-features/patch.py      rPx,
  /usr/share/code-marketplace/patch.py   rPx,
  /usr/share/libalpm/scripts/*           rPUx,
  /usr/share/texmf-dist/scripts/texlive/mktexlsr rPUx,

  # Install/update packages
  / r,
  /*{,/} rw,
  /boot/** rwl -> /boot/**,
  /etc/** rwl -> /etc/**,
  /opt/** rwl -> /opt/**,
  /srv/** rwl -> /srv/**,
  /usr/** rwlk -> /usr/**,
  /var/** rwlk -> /var/**,

  # Read packages files
  @{user_pkg_dirs}/{,**} r,

  owner /var/lib/pacman/{,**} rwl,
  owner @{tmp}/alpm_@{rand6}/{,**} rw,
  owner @{tmp}/checkup-db-@{int}/sync/{,*.db*} rw,
  owner @{tmp}/checkup-db-@{int}/db.lck rw,

  @{run}/utmp rk,

  @{sys}/{,**} r,

        @{PROC}/@{pids}/ r,
        @{PROC}/@{pids}/cgroup r,
        @{PROC}/@{pids}/cmdline r,
        @{PROC}/@{pids}/stat r,
        @{PROC}/1/environ r,
        @{PROC}/sys/kernel/osrelease r,
        @{PROC}/tty/drivers r,
        @{PROC}/uptime r,
  owner @{PROC}/@{pid}/fd/ r,
  owner @{PROC}/@{pid}/mounts r,

        /dev/tty@{int} rw,
  owner /dev/pts/@{int} rw,

  # Silencer,
  deny @{HOME}/ r,
  deny @{HOME}/**/ r,
  deny /tmp/ r,

  profile gpg {
    include <abstractions/base>
    include <abstractions/nameservice-strict>
    include <abstractions/ssl_certs>

    capability dac_read_search,

    network inet stream,
    network inet6 stream,
    network inet dgram,
    network inet6 dgram,

    @{bin}/gpg{,2} mr,
    @{bin}/gpgconf mr,
    @{bin}/gpgsm   mr,

    @{bin}/dirmngr           rix,
    @{bin}/gpg-agent         rix,
    @{bin}/gpg-connect-agent rix,

    /etc/pacman.d/gnupg/ rw,
    /etc/pacman.d/gnupg/** rwkl -> /etc/pacman.d/gnupg/**,

    @{HOME}/@{XDG_GPG_DIR}/*.conf r,

    @{PROC}/@{pid}/fd/ r,
    @{PROC}/@{pid}/task/@{tid}/comm rw,

          /dev/tty@{int} rw,
    owner /dev/pts/@{int} rw,

    deny @{user_share_dirs}/sddm/* rw,

    include if exists <local/pacman_gpg>
  }

  profile systemctl {
    include <abstractions/base>
    include <abstractions/app/systemctl>

    capability net_admin,
    capability dac_read_search,
    capability sys_resource,

    signal send set=cont peer=child-pager,
    signal receive set=winch peer=makepkg//sudo,

    @{pager_path}      rPx -> child-pager,
    @{bin}/systemd-tty-ask-password-agent rPx,

    /etc/machine-id r,

    /{run,var}/log/journal/ r,
    /{run,var}/log/journal/@{hex32}/ r,
    /{run,var}/log/journal/@{hex32}/*.journal* r,

    include if exists <local/pacman_systemctl>
  }

  include if exists <usr/pacman.d>
  include if exists <local/pacman>
}

# vim:syntax=apparmor
