diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-23 13:28:57 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-23 13:28:57 -0700 |
| commit | 4352b8aee98005853aa63f57d6377282de17a33f (patch) | |
| tree | 27614d7a9ef05c32d089004e104364ce42324837 /security/landlock/ruleset.h | |
| download | linux-stable-4352b8aee98005853aa63f57d6377282de17a33f.tar.gz linux-stable-4352b8aee98005853aa63f57d6377282de17a33f.zip | |
Merge tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linuxgrafted
Pull I3C updates from Alexandre Belloni:
"A new driver this cycle, for the AMD AXI I3C controller.
There are also new features such as IBI wakeup support, SETAASA device
discovery and ACPI support for the the DAA methods, meaning we can now
communicate with the SPD devices on DDR5 modules.
New driver:
- AMD AXI I3C master controller
Subsystem:
- I3C Common Command Code (CCC) handling improvements, especially
around GET CCCs
- SETAASA device discovery support
- ACPI support for all existing DAA methods like SETDASA, SETNEWDA as
well as I2C devices on I3C bus
- IBI-based wakeup support
Drivers:
- dw: SETAASA support
- mipi-i3c-hci: advertise IBI wakeup capability, AMD_PT I3C
controller support, PIO queue management support for HCI v1.2
- renesas: improve suspend to RAM support, add runtime PM support"
* tag 'i3c/for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux: (70 commits)
i3c: dw: reduce do_daa time if there's no client
i3c: mipi-i3c-hci: Add support for AMD_PT I3C controller
i3c: mipi-i3c-hci: Add PIO queue management support for HCI v1.2
i3c: mipi-i3c-hci: Fix missing STAT_IBI_STATUS_THLD in PIO mode
i3c: dw: rename "pclk" to "apb" to match dt-binding
i3c: dw: make struct dw_i3c_cmd smaller
i3c: dw: use COMMAND_PORT_TRANSFER_ARG instead of hardcoding
i3c: renesas: Don't register devices when ENTDAA times out
i3c: master: dw-i3c-master: fix OD timing for first broadcast
i3c: mipi-i3c-hci: Advertise IBI wakeup capability
i3c: mipi-i3c-hci: Factor out i3c_hci_sysdev()
i3c: mipi-i3c-hci-pci: Propagate I3C wakeup requirements to PCI
i3c: master: Reject IBI requests from non-IBI-capable devices
i3c: master: Add helper to query bus wakeup requirements
i3c: master: Report wakeup events for IBIs
i3c: master: Support IBI-based wakeup capability
i3c: master: Fix potential UAF in i3c_device_match()
i3c: master: Fix potential UAF in i3c_device_uevent()
i3c: Make dev->desc locking assumptions explicit
i3c: master: Fix use-after-free of master->this
...
Diffstat (limited to 'security/landlock/ruleset.h')
| -rw-r--r-- | security/landlock/ruleset.h | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h new file mode 100644 index 000000000..b536fa042 --- /dev/null +++ b/security/landlock/ruleset.h @@ -0,0 +1,250 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock LSM - Ruleset management + * + * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net> + * Copyright © 2018-2020 ANSSI + * Copyright © 2026 Cloudflare, Inc. + */ + +#ifndef _SECURITY_LANDLOCK_RULESET_H +#define _SECURITY_LANDLOCK_RULESET_H + +#include <linux/cleanup.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/rbtree.h> +#include <linux/refcount.h> + +#include "access.h" +#include "limits.h" +#include "object.h" + +/** + * struct landlock_layer - Access rights for a given layer + */ +struct landlock_layer { + /** + * @level: Position of this layer in the layer stack. Starts from 1. + */ + u8 level; + /** + * @flags: Bitfield for special flags attached to this rule. + */ + struct { + /** + * @flags.quiet: Suppresses denial logs for the object covered by + * this rule in this domain. For filesystem rules, this inherits + * down the file hierarchy. + */ + u8 quiet : 1; + } flags; + /** + * @access: Bitfield of allowed actions on the kernel object. They are + * relative to the object type (e.g. %LANDLOCK_ACTION_FS_READ). + */ + access_mask_t access; +}; + +/** + * union landlock_key - Key of a ruleset's red-black tree + */ +union landlock_key { + /** + * @object: Pointer to identify a kernel object (e.g. an inode). + */ + struct landlock_object *object; + /** + * @data: Raw data to identify an arbitrary 32-bit value + * (e.g. a TCP port). + */ + uintptr_t data; +}; + +/** + * enum landlock_key_type - Type of &union landlock_key + */ +enum landlock_key_type { + /** + * @LANDLOCK_KEY_INODE: Type of &landlock_rules.root_inode's node keys. + */ + LANDLOCK_KEY_INODE = 1, + /** + * @LANDLOCK_KEY_NET_PORT: Type of &landlock_rules.root_net_port's node + * keys. + */ + LANDLOCK_KEY_NET_PORT, +}; + +/** + * struct landlock_id - Unique rule identifier for a ruleset + */ +struct landlock_id { + /** + * @key: Identifies either a kernel object (e.g. an inode) or + * a raw value (e.g. a TCP port). + */ + union landlock_key key; + /** + * @type: Type of a landlock_ruleset's root tree. + */ + const enum landlock_key_type type; +}; + +/** + * struct landlock_rule - Access rights tied to an object + */ +struct landlock_rule { + /** + * @node: Node in the ruleset's red-black tree. + */ + struct rb_node node; + /** + * @key: A union to identify either a kernel object (e.g. an inode) or + * a raw data value (e.g. a network socket port). This is used as a key + * for this ruleset element. The pointer is set once and never + * modified. It always points to an allocated object because each rule + * increments the refcount of its object. + */ + union landlock_key key; + /** + * @num_layers: Number of entries in @layers. + */ + u32 num_layers; + /** + * @layers: Stack of layers, from the latest to the newest, implemented + * as a flexible array member (FAM). + */ + struct landlock_layer layers[] __counted_by(num_layers); +}; + +/** + * struct landlock_rules - Red-black tree storage for Landlock rules + * + * This structure holds the rule trees shared by both rulesets and domains. + */ +struct landlock_rules { + /** + * @root_inode: Root of a red-black tree containing &struct + * landlock_rule nodes with inode object. Immutable for domains. + */ + struct rb_root root_inode; + +#if IS_ENABLED(CONFIG_INET) + /** + * @root_net_port: Root of a red-black tree containing &struct + * landlock_rule nodes with network port. Immutable for domains. + */ + struct rb_root root_net_port; +#endif /* IS_ENABLED(CONFIG_INET) */ + + /** + * @num_rules: Number of non-overlapping (i.e. not for the same object) + * rules in this tree storage. + */ + u32 num_rules; +}; + +/** + * struct landlock_ruleset - Landlock ruleset + * + * This data structure must contain unique entries, be updatable, and quick to + * match an object. + */ +struct landlock_ruleset { + /** + * @rules: Red-black tree storage for rules. + */ + struct landlock_rules rules; + /** + * @lock: Protects against concurrent modifications of @rules, if @usage + * is greater than zero. + */ + struct mutex lock; + /** + * @usage: Number of file descriptors referencing this ruleset. + */ + refcount_t usage; + +#ifdef CONFIG_TRACEPOINTS + /** + * @version: Counter incremented on each successful + * landlock_add_rule(2), including when it only extends an existing + * rule's access rights. Used by tracepoints to correlate a domain with + * the exact ruleset state it was created from. Protected by @lock. + */ + u32 version; + /** + * @id: Unique identifier for this ruleset, used for tracing. + */ + u64 id; +#endif /* CONFIG_TRACEPOINTS */ + + /** + * @quiet_masks: Stores the quiet flags for an unmerged ruleset. For a + * merged domain, this is stored in each layer's struct + * landlock_hierarchy instead. + */ + struct access_masks quiet_masks; + /** + * @handled_masks: Contains the subset of filesystem and network actions + * that are handled by this ruleset. + */ + struct access_masks handled_masks; +}; + +struct landlock_ruleset * +landlock_create_ruleset(const access_mask_t access_mask_fs, + const access_mask_t access_mask_net, + const access_mask_t scope_mask); + +void landlock_put_ruleset(struct landlock_ruleset *const ruleset); + +DEFINE_FREE(landlock_put_ruleset, struct landlock_ruleset *, + if (!IS_ERR_OR_NULL(_T)) landlock_put_ruleset(_T)) + +int landlock_insert_rule(struct landlock_ruleset *const ruleset, + const struct landlock_id id, + const access_mask_t access, const u32 flags); + +int landlock_store_rule(struct landlock_rules *const rules, + const struct landlock_id id, + const struct landlock_layer (*layers)[], + const size_t num_layers); + +void landlock_free_rules(struct landlock_rules *const rules); + +/** + * landlock_get_rule_root - Get the root of a rule tree by key type + * + * @rules: The rules storage to look up. + * @key_type: The type of key to select the tree for. + * + * Return: A pointer to the rb_root, or ERR_PTR(-EINVAL) on unknown type. + */ +static inline struct rb_root * +landlock_get_rule_root(struct landlock_rules *const rules, + const enum landlock_key_type key_type) +{ + switch (key_type) { + case LANDLOCK_KEY_INODE: + return &rules->root_inode; + +#if IS_ENABLED(CONFIG_INET) + case LANDLOCK_KEY_NET_PORT: + return &rules->root_net_port; +#endif /* IS_ENABLED(CONFIG_INET) */ + + default: + WARN_ON_ONCE(1); + return ERR_PTR(-EINVAL); + } +} + +static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset) +{ + if (ruleset) + refcount_inc(&ruleset->usage); +} + +#endif /* _SECURITY_LANDLOCK_RULESET_H */ |
