code:
.. _psi:

================================
PSI - Pressure Stall Information
================================

:Date: April, 2018
:Author: Johannes Weiner <hannes@cmpxchg.org>

When CPU, memory or IO devices are contended, workloads experience
latency spikes, throughput losses, and run the risk of OOM kills.

Without an accurate measure of such contention, users are forced to
either play it safe and under-utilize their hardware resources, or
roll the dice and frequently suffer the disruptions resulting from
excessive overcommit.

The psi feature identifies and quantifies the disruptions caused by
such resource crunches and the time impact it has on complex workloads
or even entire systems.

Having an accurate measure of productivity losses caused by resource
scarcity aids users in sizing workloads to hardware--or provisioning
hardware according to workload demand.

As psi aggregates this information in realtime, systems can be managed
dynamically using techniques such as load shedding, migrating jobs to
other systems or data centers, or strategically pausing or killing low
priority or restartable batch jobs.

This allows maximizing hardware utilization without sacrificing
workload health or risking major disruptions such as OOM kills.

Pressure interface
==================

Pressure information for each resource is exported through the
respective file in /proc/pressure/ -- cpu, memory, and io.

The format is as such::

	some avg10=0.00 avg60=0.00 avg300=0.00 total=0
	full avg10=0.00 avg60=0.00 avg300=0.00 total=0

The "some" line indicates the share of time in which at least some
tasks are stalled on a given resource.

The "full" line indicates the share of time in which all non-idle
tasks are stalled on a given resource simultaneously. In this state
actual CPU cycles are going to waste, and a workload that spends
extended time in this state is considered to be thrashing. This has
severe impact on performance, and it's useful to distinguish this
situation from a state where some tasks are stalled but the CPU is
still doing productive work. As such, time spent in this subset of the
stall state is tracked separately and exported in the "full" averages.

CPU full is undefined at the system level, but has been reported
since 5.13, so it is set to zero for backward compatibility.

The ratios (in %) are tracked as recent trends over ten, sixty, and
three hundred second windows, which gives insight into short term events
as well as medium and long term trends. The total absolute stall time
(in us) is tracked and exported as well, to allow detection of latency
spikes which wouldn't necessarily make a dent in the time averages,
or to average trends over custom time frames.

Monitoring for pressure thresholds
==================================

Users can register triggers and use poll() to be woken up when resource
pressure exceeds certain thresholds.

A trigger describes the maximum cumulative stall time over a specific
time window, e.g. 100ms of total stall time within any 500ms window to
generate a wakeup event.

To register a trigger user has to open psi interface file under
/proc/pressure/ representing the resource to be monitored and write the
desired threshold and time window. The open file descriptor should be
used to wait for trigger events using select(), poll() or epoll().
The following format is used::

	<some|full> <stall amount in us> <time window in us>

For example writing "some 150000 1000000" into /proc/pressure/memory
would add 150ms threshold for partial memory stall measured within
1sec time window. Writing "full 50000 1000000" into /proc/pressure/io
would add 50ms threshold for full io stall measured within 1sec time window.

Triggers can be set on more than one psi metric and more than one trigger
for the same psi metric can be specified. However for each trigger a separate
file descriptor is required to be able to poll it separately from others,
therefore for each trigger a separate open() syscall should be made even
when opening the same psi interface file. Write operations to a file descriptor
with an already existing psi trigger will fail with EBUSY.

Monitors activate only when system enters stall state for the monitored
psi metric and deactivates upon exit from the stall state. While system is
in the stall state psi signal growth is monitored at a rate of 10 times per
tracking window.

The kernel accepts window sizes ranging from 500ms to 10s, therefore min
monitoring update interval is 50ms and max is 1s. Min limit is set to
prevent overly frequent polling. Max limit is chosen as a high enough number
after which monitors are most likely not needed and psi averages can be used
instead.

When activated, psi monitor stays active for at least the duration of one
tracking window to avoid repeated activations/deactivations when system is
bouncing in and out of the stall state.

Notifications to the userspace are rate-limited to one per tracking window.

The trigger will de-register when the file descriptor used to define the
trigger  is closed.

Userspace monitor usage example
===============================

::

  #include <errno.h>
  #include <fcntl.h>
  #include <stdio.h>
  #include <poll.h>
  #include <string.h>
  #include <unistd.h>

  /*
   * Monitor memory partial stall with 1s tracking window size
   * and 150ms threshold.
   */
  int main() {
	const char trig[] = "some 150000 1000000";
	struct pollfd fds;
	int n;

	fds.fd = open("/proc/pressure/memory", O_RDWR | O_NONBLOCK);
	if (fds.fd < 0) {
		printf("/proc/pressure/memory open error: %s\n",
			strerror(errno));
		return 1;
	}
	fds.events = POLLPRI;

	if (write(fds.fd, trig, strlen(trig) + 1) < 0) {
		printf("/proc/pressure/memory write error: %s\n",
			strerror(errno));
		return 1;
	}

	printf("waiting for events...\n");
	while (1) {
		n = poll(&fds, 1, -1);
		if (n < 0) {
			printf("poll error: %s\n", strerror(errno));
			return 1;
		}
		if (fds.revents & POLLERR) {
			printf("got POLLERR, event source is gone\n");
			return 0;
		}
		if (fds.revents & POLLPRI) {
			printf("event triggered!\n");
		} else {
			printf("unknown event received: 0x%x\n", fds.revents);
			return 1;
		}
	}

	return 0;
  }

Cgroup2 interface
=================

In a system with a CONFIG_CGROUP=y kernel and the cgroup2 filesystem
mounted, pressure stall information is also tracked for tasks grouped
into cgroups. Each subdirectory in the cgroupfs mountpoint contains
cpu.pressure, memory.pressure, and io.pressure files; the format is
the same as the /proc/pressure/ files.

Per-cgroup psi monitors can be specified and used the same way as
system-wide ones.


code:
====================
The struct taskstats
====================

This document contains an explanation of the struct taskstats fields.

There are three different groups of fields in the struct taskstats:

1) Common and basic accounting fields
    If CONFIG_TASKSTATS is set, the taskstats interface is enabled and
    the common fields and basic accounting fields are collected for
    delivery at do_exit() of a task.
2) Delay accounting fields
    These fields are placed between::

	/* Delay accounting fields start */

    and::

	/* Delay accounting fields end */

    Their values are collected if CONFIG_TASK_DELAY_ACCT is set.
3) Extended accounting fields
    These fields are placed between::

	/* Extended accounting fields start */

    and::

	/* Extended accounting fields end */

    Their values are collected if CONFIG_TASK_XACCT is set.

4) Per-task and per-thread context switch count statistics

5) Time accounting for SMT machines

6) Extended delay accounting fields for memory reclaim

Future extension should add fields to the end of the taskstats struct, and
should not change the relative position of each field within the struct.

::

  struct taskstats {

1) Common and basic accounting fields::

	/* The version number of this struct. This field is always set to
	 * TAKSTATS_VERSION, which is defined in <linux/taskstats.h>.
	 * Each time the struct is changed, the value should be incremented.
	 */
	__u16	version;

	/* The exit code of a task. */
	__u32	ac_exitcode;		/* Exit status */

	/* The accounting flags of a task as defined in <linux/acct.h>
	 * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG.
	 */
	__u8	ac_flag;		/* Record flags */

	/* The value of task_nice() of a task. */
	__u8	ac_nice;		/* task_nice */

	/* The name of the command that started this task. */
	char	ac_comm[TS_COMM_LEN];	/* Command name */

	/* The scheduling discipline as set in task->policy field. */
	__u8	ac_sched;		/* Scheduling discipline */

	__u8	ac_pad[3];
	__u32	ac_uid;			/* User ID */
	__u32	ac_gid;			/* Group ID */
	__u32	ac_pid;			/* Process ID */
	__u32	ac_ppid;		/* Parent process ID */

	/* The time when a task begins, in [secs] since 1970. */
	__u32	ac_btime;		/* Begin time [sec since 1970] */

	/* The elapsed time of a task, in [usec]. */
	__u64	ac_etime;		/* Elapsed time [usec] */

	/* The user CPU time of a task, in [usec]. */
	__u64	ac_utime;		/* User CPU time [usec] */

	/* The system CPU time of a task, in [usec]. */
	__u64	ac_stime;		/* System CPU time [usec] */

	/* The minor page fault count of a task, as set in task->min_flt. */
	__u64	ac_minflt;		/* Minor Page Fault Count */

	/* The major page fault count of a task, as set in task->maj_flt. */
	__u64	ac_majflt;		/* Major Page Fault Count */

2) Delay accounting fields::

	/* Delay accounting fields start
	 *
	 * All values, until the comment "Delay accounting fields end" are
	 * available only if delay accounting is enabled, even though the last
	 * few fields are not delays
	 *
	 * xxx_count is the number of delay values recorded
	 * xxx_delay_total is the corresponding cumulative delay in nanoseconds
	 *
	 * xxx_delay_total wraps around to zero on overflow
	 * xxx_count incremented regardless of overflow
	 */

	/* Delay waiting for cpu, while runnable
	 * count, delay_total NOT updated atomically
	 */
	__u64	cpu_count;
	__u64	cpu_delay_total;

	/* Following four fields atomically updated using task->delays->lock */

	/* Delay waiting for synchronous block I/O to complete
	 * does not account for delays in I/O submission
	 */
	__u64	blkio_count;
	__u64	blkio_delay_total;

	/* Delay waiting for page fault I/O (swap in only) */
	__u64	swapin_count;
	__u64	swapin_delay_total;

	/* cpu "wall-clock" running time
	 * On some architectures, value will adjust for cpu time stolen
	 * from the kernel in involuntary waits due to virtualization.
	 * Value is cumulative, in nanoseconds, without a corresponding count
	 * and wraps around to zero silently on overflow
	 */
	__u64	cpu_run_real_total;

	/* cpu "virtual" running time
	 * Uses time intervals seen by the kernel i.e. no adjustment
	 * for kernel's involuntary waits due to virtualization.
	 * Value is cumulative, in nanoseconds, without a corresponding count
	 * and wraps around to zero silently on overflow
	 */
	__u64	cpu_run_virtual_total;
	/* Delay accounting fields end */
	/* version 1 ends here */

