projects/linux·blob master · refs

188 lines · 5.9 KiB

1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Landlock - Filesystem management and hooks
4 *
5 * Copyright © 2017-2020 Mickaël Salaün <[email protected]>
6 * Copyright © 2018-2020 ANSSI
7 * Copyright © 2024-2025 Microsoft Corporation
8 */
9
10#ifndef _SECURITY_LANDLOCK_FS_H
11#define _SECURITY_LANDLOCK_FS_H
12
13#include <linux/build_bug.h>
14#include <linux/cleanup.h>
15#include <linux/fs.h>
16#include <linux/init.h>
17#include <linux/rcupdate.h>
18
19#include "access.h"
20#include "cred.h"
21#include "ruleset.h"
22#include "setup.h"
23
24DEFINE_FREE(__putname, char *, if (_T) __putname(_T))
25
26/**
27 * struct landlock_inode_security - Inode security blob
28 *
29 * Enable to reference a &struct landlock_object tied to an inode (i.e.
30 * underlying object).
31 */
32struct landlock_inode_security {
33 /**
34 * @object: Weak pointer to an allocated object. All assignments of a
35 * new object are protected by the underlying inode->i_lock. However,
36 * atomically disassociating @object from the inode is only protected
37 * by @object->lock, from the time @object's usage refcount drops to
38 * zero to the time this pointer is nulled out (cf. release_inode() and
39 * hook_sb_delete()). Indeed, such disassociation doesn't require
40 * inode->i_lock thanks to the careful rcu_access_pointer() check
41 * performed by get_inode_object().
42 */
43 struct landlock_object __rcu *object;
44};
45
46/**
47 * struct landlock_file_security - File security blob
48 *
49 * This information is populated when opening a file in hook_file_open, and
50 * tracks the relevant Landlock access rights that were available at the time
51 * of opening the file. Other LSM hooks use these rights in order to authorize
52 * operations on already opened files.
53 */
54struct landlock_file_security {
55 /**
56 * @allowed_access: Access rights that were available at the time of
57 * opening the file. This is not necessarily the full set of access
58 * rights available at that time, but it's the necessary subset as
59 * needed to authorize later operations on the open file.
60 */
61 access_mask_t allowed_access;
62
63#ifdef CONFIG_SECURITY_LANDLOCK_LOG
64 /**
65 * @deny_masks: Domain layer levels that deny an optional access (see
66 * _LANDLOCK_ACCESS_FS_OPTIONAL).
67 */
68 deny_masks_t deny_masks;
69 /**
70 * @quiet_optional_accesses: Stores which optional accesses are covered
71 * by quiet rules within the layer referred to in deny_masks, one access
72 * per bit. Does not take into account whether the quiet access bits
73 * are actually set in the layer's corresponding landlock_hierarchy.
74 */
75 optional_access_t quiet_optional_accesses;
76 /**
77 * @fown_layer: Layer level of @fown_subject->domain with
78 * LANDLOCK_SCOPE_SIGNAL.
79 */
80 u8 fown_layer;
81#endif /* CONFIG_SECURITY_LANDLOCK_LOG */
82
83 /**
84 * @fown_subject: Landlock credential of the task that set the PID that
85 * may receive a signal e.g., SIGURG when writing MSG_OOB to the
86 * related socket. This pointer is protected by the related
87 * file->f_owner->lock, as for fown_struct's members: pid, uid, and
88 * euid.
89 */
90 struct landlock_cred_security fown_subject;
91 /**
92 * @fown_tg: Thread group of the task that set the file owner, pinned
93 * while @fown_subject holds a domain. It lets
94 * hook_file_send_sigiotask() always allow a SIGIO delivered to the
95 * owner's own process -- e.g. the thread-group leader reached through a
96 * process-group owner -- matching the same-process exemption of
97 * hook_task_kill(). NULL when no domain is recorded. Protected by
98 * file->f_owner->lock, like @fown_subject.
99 */
100 struct pid *fown_tg;
101};
102
103#ifdef CONFIG_SECURITY_LANDLOCK_LOG
104
105/* Makes sure all layers can be identified. */
106/* clang-format off */
107static_assert((typeof_member(struct landlock_file_security, fown_layer))~0 >=
108 LANDLOCK_MAX_NUM_LAYERS);
109/* clang-format on */
110
111/*
112 * Make sure quiet_optional_accesses has enough bits to cover all optional
113 * accesses.
114 */
115static_assert(BITS_PER_TYPE(typeof_member(struct landlock_file_security,
116 quiet_optional_accesses)) >=
117 HWEIGHT(_LANDLOCK_ACCESS_FS_OPTIONAL));
118
119#endif /* CONFIG_SECURITY_LANDLOCK_LOG */
120
121/**
122 * struct landlock_superblock_security - Superblock security blob
123 *
124 * Enable hook_sb_delete() to wait for concurrent calls to release_inode().
125 */
126struct landlock_superblock_security {
127 /**
128 * @inode_refs: Number of pending inodes (from this superblock) that
129 * are being released by release_inode().
130 * Cf. struct super_block->s_fsnotify_inode_refs .
131 */
132 atomic_long_t inode_refs;
133};
134
135static inline struct landlock_file_security *
136landlock_file(const struct file *const file)
137{
138 return file->f_security + landlock_blob_sizes.lbs_file;
139}
140
141static inline struct landlock_inode_security *
142landlock_inode(const struct inode *const inode)
143{
144 return inode->i_security + landlock_blob_sizes.lbs_inode;
145}
146
147static inline struct landlock_superblock_security *
148landlock_superblock(const struct super_block *const superblock)
149{
150 return superblock->s_security + landlock_blob_sizes.lbs_superblock;
151}
152
153__init void landlock_add_fs_hooks(void);
154
155int landlock_append_fs_rule(struct landlock_ruleset *const ruleset,
156 const struct path *const path,
157 access_mask_t access_hierarchy, const u32 flags);
158
159/**
160 * resolve_path_for_trace - Resolve a path for tracepoint display
161 *
162 * @path: The path to resolve.
163 * @buf: A buffer of at least PATH_MAX bytes for the resolved path.
164 *
165 * Uses d_absolute_path() to produce a namespace-independent absolute path,
166 * unlike d_path() which resolves relative to the process's chroot. This
167 * ensures trace output is deterministic regardless of the tracer's mount
168 * namespace.
169 *
170 * Return: A pointer into @buf with the resolved path, or an error string
171 * ("<too_long>", "<unreachable>").
172 */
173static inline const char *resolve_path_for_trace(const struct path *path,
174 char *buf)
175{
176 const char *p;
177
178 p = d_absolute_path(path, buf, PATH_MAX);
179 if (!IS_ERR_OR_NULL(p))
180 return p;
181
182 if (PTR_ERR(p) == -ENAMETOOLONG)
183 return "<too_long>";
184
185 return "<unreachable>";
186}
187
188#endif /* _SECURITY_LANDLOCK_FS_H */