# apparmor.d - Full set of apparmor profiles
# Copyright (C) 2017-2021 Mikhail Morfikov
# 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}/X
@{exec_path} += @{bin}/Xorg{,.bin}
@{exec_path} += @{lib}/Xorg{,.wrap}
@{exec_path} += @{lib}/xorg/Xorg{,.wrap}
@{att} = /att/xorg/
profile xorg /{{,usr/}bin/Xorg{,.bin},{,usr/}lib{,exec,32,64}/Xorg{,.wrap},{,usr/}lib{,exec,32,64}/xorg/Xorg{,.wrap}}  flags=(attach_disconnected,attach_disconnected.path=@{att},complain) {
  include <abstractions/attached/base>
  include <abstractions/bus-system>
  include <abstractions/bus/org.freedesktop.login1.Session>
  include <abstractions/desktop>
  include <abstractions/fontconfig-cache-read>
  include <abstractions/graphics-full>
  include <abstractions/input>
  include <abstractions/nameservice-strict>

  capability chown,
  capability dac_override,
  capability dac_read_search,
  capability ipc_owner,
  capability mknod,
  capability net_admin,
  capability perfmon,
  capability setgid,
  capability setuid,
  capability sys_admin,
  capability sys_rawio,

  signal (send) set=(usr1),

  signal (receive) peer=lightdm,
  signal (receive) peer=sddm,
  signal (receive) peer=xinit,
  signal (receive) set=hup peer=gdm-session-worker,
  signal (receive) set=term peer=gdm{,-session},

  unix (bind, listen)          type=stream addr=@/tmp/.X11-unix/*,
  unix (send, receive, accept) type=stream addr=@/tmp/.X11-unix/*, # all peers

  network netlink raw,

  dbus send bus=system path=/org/freedesktop/login1/session/*
       interface=org.freedesktop.login1.Session
       member=ReleaseControl
       peer=(name=org.freedesktop.login1, label="@{p_systemd_logind}"),

  @{exec_path} mrix,

  @{sh_path}        rix,
  @{bin}/xkbcomp    rpx,
  @{bin}/pkexec     rcx -> pkexec,

  @{lib}/xorg/ r,
  @{lib}/xorg/modules/ r,
  @{lib}/xorg/modules/** mr,

  /var/lib/xkb/server-@{int}.xkm rw,
  /var/lib/xkb/compiled/server-@{int}.xkm rw,

  /usr/share/libinput*/{,**} r,

  /etc/X11/{,**} r,

  owner @{HOME}/ r,

  owner @{user_share_dirs}/xorg/ rw,
  owner @{user_share_dirs}/xorg/Xorg.@{int}.log{,.old} rw,
  owner @{user_share_dirs}/xorg/Xorg.pid-@{pid}.log{,.old} rw,

  owner /var/log/lightdm/x-*.log* rw,
  owner /var/log/Xorg.@{int}.log{,.old} rw,
  owner /var/log/Xorg.pid-@{pid}.log{,.old} rw,

  owner @{desktop_share_dirs}/xorg/ rw,
  owner @{desktop_share_dirs}/xorg/Xorg.@{int}.log{,.old} rw,
  owner @{desktop_share_dirs}/xorg/Xorg.pid-@{pid}.log{,.old} rw,

  @{run}/nvidia-xdriver-* rw,
  @{run}/sddm/{,**} rw,
  @{run}/lightdm/{,**} rw,

        /tmp/ r,
        /tmp/server-@{int}.xkm rw,
  owner @{tmp}/.tX@{int}-lock rwk,
  owner @{tmp}/.X@{int}-lock rwkl -> @{tmp}/.tX@{int}-lock,
  owner @{tmp}/server-* rwk,
  owner @{tmp}/serverauth.* r,

  @{run}/udev/data/+acpi:* r,             # Exposes ACPI objects (power buttons, batteries, thermal)
  @{run}/udev/data/+dmi* r,               # for motherboard info
  @{run}/udev/data/+drm:card@{int}-* r,   # For screen outputs
  @{run}/udev/data/+hid:* r,              # For Human Interface Device (mice, controllers, drawing tablets, scanners)
  @{run}/udev/data/+i2c:* r,              # For Inter-Integrated Circuit, low-speed peripherals (sensors, EEPROMs, etc.)
  @{run}/udev/data/+pci:* r,              # Identifies all PCI devices (CPU, GPU, Network, Disks, USB, etc.)
  @{run}/udev/data/+platform:* r,         # Identifies onboard devices (laptop/board model, power controllers, thermal sensors)
  @{run}/udev/data/+serio:* r,            # for touchpad?
  @{run}/udev/data/+sound:card@{int} r,   # for sound card
  @{run}/udev/data/+usb:* r,              # Identifies all USB devices

  @{run}/udev/data/c4:@{int}   r,         # for /dev/tty[0-9]*
  @{run}/udev/data/c5:@{int}   r,         # for /dev/tty, /dev/console, /dev/ptmx
  @{run}/udev/data/c10:@{int} r,          # for non-serial mice, misc features
  @{run}/udev/data/c189:@{int} r,         # for /dev/bus/usb/**

  @{sys}/bus/ r,
  @{sys}/bus/pci/devices/ r,
  @{sys}/class/ r,
  @{sys}/class/{tty,input,drm}/ r,
  @{sys}/class/power_supply/ r,
  @{sys}/devices/@{pci}/ r,
  @{sys}/devices/@{pci}/backlight/**/{,max_,actual_}brightness r,
  @{sys}/devices/@{pci}/backlight/**/{uevent,type,enabled} r,
  @{sys}/devices/@{pci}/backlight/**/brightness rw,
  @{sys}/devices/@{pci}/boot_vga r,
  @{sys}/devices/@{pci}/resource@{int} rw,
  @{sys}/devices/**/{uevent,name,id,config} r,
  @{sys}/devices/**/hid r,
  @{sys}/devices/**/power_supply/**/{type,online} r,
  @{sys}/devices/platform/ r,
  @{sys}/module/i915/{,**} r,

  @{PROC}/@{pids}/cmdline r,
  @{PROC}/cmdline r,
  @{PROC}/ioports r,
  @{PROC}/mtrr rw,

  /dev/ r,
  /dev/fb@{int} rw,
  /dev/shm/#@{int} rw,
  /dev/shm/shmfd-* rw,
  /dev/tty rw,
  /dev/tty@{int} rw,
  /dev/udmabuf rw,
  /dev/vga_arbiter rw,  # Graphic card modules

  profile pkexec flags=(attach_disconnected,attach_disconnected.path=@{att},complain) {
    include <abstractions/attached/base>
    include <abstractions/app/pkexec>

    include if exists <local/xorg_pkexec>
  }

  include if exists <local/xorg>
}

# vim:syntax=apparmor