3) Extended accounting fields::

	/* Extended accounting fields start */

	/* Accumulated RSS usage in duration of a task, in MBytes-usecs.
	 * The current rss usage is added to this counter every time
	 * a tick is charged to a task's system time. So, at the end we
	 * will have memory usage multiplied by system time. Thus an
	 * average usage per system time unit can be calculated.
	 */
	__u64	coremem;		/* accumulated RSS usage in MB-usec */

	/* Accumulated virtual memory usage in duration of a task.
	 * Same as acct_rss_mem1 above except that we keep track of VM usage.
	 */
	__u64	virtmem;		/* accumulated VM usage in MB-usec */

	/* High watermark of RSS usage in duration of a task, in KBytes. */
	__u64	hiwater_rss;		/* High-watermark of RSS usage */

	/* High watermark of VM  usage in duration of a task, in KBytes. */
	__u64	hiwater_vm;		/* High-water virtual memory usage */

	/* The following four fields are I/O statistics of a task. */
	__u64	read_char;		/* bytes read */
	__u64	write_char;		/* bytes written */
	__u64	read_syscalls;		/* read syscalls */
	__u64	write_syscalls;		/* write syscalls */

	/* Extended accounting fields end */

4) Per-task and per-thread statistics::

	__u64	nvcsw;			/* Context voluntary switch counter */
	__u64	nivcsw;			/* Context involuntary switch counter */

5) Time accounting for SMT machines::

	__u64	ac_utimescaled;		/* utime scaled on frequency etc */
	__u64	ac_stimescaled;		/* stime scaled on frequency etc */
	__u64	cpu_scaled_run_real_total; /* scaled cpu_run_real_total */

6) Extended delay accounting fields for memory reclaim::

	/* Delay waiting for memory reclaim */
	__u64	freepages_count;
	__u64	freepages_delay_total;

::

  }

repo_name: angery/linux


code:
=============================
Per-task statistics interface
=============================

Taskstats is a netlink-based interface for sending per-task and
per-process statistics from the kernel to userspace.

Taskstats was designed for the following benefits:

- efficiently provide statistics during lifetime of a task and on its exit
- unified interface for multiple accounting subsystems
- extensibility for use by future accounting patches

Terminology
-----------

"pid", "tid" and "task" are used interchangeably and refer to the standard
Linux task defined by struct task_struct.  per-pid stats are the same as
per-task stats.

"tgid", "process" and "thread group" are used interchangeably and refer to the
tasks that share an mm_struct i.e. the traditional Unix process. Despite the
use of tgid, there is no special treatment for the task that is thread group
leader - a process is deemed alive as long as it has any task belonging to it.

Usage
-----

To get statistics during a task's lifetime, userspace opens a unicast netlink
socket (NETLINK_GENERIC family) and sends commands specifying a pid or a tgid.
The response contains statistics for a task (if pid is specified) or the sum of
statistics for all tasks of the process (if tgid is specified).

To obtain statistics for tasks which are exiting, the userspace listener
sends a register command and specifies a cpumask. Whenever a task exits on
one of the cpus in the cpumask, its per-pid statistics are sent to the
registered listener. Using cpumasks allows the data received by one listener
to be limited and assists in flow control over the netlink interface and is
explained in more detail below.

If the exiting task is the last thread exiting its thread group,
an additional record containing the per-tgid stats is also sent to userspace.
The latter contains the sum of per-pid stats for all threads in the thread
group, both past and present.

getdelays.c is a simple utility demonstrating usage of the taskstats interface
for reporting delay accounting statistics. Users can register cpumasks,
send commands and process responses, listen for per-tid/tgid exit data,
write the data received to a file and do basic flow control by increasing
receive buffer sizes.

Interface
---------

The user-kernel interface is encapsulated in include/linux/taskstats.h

To avoid this documentation becoming obsolete as the interface evolves, only
an outline of the current version is given. taskstats.h always overrides the
description here.

struct taskstats is the common accounting structure for both per-pid and
per-tgid data. It is versioned and can be extended by each accounting subsystem
that is added to the kernel. The fields and their semantics are defined in the
taskstats.h file.

The data exchanged between user and kernel space is a netlink message belonging
to the NETLINK_GENERIC family and using the netlink attributes interface.
The messages are in the format::

    +----------+- - -+-------------+-------------------+
    | nlmsghdr | Pad |  genlmsghdr | taskstats payload |
    +----------+- - -+-------------+-------------------+

The taskstats payload is one of the following three kinds:

1. Commands: Sent from user to kernel. Commands to get data on
a pid/tgid consist of one attribute, of type TASKSTATS_CMD_ATTR_PID/TGID,
containing a u32 pid or tgid in the attribute payload. The pid/tgid denotes
the task/process for which userspace wants statistics.

Commands to register/deregister interest in exit data from a set of cpus
consist of one attribute, of type
TASKSTATS_CMD_ATTR_REGISTER/DEREGISTER_CPUMASK and contain a cpumask in the
attribute payload. The cpumask is specified as an ascii string of
comma-separated cpu ranges e.g. to listen to exit data from cpus 1,2,3,5,7,8
the cpumask would be "1-3,5,7-8". If userspace forgets to deregister interest
in cpus before closing the listening socket, the kernel cleans up its interest
set over time. However, for the sake of efficiency, an explicit deregistration
is advisable.

2. Response for a command: sent from the kernel in response to a userspace
command. The payload is a series of three attributes of type:

a) TASKSTATS_TYPE_AGGR_PID/TGID : attribute containing no payload but indicates
a pid/tgid will be followed by some stats.

b) TASKSTATS_TYPE_PID/TGID: attribute whose payload is the pid/tgid whose stats
are being returned.

c) TASKSTATS_TYPE_STATS: attribute with a struct taskstats as payload. The
same structure is used for both per-pid and per-tgid stats.

3. New message sent by kernel whenever a task exits. The payload consists of a
   series of attributes of the following type:

a) TASKSTATS_TYPE_AGGR_PID: indicates next two attributes will be pid+stats
b) TASKSTATS_TYPE_PID: contains exiting task's pid
c) TASKSTATS_TYPE_STATS: contains the exiting task's per-pid stats
d) TASKSTATS_TYPE_AGGR_TGID: indicates next two attributes will be tgid+stats
e) TASKSTATS_TYPE_TGID: contains tgid of process to which task belongs
f) TASKSTATS_TYPE_STATS: contains the per-tgid stats for exiting task's process

per-tgid stats
--------------

Taskstats provides per-process stats, in addition to per-task stats, since
resource management is often done at a process granularity and aggregating task
stats in userspace alone is inefficient and potentially inaccurate (due to lack
of atomicity).

However, maintaining per-process, in addition to per-task stats, within the
kernel has space and time overheads. To address this, the taskstats code
accumulates each exiting task's statistics into a process-wide data structure.
When the last task of a process exits, the process level data accumulated also
gets sent to userspace (along with the per-task data).

When a user queries to get per-tgid data, the sum of all other live threads in
the group is added up and added to the accumulated total for previously exited
threads of the same thread group.

Extending taskstats
-------------------

There are two ways to extend the taskstats interface to export more
per-task/process stats as patches to collect them get added to the kernel
in future:

1. Adding more fields to the end of the existing struct taskstats. Backward
   compatibility is ensured by the version number within the
   structure. Userspace will use only the fields of the struct that correspond
   to the version its using.

2. Defining separate statistic structs and using the netlink attributes
   interface to return them. Since userspace processes each netlink attribute
   independently, it can always ignore attributes whose type it does not
   understand (because it is using an older version of the interface).

Choosing between 1. and 2. is a matter of trading off flexibility and
overhead. If only a few fields need to be added, then 1. is the preferable
path since the kernel and userspace don't need to incur the overhead of
processing new netlink attributes. But if the new fields expand the existing
struct too much, requiring disparate userspace accounting utilities to
unnecessarily receive large structures whose fields are of no interest, then
extending the attributes structure would be worthwhile.

Flow control for taskstats
--------------------------

When the rate of task exits becomes large, a listener may not be able to keep
up with the kernel's rate of sending per-tid/tgid exit data leading to data
loss. This possibility gets compounded when the taskstats structure gets
extended and the number of cpus grows large.

To avoid losing statistics, userspace should do one or more of the following:

- increase the receive buffer sizes for the netlink sockets opened by
  listeners to receive exit data.

- create more listeners and reduce the number of cpus being listened to by
  each listener. In the extreme case, there could be one listener for each cpu.
  Users may also consider setting the cpu affinity of the listener to the subset
  of cpus to which it listens, especially if they are listening to just one cpu.

Despite these measures, if the userspace receives ENOBUFS error messages
indicated overflow of receive buffers, it should take measures to handle the
loss of data.


code:
=======
LoadPin
=======

LoadPin is a Linux Security Module that ensures all kernel-loaded files
(modules, firmware, etc) all originate from the same filesystem, with
the expectation that such a filesystem is backed by a read-only device
such as dm-verity or CDROM. This allows systems that have a verified
and/or unchangeable filesystem to enforce module and firmware loading
restrictions without needing to sign the files individually.

The LSM is selectable at build-time with ``CONFIG_SECURITY_LOADPIN``, and
can be controlled at boot-time with the kernel command line option
"``loadpin.enforce``". By default, it is enabled, but can be disabled at
boot ("``loadpin.enforce=0``").

LoadPin starts pinning when it sees the first file loaded. If the
block device backing the filesystem is not read-only, a sysctl is
created to toggle pinning: ``/proc/sys/kernel/loadpin/enabled``. (Having
a mutable filesystem means pinning is mutable too, but having the
sysctl allows for easy testing on systems with a mutable filesystem.)

It's also possible to exclude specific file types from LoadPin using kernel
command line option "``loadpin.exclude``". By default, all files are
included, but they can be excluded using kernel command line option such
as "``loadpin.exclude=kernel-module,kexec-image``". This allows to use
different mechanisms such as ``CONFIG_MODULE_SIG`` and
``CONFIG_KEXEC_VERIFY_SIG`` to verify kernel module and kernel image while
still use LoadPin to protect the integrity of other files kernel loads. The
full list of valid file types can be found in ``kernel_read_file_str``
defined in ``include/linux/kernel_read_file.h``.


