123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- .. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
- ===========================
- BPF_PROG_TYPE_CGROUP_SYSCTL
- ===========================
- This document describes ``BPF_PROG_TYPE_CGROUP_SYSCTL`` program type that
- provides cgroup-bpf hook for sysctl.
- The hook has to be attached to a cgroup and will be called every time a
- process inside that cgroup tries to read from or write to sysctl knob in proc.
- 1. Attach type
- **************
- ``BPF_CGROUP_SYSCTL`` attach type has to be used to attach
- ``BPF_PROG_TYPE_CGROUP_SYSCTL`` program to a cgroup.
- 2. Context
- **********
- ``BPF_PROG_TYPE_CGROUP_SYSCTL`` provides access to the following context from
- BPF program::
- struct bpf_sysctl {
- __u32 write;
- __u32 file_pos;
- };
- * ``write`` indicates whether sysctl value is being read (``0``) or written
- (``1``). This field is read-only.
- * ``file_pos`` indicates file position sysctl is being accessed at, read
- or written. This field is read-write. Writing to the field sets the starting
- position in sysctl proc file ``read(2)`` will be reading from or ``write(2)``
- will be writing to. Writing zero to the field can be used e.g. to override
- whole sysctl value by ``bpf_sysctl_set_new_value()`` on ``write(2)`` even
- when it's called by user space on ``file_pos > 0``. Writing non-zero
- value to the field can be used to access part of sysctl value starting from
- specified ``file_pos``. Not all sysctl support access with ``file_pos !=
- 0``, e.g. writes to numeric sysctl entries must always be at file position
- ``0``. See also ``kernel.sysctl_writes_strict`` sysctl.
- See `linux/bpf.h`_ for more details on how context field can be accessed.
- 3. Return code
- **************
- ``BPF_PROG_TYPE_CGROUP_SYSCTL`` program must return one of the following
- return codes:
- * ``0`` means "reject access to sysctl";
- * ``1`` means "proceed with access".
- If program returns ``0`` user space will get ``-1`` from ``read(2)`` or
- ``write(2)`` and ``errno`` will be set to ``EPERM``.
- 4. Helpers
- **********
- Since sysctl knob is represented by a name and a value, sysctl specific BPF
- helpers focus on providing access to these properties:
- * ``bpf_sysctl_get_name()`` to get sysctl name as it is visible in
- ``/proc/sys`` into provided by BPF program buffer;
- * ``bpf_sysctl_get_current_value()`` to get string value currently held by
- sysctl into provided by BPF program buffer. This helper is available on both
- ``read(2)`` from and ``write(2)`` to sysctl;
- * ``bpf_sysctl_get_new_value()`` to get new string value currently being
- written to sysctl before actual write happens. This helper can be used only
- on ``ctx->write == 1``;
- * ``bpf_sysctl_set_new_value()`` to override new string value currently being
- written to sysctl before actual write happens. Sysctl value will be
- overridden starting from the current ``ctx->file_pos``. If the whole value
- has to be overridden BPF program can set ``file_pos`` to zero before calling
- to the helper. This helper can be used only on ``ctx->write == 1``. New
- string value set by the helper is treated and verified by kernel same way as
- an equivalent string passed by user space.
- BPF program sees sysctl value same way as user space does in proc filesystem,
- i.e. as a string. Since many sysctl values represent an integer or a vector
- of integers, the following helpers can be used to get numeric value from the
- string:
- * ``bpf_strtol()`` to convert initial part of the string to long integer
- similar to user space `strtol(3)`_;
- * ``bpf_strtoul()`` to convert initial part of the string to unsigned long
- integer similar to user space `strtoul(3)`_;
- See `linux/bpf.h`_ for more details on helpers described here.
- 5. Examples
- ***********
- See `test_sysctl_prog.c`_ for an example of BPF program in C that access
- sysctl name and value, parses string value to get vector of integers and uses
- the result to make decision whether to allow or deny access to sysctl.
- 6. Notes
- ********
- ``BPF_PROG_TYPE_CGROUP_SYSCTL`` is intended to be used in **trusted** root
- environment, for example to monitor sysctl usage or catch unreasonable values
- an application, running as root in a separate cgroup, is trying to set.
- Since `task_dfl_cgroup(current)` is called at `sys_read` / `sys_write` time it
- may return results different from that at `sys_open` time, i.e. process that
- opened sysctl file in proc filesystem may differ from process that is trying
- to read from / write to it and two such processes may run in different
- cgroups, what means ``BPF_PROG_TYPE_CGROUP_SYSCTL`` should not be used as a
- security mechanism to limit sysctl usage.
- As with any cgroup-bpf program additional care should be taken if an
- application running as root in a cgroup should not be allowed to
- detach/replace BPF program attached by administrator.
- .. Links
- .. _linux/bpf.h: ../../include/uapi/linux/bpf.h
- .. _strtol(3): http://man7.org/linux/man-pages/man3/strtol.3p.html
- .. _strtoul(3): http://man7.org/linux/man-pages/man3/strtoul.3p.html
- .. _test_sysctl_prog.c:
- ../../tools/testing/selftests/bpf/progs/test_sysctl_prog.c
|