1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * sysctl.c: General linux system control interface
4 */
5
6#include <linux/sysctl.h>
7#include <linux/printk.h>
8#include <linux/capability.h>
9#include <linux/ratelimit.h>
10#include "internal.h"
11
12static const int ten_thousand = 10000;
13
14static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
15				void *buffer, size_t *lenp, loff_t *ppos)
16{
17	if (write && !capable(CAP_SYS_ADMIN))
18		return -EPERM;
19
20	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
21}
22
23static struct ctl_table printk_sysctls[] = {
24	{
25		.procname	= "printk",
26		.data		= &console_loglevel,
27		.maxlen		= 4*sizeof(int),
28		.mode		= 0644,
29		.proc_handler	= proc_dointvec,
30	},
31	{
32		.procname	= "printk_ratelimit",
33		.data		= &printk_ratelimit_state.interval,
34		.maxlen		= sizeof(int),
35		.mode		= 0644,
36		.proc_handler	= proc_dointvec_jiffies,
37	},
38	{
39		.procname	= "printk_ratelimit_burst",
40		.data		= &printk_ratelimit_state.burst,
41		.maxlen		= sizeof(int),
42		.mode		= 0644,
43		.proc_handler	= proc_dointvec,
44	},
45	{
46		.procname	= "printk_delay",
47		.data		= &printk_delay_msec,
48		.maxlen		= sizeof(int),
49		.mode		= 0644,
50		.proc_handler	= proc_dointvec_minmax,
51		.extra1		= SYSCTL_ZERO,
52		.extra2		= (void *)&ten_thousand,
53	},
54	{
55		.procname	= "printk_devkmsg",
56		.data		= devkmsg_log_str,
57		.maxlen		= DEVKMSG_STR_MAX_SIZE,
58		.mode		= 0644,
59		.proc_handler	= devkmsg_sysctl_set_loglvl,
60	},
61	{
62		.procname	= "dmesg_restrict",
63		.data		= &dmesg_restrict,
64		.maxlen		= sizeof(int),
65		.mode		= 0644,
66		.proc_handler	= proc_dointvec_minmax_sysadmin,
67		.extra1		= SYSCTL_ZERO,
68		.extra2		= SYSCTL_ONE,
69	},
70	{
71		.procname	= "kptr_restrict",
72		.data		= &kptr_restrict,
73		.maxlen		= sizeof(int),
74		.mode		= 0644,
75		.proc_handler	= proc_dointvec_minmax_sysadmin,
76		.extra1		= SYSCTL_ZERO,
77		.extra2		= SYSCTL_TWO,
78	},
79	{}
80};
81
82void __init printk_sysctl_init(void)
83{
84	register_sysctl_init("kernel", printk_sysctls);
85}
86