code:
=======
SELinux
=======

If you want to use SELinux, chances are you will want
to use the distro-provided policies, or install the
latest reference policy release from

	https://github.com/SELinuxProject/refpolicy

However, if you want to install a dummy policy for
testing, you can do using ``mdp`` provided under
scripts/selinux.  Note that this requires the selinux
userspace to be installed - in particular you will
need checkpolicy to compile a kernel, and setfiles and
fixfiles to label the filesystem.

	1. Compile the kernel with selinux enabled.
	2. Type ``make`` to compile ``mdp``.
	3. Make sure that you are not running with
	   SELinux enabled and a real policy.  If
	   you are, reboot with selinux disabled
	   before continuing.
	4. Run install_policy.sh::

		cd scripts/selinux
		sh install_policy.sh

Step 4 will create a new dummy policy valid for your
kernel, with a single selinux user, role, and type.
It will compile the policy, will set your ``SELINUXTYPE`` to
``dummy`` in ``/etc/selinux/config``, install the compiled policy
as ``dummy``, and relabel your filesystem.


code:
=========
SafeSetID
=========
SafeSetID is an LSM module that gates the setid family of syscalls to restrict
UID/GID transitions from a given UID/GID to only those approved by a
system-wide allowlist. These restrictions also prohibit the given UIDs/GIDs
from obtaining auxiliary privileges associated with CAP_SET{U/G}ID, such as
allowing a user to set up user namespace UID/GID mappings.

Background
==========
In absence of file capabilities, processes spawned on a Linux system that need
to switch to a different user must be spawned with CAP_SETUID privileges.
CAP_SETUID is granted to programs running as root or those running as a non-root
user that have been explicitly given the CAP_SETUID runtime capability. It is
often preferable to use Linux runtime capabilities rather than file
capabilities, since using file capabilities to run a program with elevated
privileges opens up possible security holes since any user with access to the
file can exec() that program to gain the elevated privileges.

While it is possible to implement a tree of processes by giving full
CAP_SET{U/G}ID capabilities, this is often at odds with the goals of running a
tree of processes under non-root user(s) in the first place. Specifically,
since CAP_SETUID allows changing to any user on the system, including the root
user, it is an overpowered capability for what is needed in this scenario,
especially since programs often only call setuid() to drop privileges to a
lesser-privileged user -- not elevate privileges. Unfortunately, there is no
generally feasible way in Linux to restrict the potential UIDs that a user can
switch to through setuid() beyond allowing a switch to any user on the system.
This SafeSetID LSM seeks to provide a solution for restricting setid
capabilities in such a way.

The main use case for this LSM is to allow a non-root program to transition to
other untrusted uids without full blown CAP_SETUID capabilities. The non-root
program would still need CAP_SETUID to do any kind of transition, but the
additional restrictions imposed by this LSM would mean it is a "safer" version
of CAP_SETUID since the non-root program cannot take advantage of CAP_SETUID to
do any unapproved actions (e.g. setuid to uid 0 or create/enter new user
namespace). The higher level goal is to allow for uid-based sandboxing of system
services without having to give out CAP_SETUID all over the place just so that
non-root programs can drop to even-lesser-privileged uids. This is especially
relevant when one non-root daemon on the system should be allowed to spawn other
processes as different uids, but its undesirable to give the daemon a
basically-root-equivalent CAP_SETUID.

Other Approaches Considered
===========================

Solve this problem in userspace
-------------------------------
For candidate applications that would like to have restricted setid capabilities
as implemented in this LSM, an alternative option would be to simply take away
setid capabilities from the application completely and refactor the process
spawning semantics in the application (e.g. by using a privileged helper program
to do process spawning and UID/GID transitions). Unfortunately, there are a
number of semantics around process spawning that would be affected by this, such
as fork() calls where the program doesn't immediately call exec() after the
fork(), parent processes specifying custom environment variables or command line
args for spawned child processes, or inheritance of file handles across a
fork()/exec(). Because of this, as solution that uses a privileged helper in
userspace would likely be less appealing to incorporate into existing projects
that rely on certain process-spawning semantics in Linux.

Use user namespaces
-------------------
Another possible approach would be to run a given process tree in its own user
namespace and give programs in the tree setid capabilities. In this way,
programs in the tree could change to any desired UID/GID in the context of their
own user namespace, and only approved UIDs/GIDs could be mapped back to the
initial system user namespace, affectively preventing privilege escalation.
Unfortunately, it is not generally feasible to use user namespaces in isolation,
without pairing them with other namespace types, which is not always an option.
Linux checks for capabilities based off of the user namespace that "owns" some
entity. For example, Linux has the notion that network namespaces are owned by
the user namespace in which they were created. A consequence of this is that
capability checks for access to a given network namespace are done by checking
whether a task has the given capability in the context of the user namespace
that owns the network namespace -- not necessarily the user namespace under
which the given task runs. Therefore spawning a process in a new user namespace
effectively prevents it from accessing the network namespace owned by the
initial namespace. This is a deal-breaker for any application that expects to
retain the CAP_NET_ADMIN capability for the purpose of adjusting network
configurations. Using user namespaces in isolation causes problems regarding
other system interactions, including use of pid namespaces and device creation.

Use an existing LSM
-------------------
None of the other in-tree LSMs have the capability to gate setid transitions, or
even employ the security_task_fix_setuid hook at all. SELinux says of that hook:
"Since setuid only affects the current process, and since the SELinux controls
are not based on the Linux identity attributes, SELinux does not need to control
this operation."

Directions for use
==================
This LSM hooks the setid syscalls to make sure transitions are allowed if an
applicable restriction policy is in place. Policies are configured through
securityfs by writing to the safesetid/uid_allowlist_policy and
safesetid/gid_allowlist_policy files at the location where securityfs is
mounted. The format for adding a policy is '<UID>:<UID>' or '<GID>:<GID>',
using literal numbers, and ending with a newline character such as '123:456\n'.
Writing an empty string "" will flush the policy. Again, configuring a policy
for a UID/GID will prevent that UID/GID from obtaining auxiliary setid
privileges, such as allowing a user to set up user namespace UID/GID mappings.

Note on GID policies and setgroups()
====================================
In v5.9 we are adding support for limiting CAP_SETGID privileges as was done
previously for CAP_SETUID. However, for compatibility with common sandboxing
related code conventions in userspace, we currently allow arbitrary
setgroups() calls for processes with CAP_SETGID restrictions. Until we add
support in a future release for restricting setgroups() calls, these GID
policies add no meaningful security. setgroups() restrictions will be enforced
once we have the policy checking code in place, which will rely on GID policy
configuration code added in v5.9.


code:
=====
Smack
=====

    "Good for you, you've decided to clean the elevator!"
    - The Elevator, from Dark Star

Smack is the Simplified Mandatory Access Control Kernel.
Smack is a kernel based implementation of mandatory access
control that includes simplicity in its primary design goals.

Smack is not the only Mandatory Access Control scheme
available for Linux. Those new to Mandatory Access Control
are encouraged to compare Smack with the other mechanisms
available to determine which is best suited to the problem
at hand.

Smack consists of three major components:

    - The kernel
    - Basic utilities, which are helpful but not required
    - Configuration data

The kernel component of Smack is implemented as a Linux
Security Modules (LSM) module. It requires netlabel and
works best with file systems that support extended attributes,
although xattr support is not strictly required.
It is safe to run a Smack kernel under a "vanilla" distribution.

Smack kernels use the CIPSO IP option. Some network
configurations are intolerant of IP options and can impede
access to systems that use them as Smack does.

Smack is used in the Tizen operating system. Please
go to http://wiki.tizen.org for information about how
Smack is used in Tizen.

The current git repository for Smack user space is:

	git://github.com/smack-team/smack.git

This should make and install on most modern distributions.
There are five commands included in smackutil:

chsmack:
	display or set Smack extended attribute values

smackctl:
	load the Smack access rules

smackaccess:
	report if a process with one label has access
	to an object with another

These two commands are obsolete with the introduction of
the smackfs/load2 and smackfs/cipso2 interfaces.

smackload:
	properly formats data for writing to smackfs/load

smackcipso:
	properly formats data for writing to smackfs/cipso

In keeping with the intent of Smack, configuration data is
minimal and not strictly required. The most important
configuration step is mounting the smackfs pseudo filesystem.
If smackutil is installed the startup script will take care
of this, but it can be manually as well.

Add this line to ``/etc/fstab``::

    smackfs /sys/fs/smackfs smackfs defaults 0 0

The ``/sys/fs/smackfs`` directory is created by the kernel.

Smack uses extended attributes (xattrs) to store labels on filesystem
objects. The attributes are stored in the extended attribute security
name space. A process must have ``CAP_MAC_ADMIN`` to change any of these
attributes.

The extended attributes that Smack uses are:

SMACK64
	Used to make access control decisions. In almost all cases
	the label given to a new filesystem object will be the label
	of the process that created it.

SMACK64EXEC
	The Smack label of a process that execs a program file with
	this attribute set will run with this attribute's value.

SMACK64MMAP
	Don't allow the file to be mmapped by a process whose Smack
	label does not allow all of the access permitted to a process
	with the label contained in this attribute. This is a very
	specific use case for shared libraries.

SMACK64TRANSMUTE
	Can only have the value "TRUE". If this attribute is present
	on a directory when an object is created in the directory and
	the Smack rule (more below) that permitted the write access
	to the directory includes the transmute ("t") mode the object
	gets the label of the directory instead of the label of the
	creating process. If the object being created is a directory
	the SMACK64TRANSMUTE attribute is set as well.

SMACK64IPIN
	This attribute is only available on file descriptors for sockets.
	Use the Smack label in this attribute for access control
	decisions on packets being delivered to this socket.

SMACK64IPOUT
	This attribute is only available on file descriptors for sockets.
	Use the Smack label in this attribute for access control
	decisions on packets coming from this socket.

There are multiple ways to set a Smack label on a file::

    # attr -S -s SMACK64 -V "value" path
    # chsmack -a value path

A process can see the Smack label it is running with by
reading ``/proc/self/attr/current``. A process with ``CAP_MAC_ADMIN``
can set the process Smack by writing there.

