# 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}/man
profile man @{exec_path} {
  include <abstractions/base>
  include <abstractions/consoles>

  signal peer=man//man_groff,
  signal peer=man//man_filter,

  @{exec_path} mr,

  # Use a special profile when man calls anything groff-related. We only include
  # the programs that actually parse input data in a non-trivial way, not
  # wrappers such as groff and nroff, since they would need a broader profile.
  @{bin}/eqn      rCx -> man_groff,
  @{bin}/grap     rCx -> man_groff,
  @{bin}/pic      rCx -> man_groff,
  @{bin}/preconv  rCx -> man_groff,
  @{bin}/refer    rCx -> man_groff,
  @{bin}/tbl      rCx -> man_groff,
  @{bin}/troff    rCx -> man_groff,
  @{bin}/vgrind   rCx -> man_groff,

  # Use a special profile when man calls decompressors and other simple filters.
  @{bin}/bzip2      rCx -> man_filter,
  @{bin}/gzip       rCx -> man_filter,
  @{bin}/col        rCx -> man_filter,
  @{bin}/compress   rCx -> man_filter,
  @{bin}/iconv      rCx -> man_filter,
  @{bin}/lzip.lzip  rCx -> man_filter,
  @{bin}/tr         rCx -> man_filter,
  @{bin}/xz         rCx -> man_filter,

  @{bin}/pager      rPx -> child-pager,
  @{bin}/less       rPx -> child-pager,
  @{bin}/more       rPx -> child-pager,

  @{bin}/locale rix,

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

  /usr/**/man/{,**} r,
  /var/**/man/{,**} r,
  /var/cache/man/index.db rk,

  /etc/man_db.conf r,
  /etc/manpath.config r,

  /dev/tty r,

  include if exists <local/man>
}

profile man_groff {
  include <abstractions/base>
  include <abstractions/consoles>

  signal peer=man,

  @{bin}/eqn      mr,
  @{bin}/grap     mr,
  @{bin}/pic      mr,
  @{bin}/preconv  mr,
  @{bin}/refer    mr,
  @{bin}/tbl      mr,
  @{bin}/troff    mr,
  @{bin}/vgrind   mr,

  @{lib}/groff/site-tmac/** r,
  /usr/share/groff/** r,

  /etc/groff/** r,
  /etc/papersize r,

  /tmp/groff* rw,
  owner @{tmp}/* rw,

  include if exists <local/man_groff>
}

profile man_filter {
  include <abstractions/base>
  include <abstractions/consoles>

  signal peer=man,

  @{bin}/bzip2      mr,
  @{bin}/gzip       mr,
  @{bin}/col        mr,
  @{bin}/compress   mr,
  @{bin}/iconv      mr,
  @{bin}/lzip.lzip  mr,
  @{bin}/tr         mr,
  @{bin}/xz         mr,

  # Manual pages can be more or less anywhere, especially with "man -l", and
  # there's no harm in allowing wide read access here since the worst it can
  # do is feed data to the invoking man process.
        /usr/** r,
  owner @{HOME}/@{XDG_DATA_DIR}/** r,
  owner @{user_projects_dirs}/** r,
  owner @{user_cache_dirs}/** r,
  owner @{MOUNTS}/*/@{XDG_DATA_DIR}/** r,

  /var/cache/man/** w,

  include if exists <local/man_filter>
}

# vim:syntax=apparmor
