Skip to content

Commit c813e8c

Browse files
committed
Merge tag 'x86-misc-2020-08-03' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 MSR filtering from Ingo Molnar: "Filter MSR writes from user-space by default, and print a syslog entry if they happen outside the allowed set of MSRs, which is a single one for now, MSR_IA32_ENERGY_PERF_BIAS. The plan is to eventually disable MSR writes by default (they can still be enabled via allow_writes=on)" * tag 'x86-misc-2020-08-03' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/msr: Filter MSR writes
2 parents 69094c2 + a7e1f67 commit c813e8c

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

arch/x86/kernel/msr.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
static struct class *msr_class;
4343
static enum cpuhp_state cpuhp_msr_state;
4444

45+
enum allow_write_msrs {
46+
MSR_WRITES_ON,
47+
MSR_WRITES_OFF,
48+
MSR_WRITES_DEFAULT,
49+
};
50+
51+
static enum allow_write_msrs allow_writes = MSR_WRITES_DEFAULT;
52+
4553
static ssize_t msr_read(struct file *file, char __user *buf,
4654
size_t count, loff_t *ppos)
4755
{
@@ -70,6 +78,24 @@ static ssize_t msr_read(struct file *file, char __user *buf,
7078
return bytes ? bytes : err;
7179
}
7280

81+
static int filter_write(u32 reg)
82+
{
83+
switch (allow_writes) {
84+
case MSR_WRITES_ON: return 0;
85+
case MSR_WRITES_OFF: return -EPERM;
86+
default: break;
87+
}
88+
89+
if (reg == MSR_IA32_ENERGY_PERF_BIAS)
90+
return 0;
91+
92+
pr_err_ratelimited("Write to unrecognized MSR 0x%x by %s\n"
93+
"Please report to [email protected]\n",
94+
reg, current->comm);
95+
96+
return 0;
97+
}
98+
7399
static ssize_t msr_write(struct file *file, const char __user *buf,
74100
size_t count, loff_t *ppos)
75101
{
@@ -84,6 +110,10 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
84110
if (err)
85111
return err;
86112

113+
err = filter_write(reg);
114+
if (err)
115+
return err;
116+
87117
if (count % 8)
88118
return -EINVAL; /* Invalid chunk size */
89119

@@ -92,9 +122,13 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
92122
err = -EFAULT;
93123
break;
94124
}
125+
126+
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
127+
95128
err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
96129
if (err)
97130
break;
131+
98132
tmp += 2;
99133
bytes += 8;
100134
}
@@ -242,6 +276,41 @@ static void __exit msr_exit(void)
242276
}
243277
module_exit(msr_exit)
244278

279+
static int set_allow_writes(const char *val, const struct kernel_param *cp)
280+
{
281+
/* val is NUL-terminated, see kernfs_fop_write() */
282+
char *s = strstrip((char *)val);
283+
284+
if (!strcmp(s, "on"))
285+
allow_writes = MSR_WRITES_ON;
286+
else if (!strcmp(s, "off"))
287+
allow_writes = MSR_WRITES_OFF;
288+
else
289+
allow_writes = MSR_WRITES_DEFAULT;
290+
291+
return 0;
292+
}
293+
294+
static int get_allow_writes(char *buf, const struct kernel_param *kp)
295+
{
296+
const char *res;
297+
298+
switch (allow_writes) {
299+
case MSR_WRITES_ON: res = "on"; break;
300+
case MSR_WRITES_OFF: res = "off"; break;
301+
default: res = "default"; break;
302+
}
303+
304+
return sprintf(buf, "%s\n", res);
305+
}
306+
307+
static const struct kernel_param_ops allow_writes_ops = {
308+
.set = set_allow_writes,
309+
.get = get_allow_writes
310+
};
311+
312+
module_param_cb(allow_writes, &allow_writes_ops, NULL, 0600);
313+
245314
MODULE_AUTHOR("H. Peter Anvin <[email protected]>");
246315
MODULE_DESCRIPTION("x86 generic MSR driver");
247316
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)