Most Smack configuration is accomplished by writing to files
in the smackfs filesystem. This pseudo-filesystem is mounted
on ``/sys/fs/smackfs``.

access
	Provided for backward compatibility. The access2 interface
	is preferred and should be used instead.
	This interface reports whether a subject with the specified
	Smack label has a particular access to an object with a
	specified Smack label. Write a fixed format access rule to
	this file. The next read will indicate whether the access
	would be permitted. The text will be either "1" indicating
	access, or "0" indicating denial.

access2
	This interface reports whether a subject with the specified
	Smack label has a particular access to an object with a
	specified Smack label. Write a long format access rule to
	this file. The next read will indicate whether the access
	would be permitted. The text will be either "1" indicating
	access, or "0" indicating denial.

ambient
	This contains the Smack label applied to unlabeled network
	packets.

change-rule
	This interface allows modification of existing access control rules.
	The format accepted on write is::

		"%s %s %s %s"

	where the first string is the subject label, the second the
	object label, the third the access to allow and the fourth the
	access to deny. The access strings may contain only the characters
	"rwxat-". If a rule for a given subject and object exists it will be
	modified by enabling the permissions in the third string and disabling
	those in the fourth string. If there is no such rule it will be
	created using the access specified in the third and the fourth strings.

cipso
	Provided for backward compatibility. The cipso2 interface
	is preferred and should be used instead.
	This interface allows a specific CIPSO header to be assigned
	to a Smack label. The format accepted on write is::

		"%24s%4d%4d"["%4d"]...

	The first string is a fixed Smack label. The first number is
	the level to use. The second number is the number of categories.
	The following numbers are the categories::

		"level-3-cats-5-19          3   2   5  19"

cipso2
	This interface allows a specific CIPSO header to be assigned
	to a Smack label. The format accepted on write is::

		"%s%4d%4d"["%4d"]...

	The first string is a long Smack label. The first number is
	the level to use. The second number is the number of categories.
	The following numbers are the categories::

		"level-3-cats-5-19   3   2   5  19"

direct
	This contains the CIPSO level used for Smack direct label
	representation in network packets.

doi
	This contains the CIPSO domain of interpretation used in
	network packets.

ipv6host
	This interface allows specific IPv6 internet addresses to be
	treated as single label hosts. Packets are sent to single
	label hosts only from processes that have Smack write access
	to the host label. All packets received from single label hosts
	are given the specified label. The format accepted on write is::

		"%h:%h:%h:%h:%h:%h:%h:%h label" or
		"%h:%h:%h:%h:%h:%h:%h:%h/%d label".

	The "::" address shortcut is not supported.
	If label is "-DELETE" a matched entry will be deleted.

load
	Provided for backward compatibility. The load2 interface
	is preferred and should be used instead.
	This interface allows access control rules in addition to
	the system defined rules to be specified. The format accepted
	on write is::

		"%24s%24s%5s"

	where the first string is the subject label, the second the
	object label, and the third the requested access. The access
	string may contain only the characters "rwxat-", and specifies
	which sort of access is allowed. The "-" is a placeholder for
	permissions that are not allowed. The string "r-x--" would
	specify read and execute access. Labels are limited to 23
	characters in length.

load2
	This interface allows access control rules in addition to
	the system defined rules to be specified. The format accepted
	on write is::

		"%s %s %s"

	where the first string is the subject label, the second the
	object label, and the third the requested access. The access
	string may contain only the characters "rwxat-", and specifies
	which sort of access is allowed. The "-" is a placeholder for
	permissions that are not allowed. The string "r-x--" would
	specify read and execute access.

load-self
	Provided for backward compatibility. The load-self2 interface
	is preferred and should be used instead.
	This interface allows process specific access rules to be
	defined. These rules are only consulted if access would
	otherwise be permitted, and are intended to provide additional
	restrictions on the process. The format is the same as for
	the load interface.

load-self2
	This interface allows process specific access rules to be
	defined. These rules are only consulted if access would
	otherwise be permitted, and are intended to provide additional
	restrictions on the process. The format is the same as for
	the load2 interface.

logging
	This contains the Smack logging state.

mapped
	This contains the CIPSO level used for Smack mapped label
	representation in network packets.

netlabel
	This interface allows specific internet addresses to be
	treated as single label hosts. Packets are sent to single
	label hosts without CIPSO headers, but only from processes
	that have Smack write access to the host label. All packets
	received from single label hosts are given the specified
	label. The format accepted on write is::

		"%d.%d.%d.%d label" or "%d.%d.%d.%d/%d label".

	If the label specified is "-CIPSO" the address is treated
	as a host that supports CIPSO headers.

onlycap
	This contains labels processes must have for CAP_MAC_ADMIN
	and ``CAP_MAC_OVERRIDE`` to be effective. If this file is empty
	these capabilities are effective at for processes with any
	label. The values are set by writing the desired labels, separated
	by spaces, to the file or cleared by writing "-" to the file.

ptrace
	This is used to define the current ptrace policy

	0 - default:
	    this is the policy that relies on Smack access rules.
	    For the ``PTRACE_READ`` a subject needs to have a read access on
	    object. For the ``PTRACE_ATTACH`` a read-write access is required.

	1 - exact:
	    this is the policy that limits ``PTRACE_ATTACH``. Attach is
	    only allowed when subject's and object's labels are equal.
	    ``PTRACE_READ`` is not affected. Can be overridden with ``CAP_SYS_PTRACE``.

	2 - draconian:
	    this policy behaves like the 'exact' above with an
	    exception that it can't be overridden with ``CAP_SYS_PTRACE``.

revoke-subject
	Writing a Smack label here sets the access to '-' for all access
	rules with that subject label.

unconfined
	If the kernel is configured with ``CONFIG_SECURITY_SMACK_BRINGUP``
	a process with ``CAP_MAC_ADMIN`` can write a label into this interface.
	Thereafter, accesses that involve that label will be logged and
	the access permitted if it wouldn't be otherwise. Note that this
	is dangerous and can ruin the proper labeling of your system.
	It should never be used in production.

relabel-self
	This interface contains a list of labels to which the process can
	transition to, by writing to ``/proc/self/attr/current``.
	Normally a process can change its own label to any legal value, but only
	if it has ``CAP_MAC_ADMIN``. This interface allows a process without
	``CAP_MAC_ADMIN`` to relabel itself to one of labels from predefined list.
	A process without ``CAP_MAC_ADMIN`` can change its label only once. When it
	does, this list will be cleared.
	The values are set by writing the desired labels, separated
	by spaces, to the file or cleared by writing "-" to the file.

If you are using the smackload utility
you can add access rules in ``/etc/smack/accesses``. They take the form::

    subjectlabel objectlabel access

access is a combination of the letters rwxatb which specify the
kind of access permitted a subject with subjectlabel on an
object with objectlabel. If there is no rule no access is allowed.

Look for additional programs on http://schaufler-ca.com

The Simplified Mandatory Access Control Kernel (Whitepaper)
===========================================================

Casey Schaufler
casey@schaufler-ca.com

Mandatory Access Control
------------------------

Computer systems employ a variety of schemes to constrain how information is
shared among the people and services using the machine. Some of these schemes
allow the program or user to decide what other programs or users are allowed
access to pieces of data. These schemes are called discretionary access
control mechanisms because the access control is specified at the discretion
of the user. Other schemes do not leave the decision regarding what a user or
program can access up to users or programs. These schemes are called mandatory
access control mechanisms because you don't have a choice regarding the users
or programs that have access to pieces of data.

Bell & LaPadula
---------------

From the middle of the 1980's until the turn of the century Mandatory Access
Control (MAC) was very closely associated with the Bell & LaPadula security
model, a mathematical description of the United States Department of Defense
policy for marking paper documents. MAC in this form enjoyed a following
within the Capital Beltway and Scandinavian supercomputer centers but was
often sited as failing to address general needs.

Domain Type Enforcement
-----------------------

Around the turn of the century Domain Type Enforcement (DTE) became popular.
This scheme organizes users, programs, and data into domains that are
protected from each other. This scheme has been widely deployed as a component
of popular Linux distributions. The administrative overhead required to
maintain this scheme and the detailed understanding of the whole system
necessary to provide a secure domain mapping leads to the scheme being
disabled or used in limited ways in the majority of cases.

Smack
-----

Smack is a Mandatory Access Control mechanism designed to provide useful MAC
while avoiding the pitfalls of its predecessors. The limitations of Bell &
LaPadula are addressed by providing a scheme whereby access can be controlled
according to the requirements of the system and its purpose rather than those
imposed by an arcane government policy. The complexity of Domain Type
Enforcement and avoided by defining access controls in terms of the access
modes already in use.

Smack Terminology
-----------------

The jargon used to talk about Smack will be familiar to those who have dealt
with other MAC systems and shouldn't be too difficult for the uninitiated to
pick up. There are four terms that are used in a specific way and that are
especially important:

  Subject:
	A subject is an active entity on the computer system.
	On Smack a subject is a task, which is in turn the basic unit
	of execution.

  Object:
	An object is a passive entity on the computer system.
	On Smack files of all types, IPC, and tasks can be objects.

  Access:
	Any attempt by a subject to put information into or get
	information from an object is an access.

  Label:
	Data that identifies the Mandatory Access Control
	characteristics of a subject or an object.

These definitions are consistent with the traditional use in the security
community. There are also some terms from Linux that are likely to crop up:

  Capability:
	A task that possesses a capability has permission to
	violate an aspect of the system security policy, as identified by
	the specific capability. A task that possesses one or more
	capabilities is a privileged task, whereas a task with no
	capabilities is an unprivileged task.

  Privilege:
	A task that is allowed to violate the system security
	policy is said to have privilege. As of this writing a task can
	have privilege either by possessing capabilities or by having an
	effective user of root.

Smack Basics
------------

Smack is an extension to a Linux system. It enforces additional restrictions
on what subjects can access which objects, based on the labels attached to
each of the subject and the object.

Labels
~~~~~~

