# AppArmor profile for MariaDB 11.8 server daemon
#
# TESTING:
# - Monitor denials: journalctl -k --since=yesterday --follow --grep="apparmor"
# - Test in complain mode first: aa-complain /etc/apparmor.d/mariadbd
# - See confinement status: aa-status | grep -C 10 mariadb
# - Check specific denials: aa-logprof
# - Test all server functionality: systemctl restart mariadb
# - Verify plugin loading, backups, replication, all packaged Galera SST
#   mechanisms (both donor + joiner), etc.
#
# CONTAINMENT ERRORS:
# - Check syslog/journal for "apparmor=denied" messages
# - Look for "operation=open" denials for file access
# - Check for "operation=exec" denials for program execution
# - Monitor /var/log/audit/audit.log if auditd is installed
#
# PROFILE UPDATE WORKFLOW:
# 1. Identify denial in logs (operation, path, requested_mask)
# 2. Add appropriate rule to this profile
# 3. Reload profile: apparmor_parser -r /etc/apparmor.d/mariadbd
# 4. Test again in complain mode
# 5. Switch to enforce mode when confident: aa-enforce /etc/apparmor.d/mariadbd
# 6. Consider adding site-specific rules to /etc/apparmor.d/local/mariadbd

# Define RUN, HOMEDIRS etc globally
include <tunables/global>

profile mariadbd /usr/sbin/mariadbd flags=(attach_disconnected) {

  # Including <abstractions/base> does not work on Ubuntu 24.04. The issue was
  # fixed upstream https://gitlab.com/apparmor/apparmor/-/merge_requests/1236
  # but has not landed on ubuntu 24.04 yet (tracking in
  # https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2065685)
  include <abstractions/base>
  include <abstractions/nameservice>
  include <abstractions/user-tmp>
  include <abstractions/mysql>
  include <abstractions/winbind>

  # Minimal essential rules traditionally provided by abstractions/base
  # These rules are commonly needed by system services and avoid the passt inclusion
  capability chown,
  capability fowner,
  # per systemd service file is used with --memlock to lock memory beyond the usual rlimit
  capability ipc_lock,
  # Galera gu_thread_setschedparam still uses this
  capability sys_nice,
  capability kill,
  network inet stream,
  network inet dgram,
  network unix stream,
  # Probably excessive/unnecessary:
  #@{PROC}/sys/kernel/ngroups_max r,
  #@{PROC}/@{pid}/fd/ r,
  #@{PROC}/@{pid}/stat r,

  # Allow system resource access
  @{PROC}/@{pid}/cgroup r,
  @{PROC}/@{pid}/status r,
  @{PROC}/sys/kernel/core_pattern r,
  @{sys}/block/** r,
  @{sys}/block/*/queue/** r,
  @{sys}/devices/**/queue/** r,
  @{sys}/devices/system/cpu/ r,
  @{sys}/devices/system/node/ r,
  @{sys}/devices/system/node/** r,

  # Should not be necessary according to Daniel Black:
  #capability dac_override,
  #capability dac_read_search,
  # Should not be necessary as mariadbd does not run as root:
  #capability setuid,
  #capability setgid,

  # Allow network access
  network tcp,

  # Allow config access
  /etc/ r,
  /etc/mariadb/** r,
  /etc/mysql/** r,
  /etc/ssl/openssl.cnf r,
  /etc/systemd/system/mariadb.service.d/ r,
  /etc/systemd/system/mariadb.service.d/** r,

  # Allow pid, socket, socket lock file access
  /run/mariadbd/** rw,
  /run/mysqld/** rw,

  # Allow systemd notify messages
  /run/systemd/notify w,
  /run/systemd/private rw,

  # Allow execution of server binary
  /usr/sbin/mariadbd mr,
  /usr/sbin/mysqld mr,

  # Allow plugin access
  /usr/lib/{@{multiarch},mysql}/mariadb{,d}/plugin/ r,
  /usr/lib/{@{multiarch},mysql}/mariadb{,d}/plugin/*.so* mr,
  /usr/lib/mysql/plugin/ r,
  /usr/lib/mysql/plugin/*.so* mr,

  # Allow error msg and charset access
  /usr/share/mariadb/ r,
  /usr/share/mariadb/** r,

  # Allow data dir access
  /var/lib/mariadb/ r,
  /var/lib/mariadb/** rwk,
  /var/lib/mysql/ r,
  /var/lib/mysql/** rwk,

  # Allow log file access
  /var/log/mariadb/ r,
  /var/log/mariadb/** rw,
  /var/log/mysql/ r,
  /var/log/mysql/** rw,

  # Allow reading process mounts info (container/filesystem detection)
  @{PROC}/@{pid}/mounts r,
  @{PROC}/@{pid}/mountinfo r,
  @{PROC}/@{pid}/limits r,

  # Allow memory mapping limit introspection
  @{PROC}/sys/vm/mmap_min_addr r,

  # Allow shared memory access
  /{run,dev}/shm/** rw,

  # Allow cgroup hierarchy detection
  @{PROC}/cgroups r,

  # Allow cgroup v2 detection and memory limit introspection
  @{sys}/fs/cgroup/cgroup.controllers r,
  @{sys}/fs/cgroup/**/cpu.max r,
  @{sys}/fs/cgroup/**/memory.max r,
  @{sys}/fs/cgroup/**/memory.pressure rw,

  # For huge/large page support
  @{sys}/kernel/mm/hugepages/ r,
  @{sys}/kernel/mm/hugepages/** r,
  @{sys}/kernel/mm/transparent_hugepage/enabled r,
  @{sys}/kernel/mm/transparent_hugepage/shmem_enabled r,

  # Innodb physical disk size introspection
  @{sys}/dev/block/*/queue/physical_block_size r,
  @{sys}/devices/**/queue/physical_block_size r,

  # Additional sys/block access for RocksDB/InnoDB disk introspection
  /sys/block/ r,
  /sys/devices/virtual/block/*/dev r,

  # Allow cracklib dictionary access (for cracklib_password_check plugin)
  /var/cache/cracklib/cracklib_dict.* r,

  # Allow GSS mechanism configuration (for GSSAPI plugin)
  /etc/gss/mech.d/ r,
  /etc/gss/mech.d/* r,

  # Allow ODBC configuration (for Connect engine)
  /etc/odbc.ini r,
  /etc/odbcinst.ini r,
  /var/lib/odbc/*.ini r,
  owner @{HOME}/.odbc.ini rw,

  # Allow Java/OpenJDK configuration (for Connect engine and UDFs)
  /etc/java-*-openjdk/** r,

  # Allow network interface enumeration (for Java/Connect engine)
  @{PROC}/@{pid}/net/if_inet6 r,

  # Allow OS detection (lsb_release)
  /etc/lsb-release r,

  # Allow kernel version detection
  @{PROC}/version r,

  # Allow mmap of root directory (path resolution)
  / r,

  # UUID generation for internal use
  @{PROC}/sys/kernel/random/uuid r,

  # Thread name setting (required by some storage engines and for debugging)
  @{PROC}/@{pid}/task/*/comm rw,

  # Allow coredump filter configuration (for debugging)
  @{PROC}/@{pid}/coredump_filter rw,

  # Allow addr2line for stack trace symbolization on crashes
  /usr/bin/*-linux-gnu-addr2line mrix,

  # Deny invalid runbindable mount rule that causes parser errors
  # This broad deny rule should override any problematic mount operations
  # that might be included from system abstractions
  audit deny mount options=(runbindable),

  # Site-specific additions and overrides. See local/README for details.
  include if exists <local/mariadbd>
}
