Skip to content

Commit a2564d0

Browse files
committed
loadpin: Implement custom proc_handler for enforce
Add a new static variable (loadpin_root_writable) to keep the write-ability state of enforce. Remove set_sysctl and const qualify loadpin_sysctl_table (moves into .rodata) as there is no longer need to change the value of extra1. The new proc_handler_loadpin returns -EINVAL when loadpin_root_writable is false and the kernel var (enforce) is being written. The old way of modifying the write-ability of enforce stays in loadpin_check and is still set by calling sb_is_writable. Signed-off-by: Joel Granados <joel.granados@kernel.org>
1 parent b22d81f commit a2564d0

1 file changed

Lines changed: 16 additions & 21 deletions

File tree

security/loadpin/loadpin.c

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,32 +52,29 @@ static DEFINE_SPINLOCK(pinned_root_spinlock);
5252
static bool deny_reading_verity_digests;
5353
#endif
5454

55+
// initialized to false
56+
static bool loadpin_root_writable;
5557
#ifdef CONFIG_SYSCTL
56-
static struct ctl_table loadpin_sysctl_table[] = {
58+
59+
static int proc_handler_loadpin(const struct ctl_table *table, int dir,
60+
void *buffer, size_t *lenp, loff_t *ppos)
61+
{
62+
if (!loadpin_root_writable && SYSCTL_USER_TO_KERN(dir))
63+
return -EINVAL;
64+
return proc_dointvec_minmax(table, dir, buffer, lenp, ppos);
65+
}
66+
67+
static const struct ctl_table loadpin_sysctl_table[] = {
5768
{
5869
.procname = "enforce",
5970
.data = &enforce,
6071
.maxlen = sizeof(int),
6172
.mode = 0644,
62-
.proc_handler = proc_dointvec_minmax,
63-
.extra1 = SYSCTL_ONE,
73+
.proc_handler = proc_handler_loadpin,
74+
.extra1 = SYSCTL_ZERO,
6475
.extra2 = SYSCTL_ONE,
6576
},
6677
};
67-
68-
static void set_sysctl(bool is_writable)
69-
{
70-
/*
71-
* If load pinning is not enforced via a read-only block
72-
* device, allow sysctl to change modes for testing.
73-
*/
74-
if (is_writable)
75-
loadpin_sysctl_table[0].extra1 = SYSCTL_ZERO;
76-
else
77-
loadpin_sysctl_table[0].extra1 = SYSCTL_ONE;
78-
}
79-
#else
80-
static inline void set_sysctl(bool is_writable) { }
8178
#endif
8279

8380
static void report_writable(struct super_block *mnt_sb, bool writable)
@@ -131,7 +128,6 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
131128
struct super_block *load_root;
132129
const char *origin = kernel_read_file_id_str(id);
133130
bool first_root_pin = false;
134-
bool load_root_writable;
135131

136132
/* If the file id is excluded, ignore the pinning. */
137133
if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) &&
@@ -152,7 +148,6 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
152148
}
153149

154150
load_root = file->f_path.mnt->mnt_sb;
155-
load_root_writable = sb_is_writable(load_root);
156151

157152
/* First loaded module/firmware defines the root for all others. */
158153
spin_lock(&pinned_root_spinlock);
@@ -168,8 +163,8 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id)
168163
spin_unlock(&pinned_root_spinlock);
169164

170165
if (first_root_pin) {
171-
report_writable(pinned_root, load_root_writable);
172-
set_sysctl(load_root_writable);
166+
loadpin_root_writable = sb_is_writable(pinned_root);
167+
report_writable(pinned_root, loadpin_root_writable);
173168
report_load(origin, file, "pinned");
174169
}
175170

0 commit comments

Comments
 (0)