Smack labels are ASCII character strings. They can be up to 255 characters
long, but keeping them to twenty-three characters is recommended.
Single character labels using special characters, that being anything
other than a letter or digit, are reserved for use by the Smack development
team. Smack labels are unstructured, case sensitive, and the only operation
ever performed on them is comparison for equality. Smack labels cannot
contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
(quote) and '"' (double-quote) characters.
Smack labels cannot begin with a '-'. This is reserved for special options.

There are some predefined labels::

	_ 	Pronounced "floor", a single underscore character.
	^ 	Pronounced "hat", a single circumflex character.
	* 	Pronounced "star", a single asterisk character.
	? 	Pronounced "huh", a single question mark character.
	@ 	Pronounced "web", a single at sign character.

Every task on a Smack system is assigned a label. The Smack label
of a process will usually be assigned by the system initialization
mechanism.

Access Rules
~~~~~~~~~~~~

Smack uses the traditional access modes of Linux. These modes are read,
execute, write, and occasionally append. There are a few cases where the
access mode may not be obvious. These include:

  Signals:
	A signal is a write operation from the subject task to
	the object task.

  Internet Domain IPC:
	Transmission of a packet is considered a
	write operation from the source task to the destination task.

Smack restricts access based on the label attached to a subject and the label
attached to the object it is trying to access. The rules enforced are, in
order:

	1. Any access requested by a task labeled "*" is denied.
	2. A read or execute access requested by a task labeled "^"
	   is permitted.
	3. A read or execute access requested on an object labeled "_"
	   is permitted.
	4. Any access requested on an object labeled "*" is permitted.
	5. Any access requested by a task on an object with the same
	   label is permitted.
	6. Any access requested that is explicitly defined in the loaded
	   rule set is permitted.
	7. Any other access is denied.

Smack Access Rules
~~~~~~~~~~~~~~~~~~

With the isolation provided by Smack access separation is simple. There are
many interesting cases where limited access by subjects to objects with
different labels is desired. One example is the familiar spy model of
sensitivity, where a scientist working on a highly classified project would be
able to read documents of lower classifications and anything she writes will
be "born" highly classified. To accommodate such schemes Smack includes a
mechanism for specifying rules allowing access between labels.

Access Rule Format
~~~~~~~~~~~~~~~~~~

The format of an access rule is::

	subject-label object-label access

Where subject-label is the Smack label of the task, object-label is the Smack
label of the thing being accessed, and access is a string specifying the sort
of access allowed. The access specification is searched for letters that
describe access modes:

	a: indicates that append access should be granted.
	r: indicates that read access should be granted.
	w: indicates that write access should be granted.
	x: indicates that execute access should be granted.
	t: indicates that the rule requests transmutation.
	b: indicates that the rule should be reported for bring-up.

Uppercase values for the specification letters are allowed as well.
Access mode specifications can be in any order. Examples of acceptable rules
are::

	TopSecret Secret  rx
	Secret    Unclass R
	Manager   Game    x
	User      HR      w
	Snap      Crackle rwxatb
	New       Old     rRrRr
	Closed    Off     -

Examples of unacceptable rules are::

	Top Secret Secret     rx
	Ace        Ace        r
	Odd        spells     waxbeans

Spaces are not allowed in labels. Since a subject always has access to files
with the same label specifying a rule for that case is pointless. Only
valid letters (rwxatbRWXATB) and the dash ('-') character are allowed in
access specifications. The dash is a placeholder, so "a-r" is the same
as "ar". A lone dash is used to specify that no access should be allowed.

Applying Access Rules
~~~~~~~~~~~~~~~~~~~~~

The developers of Linux rarely define new sorts of things, usually importing
schemes and concepts from other systems. Most often, the other systems are
variants of Unix. Unix has many endearing properties, but consistency of
access control models is not one of them. Smack strives to treat accesses as
uniformly as is sensible while keeping with the spirit of the underlying
mechanism.

File system objects including files, directories, named pipes, symbolic links,
and devices require access permissions that closely match those used by mode
bit access. To open a file for reading read access is required on the file. To
search a directory requires execute access. Creating a file with write access
requires both read and write access on the containing directory. Deleting a
file requires read and write access to the file and to the containing
directory. It is possible that a user may be able to see that a file exists
but not any of its attributes by the circumstance of having read access to the
containing directory but not to the differently labeled file. This is an
artifact of the file name being data in the directory, not a part of the file.

If a directory is marked as transmuting (SMACK64TRANSMUTE=TRUE) and the
access rule that allows a process to create an object in that directory
includes 't' access the label assigned to the new object will be that
of the directory, not the creating process. This makes it much easier
for two processes with different labels to share data without granting
access to all of their files.

IPC objects, message queues, semaphore sets, and memory segments exist in flat
namespaces and access requests are only required to match the object in
question.

Process objects reflect tasks on the system and the Smack label used to access
them is the same Smack label that the task would use for its own access
attempts. Sending a signal via the kill() system call is a write operation
from the signaler to the recipient. Debugging a process requires both reading
and writing. Creating a new task is an internal operation that results in two
tasks with identical Smack labels and requires no access checks.

Sockets are data structures attached to processes and sending a packet from
one process to another requires that the sender have write access to the
receiver. The receiver is not required to have read access to the sender.

Setting Access Rules
~~~~~~~~~~~~~~~~~~~~

The configuration file /etc/smack/accesses contains the rules to be set at
system startup. The contents are written to the special file
/sys/fs/smackfs/load2. Rules can be added at any time and take effect
immediately. For any pair of subject and object labels there can be only
one rule, with the most recently specified overriding any earlier
specification.

Task Attribute
~~~~~~~~~~~~~~

The Smack label of a process can be read from /proc/<pid>/attr/current. A
process can read its own Smack label from /proc/self/attr/current. A
privileged process can change its own Smack label by writing to
/proc/self/attr/current but not the label of another process.

File Attribute
~~~~~~~~~~~~~~

The Smack label of a filesystem object is stored as an extended attribute
named SMACK64 on the file. This attribute is in the security namespace. It can
only be changed by a process with privilege.

Privilege
~~~~~~~~~

A process with CAP_MAC_OVERRIDE or CAP_MAC_ADMIN is privileged.
CAP_MAC_OVERRIDE allows the process access to objects it would
be denied otherwise. CAP_MAC_ADMIN allows a process to change
Smack data, including rules and attributes.

Smack Networking
~~~~~~~~~~~~~~~~

As mentioned before, Smack enforces access control on network protocol
transmissions. Every packet sent by a Smack process is tagged with its Smack
label. This is done by adding a CIPSO tag to the header of the IP packet. Each
packet received is expected to have a CIPSO tag that identifies the label and
if it lacks such a tag the network ambient label is assumed. Before the packet
is delivered a check is made to determine that a subject with the label on the
packet has write access to the receiving process and if that is not the case
the packet is dropped.

CIPSO Configuration
~~~~~~~~~~~~~~~~~~~

It is normally unnecessary to specify the CIPSO configuration. The default
values used by the system handle all internal cases. Smack will compose CIPSO
label values to match the Smack labels being used without administrative
intervention. Unlabeled packets that come into the system will be given the
ambient label.

Smack requires configuration in the case where packets from a system that is
not Smack that speaks CIPSO may be encountered. Usually this will be a Trusted
Solaris system, but there are other, less widely deployed systems out there.
CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
and a category set with each packet. The DOI is intended to identify a group
of systems that use compatible labeling schemes, and the DOI specified on the
Smack system must match that of the remote system or packets will be
discarded. The DOI is 3 by default. The value can be read from
/sys/fs/smackfs/doi and can be changed by writing to /sys/fs/smackfs/doi.

The label and category set are mapped to a Smack label as defined in
/etc/smack/cipso.

A Smack/CIPSO mapping has the form::

	smack level [category [category]*]

Smack does not expect the level or category sets to be related in any
particular way and does not assume or assign accesses based on them. Some
examples of mappings::

	TopSecret 7
	TS:A,B    7 1 2
	SecBDE    5 2 4 6
	RAFTERS   7 12 26

The ":" and "," characters are permitted in a Smack label but have no special
meaning.

The mapping of Smack labels to CIPSO values is defined by writing to
/sys/fs/smackfs/cipso2.

In addition to explicit mappings Smack supports direct CIPSO mappings. One
CIPSO level is used to indicate that the category set passed in the packet is
in fact an encoding of the Smack label. The level used is 250 by default. The
value can be read from /sys/fs/smackfs/direct and changed by writing to
/sys/fs/smackfs/direct.

Socket Attributes
~~~~~~~~~~~~~~~~~

There are two attributes that are associated with sockets. These attributes
can only be set by privileged tasks, but any task can read them for their own
sockets.

  SMACK64IPIN:
	The Smack label of the task object. A privileged
	program that will enforce policy may set this to the star label.

  SMACK64IPOUT:
	The Smack label transmitted with outgoing packets.
	A privileged program may set this to match the label of another
	task with which it hopes to communicate.

Smack Netlabel Exceptions
~~~~~~~~~~~~~~~~~~~~~~~~~

You will often find that your labeled application has to talk to the outside,
unlabeled world. To do this there's a special file /sys/fs/smackfs/netlabel
where you can add some exceptions in the form of::

	@IP1	   LABEL1 or
	@IP2/MASK  LABEL2

It means that your application will have unlabeled access to @IP1 if it has
write access on LABEL1, and access to the subnet @IP2/MASK if it has write
access on LABEL2.

Entries in the /sys/fs/smackfs/netlabel file are matched by longest mask
first, like in classless IPv4 routing.

A special label '@' and an option '-CIPSO' can be used there::

	@      means Internet, any application with any label has access to it
	-CIPSO means standard CIPSO networking

If you don't know what CIPSO is and don't plan to use it, you can just do::

	echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
	echo 0.0.0.0/0 @      > /sys/fs/smackfs/netlabel

If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
Internet access, you can have::

	echo 127.0.0.1      -CIPSO > /sys/fs/smackfs/netlabel
	echo 192.168.0.0/16 -CIPSO > /sys/fs/smackfs/netlabel
	echo 0.0.0.0/0      @      > /sys/fs/smackfs/netlabel

Writing Applications for Smack
------------------------------

There are three sorts of applications that will run on a Smack system. How an
application interacts with Smack will determine what it will have to do to
work properly under Smack.

Smack Ignorant Applications
---------------------------

By far the majority of applications have no reason whatever to care about the
unique properties of Smack. Since invoking a program has no impact on the
Smack label associated with the process the only concern likely to arise is
whether the process has execute access to the program.

Smack Relevant Applications
---------------------------

Some programs can be improved by teaching them about Smack, but do not make
any security decisions themselves. The utility ls(1) is one example of such a
program.

Smack Enforcing Applications
----------------------------

These are special programs that not only know about Smack, but participate in
the enforcement of system policy. In most cases these are the programs that
set up user sessions. There are also network services that provide information
to processes running with various labels.

File System Interfaces
----------------------

Smack maintains labels on file system objects using extended attributes. The
Smack label of a file, directory, or other file system object can be obtained
using getxattr(2)::

	len = getxattr("/", "security.SMACK64", value, sizeof (value));

will put the Smack label of the root directory into value. A privileged
process can set the Smack label of a file system object with setxattr(2)::

	len = strlen("Rubble");
	rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0);

will set the Smack label of /foo to "Rubble" if the program has appropriate
privilege.

Socket Interfaces
-----------------

The socket attributes can be read using fgetxattr(2).

A privileged process can set the Smack label of outgoing packets with
fsetxattr(2)::

	len = strlen("Rubble");
	rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0);

will set the Smack label "Rubble" on packets going out from the socket if the
program has appropriate privilege::

	rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0);

will set the Smack label "*" as the object label against which incoming
packets will be checked if the program has appropriate privilege.

Administration
--------------

Smack supports some mount options:

  smackfsdef=label:
	specifies the label to give files that lack
	the Smack label extended attribute.

  smackfsroot=label:
	specifies the label to assign the root of the
	file system if it lacks the Smack extended attribute.

  smackfshat=label:
	specifies a label that must have read access to
	all labels set on the filesystem. Not yet enforced.

  smackfsfloor=label:
	specifies a label to which all labels set on the
	filesystem must have read access. Not yet enforced.

  smackfstransmute=label:
	behaves exactly like smackfsroot except that it also
	sets the transmute flag on the root of the mount

These mount options apply to all file system types.

Smack auditing
--------------

If you want Smack auditing of security events, you need to set CONFIG_AUDIT
in your kernel configuration.
By default, all denied events will be audited. You can change this behavior by
writing a single character to the /sys/fs/smackfs/logging file::

	0 : no logging
	1 : log denied (default)
	2 : log accepted
	3 : log denied & accepted

Events are logged as 'key=value' pairs, for each event you at least will get
the subject, the object, the rights requested, the action, the kernel function
that triggered the event, plus other pairs depending on the type of event
audited.

Bringup Mode
------------

Bringup mode provides logging features that can make application
configuration and system bringup easier. Configure the kernel with
CONFIG_SECURITY_SMACK_BRINGUP to enable these features. When bringup
mode is enabled accesses that succeed due to rules marked with the "b"
access mode will logged. When a new label is introduced for processes
rules can be added aggressively, marked with the "b". The logging allows
tracking of which rules actual get used for that label.

Another feature of bringup mode is the "unconfined" option. Writing
a label to /sys/fs/smackfs/unconfined makes subjects with that label
able to access any object, and objects with that label accessible to
all subjects. Any access that is granted because a label is unconfined
is logged. This feature is dangerous, as files and directories may
be created in places they couldn't if the policy were being enforced.


code:
====
Yama
====

Yama is a Linux Security Module that collects system-wide DAC security
protections that are not handled by the core kernel itself. This is
selectable at build-time with ``CONFIG_SECURITY_YAMA``, and can be controlled
at run-time through sysctls in ``/proc/sys/kernel/yama``:

ptrace_scope
============

As Linux grows in popularity, it will become a larger target for
malware. One particularly troubling weakness of the Linux process
interfaces is that a single user is able to examine the memory and
running state of any of their processes. For example, if one application
(e.g. Pidgin) was compromised, it would be possible for an attacker to
attach to other running processes (e.g. Firefox, SSH sessions, GPG agent,
etc) to extract additional credentials and continue to expand the scope
of their attack without resorting to user-assisted phishing.

This is not a theoretical problem. `SSH session hijacking
<https://www.blackhat.com/presentations/bh-usa-05/bh-us-05-boileau.pdf>`_
and `arbitrary code injection
<https://c-skills.blogspot.com/2007/05/injectso.html>`_ attacks already
exist and remain possible if ptrace is allowed to operate as before.
Since ptrace is not commonly used by non-developers and non-admins, system
builders should be allowed the option to disable this debugging system.

For a solution, some applications use ``prctl(PR_SET_DUMPABLE, ...)`` to
specifically disallow such ptrace attachment (e.g. ssh-agent), but many
do not. A more general solution is to only allow ptrace directly from a
parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still
work), or with ``CAP_SYS_PTRACE`` (i.e. "gdb --pid=PID", and "strace -p PID"
still work as root).

In mode 1, software that has defined application-specific relationships
between a debugging process and its inferior (crash handlers, etc),
``prctl(PR_SET_PTRACER, pid, ...)`` can be used. An inferior can declare which
other process (and its descendants) are allowed to call ``PTRACE_ATTACH``
against it. Only one such declared debugging process can exists for
each inferior at a time. For example, this is used by KDE, Chromium, and
Firefox's crash handlers, and by Wine for allowing only Wine processes
to ptrace each other. If a process wishes to entirely disable these ptrace
restrictions, it can call ``prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)``
so that any otherwise allowed process (even those in external pid namespaces)
may attach.

The sysctl settings (writable only with ``CAP_SYS_PTRACE``) are:

0 - classic ptrace permissions:
    a process can ``PTRACE_ATTACH`` to any other
    process running under the same uid, as long as it is dumpable (i.e.
    did not transition uids, start privileged, or have called
    ``prctl(PR_SET_DUMPABLE...)`` already). Similarly, ``PTRACE_TRACEME`` is
    unchanged.

1 - restricted ptrace:
    a process must have a predefined relationship
    with the inferior it wants to call ``PTRACE_ATTACH`` on. By default,
    this relationship is that of only its descendants when the above
    classic criteria is also met. To change the relationship, an
    inferior can call ``prctl(PR_SET_PTRACER, debugger, ...)`` to declare
    an allowed debugger PID to call ``PTRACE_ATTACH`` on the inferior.
    Using ``PTRACE_TRACEME`` is unchanged.

2 - admin-only attach:
    only processes with ``CAP_SYS_PTRACE`` may use ptrace, either with
    ``PTRACE_ATTACH`` or through children calling ``PTRACE_TRACEME``.

3 - no attach:
    no processes may use ptrace with ``PTRACE_ATTACH`` nor via
    ``PTRACE_TRACEME``. Once set, this sysctl value cannot be changed.

The original children-only logic was based on the restrictions in grsecurity.


code:
========
AppArmor
========

What is AppArmor?
=================

AppArmor is MAC style security extension for the Linux kernel.  It implements
a task centered policy, with task "profiles" being created and loaded
from user space.  Tasks on the system that do not have a profile defined for
them run in an unconfined state which is equivalent to standard Linux DAC
permissions.

How to enable/disable
=====================

set ``CONFIG_SECURITY_APPARMOR=y``

If AppArmor should be selected as the default security module then set::

   CONFIG_DEFAULT_SECURITY="apparmor"
   CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1

Build the kernel

If AppArmor is not the default security module it can be enabled by passing
``security=apparmor`` on the kernel's command line.

If AppArmor is the default security module it can be disabled by passing
``apparmor=0, security=XXXX`` (where ``XXXX`` is valid security module), on the
kernel's command line.

For AppArmor to enforce any restrictions beyond standard Linux DAC permissions
policy must be loaded into the kernel from user space (see the Documentation
and tools links).

Documentation
=============

Documentation can be found on the wiki, linked below.

Links
=====

Mailing List - apparmor@lists.ubuntu.com

Wiki - http://wiki.apparmor.net

User space tools - https://gitlab.com/apparmor

Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor


code:
===========================
Linux Security Module Usage
===========================

The Linux Security Module (LSM) framework provides a mechanism for
various security checks to be hooked by new kernel extensions. The name
"module" is a bit of a misnomer since these extensions are not actually
loadable kernel modules. Instead, they are selectable at build-time via
CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the
``"security=..."`` kernel command line argument, in the case where multiple
LSMs were built into a given kernel.

The primary users of the LSM interface are Mandatory Access Control
(MAC) extensions which provide a comprehensive security policy. Examples
include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger
MAC extensions, other extensions can be built using the LSM to provide
specific changes to system operation when these tweaks are not available
in the core functionality of Linux itself.

The Linux capabilities modules will always be included. This may be
followed by any number of "minor" modules and at most one "major" module.
For more details on capabilities, see ``capabilities(7)`` in the Linux
man-pages project.

A list of the active security modules can be found by reading
``/sys/kernel/security/lsm``. This is a comma separated list, and
will always include the capability module. The list reflects the
order in which checks are made. The capability module will always
be first, followed by any "minor" modules (e.g. Yama) and then
the one "major" module (e.g. SELinux) if there is one configured.

Process attributes associated with "major" security modules should
be accessed and maintained using the special files in ``/proc/.../attr``.
A security module may maintain a module specific subdirectory there,
named after the module. ``/proc/.../attr/smack`` is provided by the Smack
security module and contains all its special files. The files directly
in ``/proc/.../attr`` remain as legacy interfaces for modules that provide
subdirectories.

.. toctree::
   :maxdepth: 1

   apparmor
   LoadPin
   SELinux
   Smack
   tomoyo
   Yama
   SafeSetID


code:
======
TOMOYO
======

What is TOMOYO?
===============

TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.

LiveCD-based tutorials are available at

http://tomoyo.sourceforge.jp/1.8/ubuntu12.04-live.html
http://tomoyo.sourceforge.jp/1.8/centos6-live.html

Though these tutorials use non-LSM version of TOMOYO, they are useful for you
to know what TOMOYO is.

How to enable TOMOYO?
=====================

Build the kernel with ``CONFIG_SECURITY_TOMOYO=y`` and pass ``security=tomoyo`` on
kernel's command line.

Please see http://tomoyo.osdn.jp/2.5/ for details.

Where is documentation?
=======================

User <-> Kernel interface documentation is available at
https://tomoyo.osdn.jp/2.5/policy-specification/index.html .

Materials we prepared for seminars and symposiums are available at
https://osdn.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
Below lists are chosen from three aspects.

What is TOMOYO?
  TOMOYO Linux Overview
    https://osdn.jp/projects/tomoyo/docs/lca2009-takeda.pdf
  TOMOYO Linux: pragmatic and manageable security for Linux
    https://osdn.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
  TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
    https://osdn.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf

What can TOMOYO do?
  Deep inside TOMOYO Linux
    https://osdn.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
  The role of "pathname based access control" in security.
    https://osdn.jp/projects/tomoyo/docs/lfj2008-bof.pdf

History of TOMOYO?
  Realities of Mainlining
    https://osdn.jp/projects/tomoyo/docs/lfj2008.pdf

What is future plan?
====================

We believe that inode based security and name based security are complementary
and both should be used together. But unfortunately, so far, we cannot enable
multiple LSM modules at the same time. We feel sorry that you have to give up
SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.

We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
version of TOMOYO, available at http://tomoyo.osdn.jp/1.8/ .
LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
to port non-LSM version's functionalities to LSM versions.


code:
.. _readme:

Linux kernel release 6.x <http://kernel.org/>
=============================================

These are the release notes for Linux version 6.  Read them carefully,
as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong.

What is Linux?
--------------

  Linux is a clone of the operating system Unix, written from scratch by
  Linus Torvalds with assistance from a loosely-knit team of hackers across
  the Net. It aims towards POSIX and Single UNIX Specification compliance.

  It has all the features you would expect in a modern fully-fledged Unix,
  including true multitasking, virtual memory, shared libraries, demand
  loading, shared copy-on-write executables, proper memory management,
  and multistack networking including IPv4 and IPv6.

  It is distributed under the GNU General Public License v2 - see the
  accompanying COPYING file for more details.

On what hardware does it run?
-----------------------------

  Although originally developed first for 32-bit x86-based PCs (386 or higher),
  today Linux also runs on (at least) the Compaq Alpha AXP, Sun SPARC and
  UltraSPARC, Motorola 68000, PowerPC, PowerPC64, ARM, Hitachi SuperH, Cell,
  IBM S/390, MIPS, HP PA-RISC, Intel IA-64, DEC VAX, AMD x86-64 Xtensa, and
  ARC architectures.

  Linux is easily portable to most general-purpose 32- or 64-bit architectures
  as long as they have a paged memory management unit (PMMU) and a port of the
  GNU C compiler (gcc) (part of The GNU Compiler Collection, GCC). Linux has
  also been ported to a number of architectures without a PMMU, although
  functionality is then obviously somewhat limited.
  Linux has also been ported to itself. You can now run the kernel as a
  userspace application - this is called UserMode Linux (UML).

Documentation
-------------

 - There is a lot of documentation available both in electronic form on
   the Internet and in books, both Linux-specific and pertaining to
   general UNIX questions.  I'd recommend looking into the documentation
   subdirectories on any Linux FTP site for the LDP (Linux Documentation
   Project) books.  This README is not meant to be documentation on the
   system: there are much better sources available.

 - There are various README files in the Documentation/ subdirectory:
   these typically contain kernel-specific installation notes for some
   drivers for example. Please read the
   :ref:`Documentation/process/changes.rst <changes>` file, as it
   contains information about the problems, which may result by upgrading
   your kernel.

Installing the kernel source
----------------------------

 - If you install the full sources, put the kernel tarball in a
   directory where you have permissions (e.g. your home directory) and
   unpack it::

     xz -cd linux-6.x.tar.xz | tar xvf -

   Replace "X" with the version number of the latest kernel.

   Do NOT use the /usr/src/linux area! This area has a (usually
   incomplete) set of kernel headers that are used by the library header
   files.  They should match the library, and not get messed up by
   whatever the kernel-du-jour happens to be.

 - You can also upgrade between 6.x releases by patching.  Patches are
   distributed in the xz format.  To install by patching, get all the
   newer patch files, enter the top level directory of the kernel source
   (linux-6.x) and execute::

     xz -cd ../patch-6.x.xz | patch -p1

   Replace "x" for all versions bigger than the version "x" of your current
   source tree, **in_order**, and you should be ok.  You may want to remove
   the backup files (some-file-name~ or some-file-name.orig), and make sure
   that there are no failed patches (some-file-name# or some-file-name.rej).
   If there are, either you or I have made a mistake.

   Unlike patches for the 6.x kernels, patches for the 6.x.y kernels
   (also known as the -stable kernels) are not incremental but instead apply
   directly to the base 6.x kernel.  For example, if your base kernel is 6.0
   and you want to apply the 6.0.3 patch, you must not first apply the 6.0.1
   and 6.0.2 patches. Similarly, if you are running kernel version 6.0.2 and
   want to jump to 6.0.3, you must first reverse the 6.0.2 patch (that is,
   patch -R) **before** applying the 6.0.3 patch. You can read more on this in
   :ref:`Documentation/process/applying-patches.rst <applying_patches>`.

   Alternatively, the script patch-kernel can be used to automate this
   process.  It determines the current kernel version and applies any
   patches found::

     linux/scripts/patch-kernel linux

   The first argument in the command above is the location of the
   kernel source.  Patches are applied from the current directory, but
   an alternative directory can be specified as the second argument.

 - Make sure you have no stale .o files and dependencies lying around::

     cd linux
     make mrproper

   You should now have the sources correctly installed.

Software requirements
---------------------

   Compiling and running the 6.x kernels requires up-to-date
   versions of various software packages.  Consult
   :ref:`Documentation/process/changes.rst <changes>` for the minimum version numbers
   required and how to get updates for these packages.  Beware that using
   excessively old versions of these packages can cause indirect
   errors that are very difficult to track down, so don't assume that
   you can just update packages when obvious problems arise during
   build or operation.

Build directory for the kernel
------------------------------

   When compiling the kernel, all output files will per default be
   stored together with the kernel source code.
   Using the option ``make O=output/dir`` allows you to specify an alternate
   place for the output files (including .config).
   Example::

     kernel source code: /usr/src/linux-6.x
     build directory:    /home/name/build/kernel

   To configure and build the kernel, use::

     cd /usr/src/linux-6.x
     make O=/home/name/build/kernel menuconfig
     make O=/home/name/build/kernel
     sudo make O=/home/name/build/kernel modules_install install

   Please note: If the ``O=output/dir`` option is used, then it must be
   used for all invocations of make.

Configuring the kernel
----------------------

   Do not skip this step even if you are only upgrading one minor
   version.  New configuration options are added in each release, and
   odd problems will turn up if the configuration files are not set up
   as expected.  If you want to carry your existing configuration to a
   new version with minimal work, use ``make oldconfig``, which will
   only ask you for the answers to new questions.

 - Alternative configuration commands are::

     "make config"      Plain text interface.

     "make menuconfig"  Text based color menus, radiolists & dialogs.

     "make nconfig"     Enhanced text based color menus.

     "make xconfig"     Qt based configuration tool.

     "make gconfig"     GTK+ based configuration tool.

     "make oldconfig"   Default all questions based on the contents of
                        your existing ./.config file and asking about
                        new config symbols.

     "make olddefconfig"
                        Like above, but sets new symbols to their default
                        values without prompting.

     "make defconfig"   Create a ./.config file by using the default
                        symbol values from either arch/$ARCH/defconfig
                        or arch/$ARCH/configs/${PLATFORM}_defconfig,
                        depending on the architecture.

     "make ${PLATFORM}_defconfig"
                        Create a ./.config file by using the default
                        symbol values from
                        arch/$ARCH/configs/${PLATFORM}_defconfig.
                        Use "make help" to get a list of all available
                        platforms of your architecture.

     "make allyesconfig"
                        Create a ./.config file by setting symbol
                        values to 'y' as much as possible.

     "make allmodconfig"
                        Create a ./.config file by setting symbol
                        values to 'm' as much as possible.

     "make allnoconfig" Create a ./.config file by setting symbol
                        values to 'n' as much as possible.

     "make randconfig"  Create a ./.config file by setting symbol
                        values to random values.

     "make localmodconfig" Create a config based on current config and
                           loaded modules (lsmod). Disables any module
                           option that is not needed for the loaded modules.

                           To create a localmodconfig for another machine,
                           store the lsmod of that machine into a file
                           and pass it in as a LSMOD parameter.

                           Also, you can preserve modules in certain folders
                           or kconfig files by specifying their paths in
                           parameter LMC_KEEP.

                   target$ lsmod > /tmp/mylsmod
                   target$ scp /tmp/mylsmod host:/tmp

                   host$ make LSMOD=/tmp/mylsmod \
                           LMC_KEEP="drivers/usb:drivers/gpu:fs" \
                           localmodconfig

                           The above also works when cross compiling.

     "make localyesconfig" Similar to localmodconfig, except it will convert
                           all module options to built in (=y) options. You can
                           also preserve modules by LMC_KEEP.

     "make kvm_guest.config"   Enable additional options for kvm guest kernel
                               support.

     "make xen.config"   Enable additional options for xen dom0 guest kernel
                         support.

     "make tinyconfig"  Configure the tiniest possible kernel.

   You can find more information on using the Linux kernel config tools
   in Documentation/kbuild/kconfig.rst.

 - NOTES on ``make config``:

    - Having unnecessary drivers will make the kernel bigger, and can
      under some circumstances lead to problems: probing for a
      nonexistent controller card may confuse your other controllers.

    - A kernel with math-emulation compiled in will still use the
      coprocessor if one is present: the math emulation will just
      never get used in that case.  The kernel will be slightly larger,
      but will work on different machines regardless of whether they
      have a math coprocessor or not.

    - The "kernel hacking" configuration details usually result in a
      bigger or slower kernel (or both), and can even make the kernel
      less stable by configuring some routines to actively try to
      break bad code to find kernel problems (kmalloc()).  Thus you
      should probably answer 'n' to the questions for "development",
      "experimental", or "debugging" features.

Compiling the kernel
--------------------

 - Make sure you have at least gcc 5.1 available.
   For more information, refer to :ref:`Documentation/process/changes.rst <changes>`.

 - Do a ``make`` to create a compressed kernel image. It is also
   possible to do ``make install`` if you have lilo installed to suit the
   kernel makefiles, but you may want to check your particular lilo setup first.

   To do the actual install, you have to be root, but none of the normal
   build should require that. Don't take the name of root in vain.

 - If you configured any of the parts of the kernel as ``modules``, you
   will also have to do ``make modules_install``.

 - Verbose kernel compile/build output:

   Normally, the kernel build system runs in a fairly quiet mode (but not
   totally silent).  However, sometimes you or other kernel developers need
   to see compile, link, or other commands exactly as they are executed.
   For this, use "verbose" build mode.  This is done by passing
   ``V=1`` to the ``make`` command, e.g.::

     make V=1 all

   To have the build system also tell the reason for the rebuild of each
   target, use ``V=2``.  The default is ``V=0``.

 - Keep a backup kernel handy in case something goes wrong.  This is
   especially true for the development releases, since each new release
   contains new code which has not been debugged.  Make sure you keep a
   backup of the modules corresponding to that kernel, as well.  If you
   are installing a new kernel with the same version number as your
   working kernel, make a backup of your modules directory before you
   do a ``make modules_install``.

   Alternatively, before compiling, use the kernel config option
   "LOCALVERSION" to append a unique suffix to the regular kernel version.
   LOCALVERSION can be set in the "General Setup" menu.

 - In order to boot your new kernel, you'll need to copy the kernel
   image (e.g. .../linux/arch/x86/boot/bzImage after compilation)
   to the place where your regular bootable kernel is found.

 - Booting a kernel directly from a floppy without the assistance of a
   bootloader such as LILO, is no longer supported.

   If you boot Linux from the hard drive, chances are you use LILO, which
   uses the kernel image as specified in the file /etc/lilo.conf.  The
   kernel image file is usually /vmlinuz, /boot/vmlinuz, /bzImage or
   /boot/bzImage.  To use the new kernel, save a copy of the old image
   and copy the new image over the old one.  Then, you MUST RERUN LILO
   to update the loading map! If you don't, you won't be able to boot
   the new kernel image.

   Reinstalling LILO is usually a matter of running /sbin/lilo.
   You may wish to edit /etc/lilo.conf to specify an entry for your
   old kernel image (say, /vmlinux.old) in case the new one does not
   work.  See the LILO docs for more information.

   After reinstalling LILO, you should be all set.  Shutdown the system,
   reboot, and enjoy!

   If you ever need to change the default root device, video mode,
   etc. in the kernel image, use your bootloader's boot options
   where appropriate.  No need to recompile the kernel to change
   these parameters.

 - Reboot with the new kernel and enjoy.

If something goes wrong
-----------------------

If you have problems that seem to be due to kernel bugs, please follow the
instructions at 'Documentation/admin-guide/reporting-issues.rst'.

Hints on understanding kernel bug reports are in
'Documentation/admin-guide/bug-hunting.rst'. More on debugging the kernel
with gdb is in 'Documentation/dev-tools/gdb-kernel-debugging.rst' and
'Documentation/dev-tools/kgdb.rst'.


code:
ABI obsolete symbols
====================

Documents interfaces that are still remaining in the kernel, but are
marked to be removed at some later point in time.

The description of the interface will document the reason why it is
obsolete and when it can be expected to be removed.

.. kernel-abi:: $srctree/Documentation/ABI/obsolete
   :rst:


code:
ABI removed symbols
===================

.. kernel-abi:: $srctree/Documentation/ABI/removed
   :rst:


code:
ABI stable symbols
==================

Documents the interfaces that the developer has defined to be stable.

Userspace programs are free to use these interfaces with no
restrictions, and backward compatibility for them will be guaranteed
for at least 2 years.

Most interfaces (like syscalls) are expected to never change and always
be available.

.. kernel-abi:: $srctree/Documentation/ABI/stable
   :rst:


code:
ABI testing symbols
===================

Documents interfaces that are felt to be stable,
as the main development of this interface has been completed.

The interface can be changed to add new features, but the
current interface will not break by doing this, unless grave
errors or security problems are found in them.

Userspace programs can start to rely on these interfaces, but they must
be aware of changes that can occur before these interfaces move to
be marked stable.

Programs that use these interfaces are strongly encouraged to add their
name to the description of these interfaces, so that the kernel
developers can easily notify them if any changes occur.

.. kernel-abi:: $srctree/Documentation/ABI/testing
   :rst:


code:
=====================
Linux ABI description
=====================

.. toctree::
   :maxdepth: 2

   abi-stable
   abi-testing
   abi-obsolete
   abi-removed


code:
.. SPDX-License-Identifier: GPL-2.0

==================================================
Collaborative Processor Performance Control (CPPC)
==================================================

.. _cppc_sysfs:

CPPC
====

CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
performance of a logical processor on a contiguous and abstract performance
scale. CPPC exposes a set of registers to describe abstract performance scale,
to request performance levels and to measure per-cpu delivered performance.

For more details on CPPC please refer to the ACPI specification at:

http://uefi.org/specifications

Some of the CPPC registers are exposed via sysfs under::

  /sys/devices/system/cpu/cpuX/acpi_cppc/

for each cpu X::

  $ ls -lR  /sys/devices/system/cpu/cpu0/acpi_cppc/
  /sys/devices/system/cpu/cpu0/acpi_cppc/:
  total 0
  -r--r--r-- 1 root root 65536 Mar  5 19:38 feedback_ctrs
  -r--r--r-- 1 root root 65536 Mar  5 19:38 highest_perf
  -r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_freq
  -r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_nonlinear_perf
  -r--r--r-- 1 root root 65536 Mar  5 19:38 lowest_perf
  -r--r--r-- 1 root root 65536 Mar  5 19:38 nominal_freq
  -r--r--r-- 1 root root 65536 Mar  5 19:38 nominal_perf
  -r--r--r-- 1 root root 65536 Mar  5 19:38 reference_perf
  -r--r--r-- 1 root root 65536 Mar  5 19:38 wraparound_time

* highest_perf : Highest performance of this processor (abstract scale).
* nominal_perf : Highest sustained performance of this processor
  (abstract scale).
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
  power savings (abstract scale).
* lowest_perf : Lowest performance of this processor (abstract scale).

* lowest_freq : CPU frequency corresponding to lowest_perf (in MHz).
* nominal_freq : CPU frequency corresponding to nominal_perf (in MHz).
  The above frequencies should only be used to report processor performance in
  frequency instead of abstract scale. These values should not be used for any
  functional decisions.

* feedback_ctrs : Includes both Reference and delivered performance counter.
  Reference counter ticks up proportional to processor's reference performance.
  Delivered counter ticks up proportional to processor's delivered performance.
* wraparound_time: Minimum time for the feedback counters to wraparound
  (seconds).
* reference_perf : Performance level at which reference performance counter
  accumulates (abstract scale).

Computing Average Delivered Performance
=======================================

Below describes the steps to compute the average performance delivered by
taking two different snapshots of feedback counters at time T1 and T2.

  T1: Read feedback_ctrs as fbc_t1
      Wait or run some workload

  T2: Read feedback_ctrs as fbc_t2

::

  delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
  reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]

  delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta


code:
.. SPDX-License-Identifier: GPL-2.0

===========================
ACPI Fan Performance States
===========================

When the optional _FPS object is present under an ACPI device representing a
fan (for example, PNP0C0B or INT3404), the ACPI fan driver creates additional
"state*" attributes in the sysfs directory of the ACPI device in question.
These attributes list properties of fan performance states.

For more information on _FPS refer to the ACPI specification at:

http://uefi.org/specifications

For instance, the contents of the INT3404 ACPI device sysfs directory
may look as follows::

 $ ls -l /sys/bus/acpi/devices/INT3404:00/
 total 0
 ...
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state0
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state1
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state10
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state11
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state2
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state3
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state4
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state5
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state6
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state7
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state8
 -r--r--r-- 1 root root 4096 Dec 13 20:38 state9
 -r--r--r-- 1 root root 4096 Dec 13 01:00 status
 ...

where each of the "state*" files represents one performance state of the fan
and contains a colon-separated list of 5 integer numbers (fields) with the
following interpretation::

  control_percent:trip_point_index:speed_rpm:noise_level_mdb:power_mw

* ``control_percent``: The percent value to be used to set the fan speed to a
  specific level using the _FSL object (0-100).

* ``trip_point_index``: The active cooling trip point number that corresponds
  to this performance state (0-9).

* ``speed_rpm``: Speed of the fan in rotations per minute.

* ``noise_level_mdb``: Audible noise emitted by the fan in this state in
  millidecibels.

* ``power_mw``: Power draw of the fan in this state in milliwatts.

For example::

 $cat /sys/bus/acpi/devices/INT3404:00/state1
 25:0:3200:12500:1250

When a given field is not populated or its value provided by the platform
firmware is invalid, the "not-defined" string is shown instead of the value.

ACPI Fan Fine Grain Control
=============================

When _FIF object specifies support for fine grain control, then fan speed
can be set from 0 to 100% with the recommended minimum "step size" via
_FSL object. User can adjust fan speed using thermal sysfs cooling device.

Here use can look at fan performance states for a reference speed (speed_rpm)
and set it by changing cooling device cur_state. If the fine grain control
is supported then user can also adjust to some other speeds which are
not defined in the performance states.

The support of fine grain control is presented via sysfs attribute
"fine_grain_control". If fine grain control is present, this attribute
will show "1" otherwise "0".

This sysfs attribute is presented in the same directory as performance states.

ACPI Fan Performance Feedback
=============================

The optional _FST object provides status information for the fan device.
This includes field to provide current fan speed in revolutions per minute
at which the fan is rotating.

This speed is presented in the sysfs using the attribute "fan_speed_rpm",
in the same directory as performance states.


code:
============
ACPI Support
============

Here we document in detail how to interact with various mechanisms in
the Linux ACPI support.

.. toctree::
   :maxdepth: 1

   initrd_table_override
   ssdt-overlays
   cppc_sysfs
   fan_performance_states