Commit eaee4172 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Greg Kroah-Hartman

sysctl/sysrq: Remove __sysrq_enabled copy

Many embedded boards have a disconnected TTL level serial which can
generate some garbage that can lead to spurious false sysrq detects.

Currently, sysrq can be either completely disabled for serial console
or always disabled (with CONFIG_MAGIC_SYSRQ_SERIAL), since
commit 732dbf3a ("serial: do not accept sysrq characters via serial port")

At Arista, we have such boards that can generate BREAK and random
garbage. While disabling sysrq for serial console would solve
the problem with spurious false sysrq triggers, it's also desirable
to have a way to enable sysrq back.

Having the way to enable sysrq was beneficial to debug lockups with
a manual investigation in field and on the other side preventing false
sysrq detections.

As a preparation to add sysrq_toggle_support() call into uart,
remove a private copy of sysrq_enabled from sysctl - it should reflect
the actual status of sysrq.

Furthermore, the private copy isn't correct already in case
sysrq_always_enabled is true. So, remove __sysrq_enabled and use a
getter-helper sysrq_mask() to check sysrq_key_op enabled status.

Cc: Iurii Zaikin <yzaikin@google.com>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Link: https://lore.kernel.org/r/20200302175135.269397-2-dima@arista.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7f980307
...@@ -63,6 +63,18 @@ static bool sysrq_on(void) ...@@ -63,6 +63,18 @@ static bool sysrq_on(void)
return sysrq_enabled || sysrq_always_enabled; return sysrq_enabled || sysrq_always_enabled;
} }
/**
* sysrq_mask - Getter for sysrq_enabled mask.
*
* Return: 1 if sysrq is always enabled, enabled sysrq_key_op mask otherwise.
*/
int sysrq_mask(void)
{
if (sysrq_always_enabled)
return 1;
return sysrq_enabled;
}
/* /*
* A value of 1 means 'all', other nonzero values are an op mask: * A value of 1 means 'all', other nonzero values are an op mask:
*/ */
......
...@@ -50,6 +50,7 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op); ...@@ -50,6 +50,7 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op);
struct sysrq_key_op *__sysrq_get_key_op(int key); struct sysrq_key_op *__sysrq_get_key_op(int key);
int sysrq_toggle_support(int enable_mask); int sysrq_toggle_support(int enable_mask);
int sysrq_mask(void);
#else #else
...@@ -71,6 +72,12 @@ static inline int unregister_sysrq_key(int key, struct sysrq_key_op *op) ...@@ -71,6 +72,12 @@ static inline int unregister_sysrq_key(int key, struct sysrq_key_op *op)
return -EINVAL; return -EINVAL;
} }
static inline int sysrq_mask(void)
{
/* Magic SysRq disabled mask */
return 0;
}
#endif #endif
#endif /* _LINUX_SYSRQ_H */ #endif /* _LINUX_SYSRQ_H */
...@@ -229,25 +229,8 @@ static int proc_dopipe_max_size(struct ctl_table *table, int write, ...@@ -229,25 +229,8 @@ static int proc_dopipe_max_size(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void __user *buffer, size_t *lenp, loff_t *ppos);
#ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAGIC_SYSRQ
/* Note: sysrq code uses its own private copy */
static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
static int sysrq_sysctl_handler(struct ctl_table *table, int write, static int sysrq_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, void __user *buffer, size_t *lenp, loff_t *ppos);
loff_t *ppos)
{
int error;
error = proc_dointvec(table, write, buffer, lenp, ppos);
if (error)
return error;
if (write)
sysrq_toggle_support(__sysrq_enabled);
return 0;
}
#endif #endif
static struct ctl_table kern_table[]; static struct ctl_table kern_table[];
...@@ -747,7 +730,7 @@ static struct ctl_table kern_table[] = { ...@@ -747,7 +730,7 @@ static struct ctl_table kern_table[] = {
#ifdef CONFIG_MAGIC_SYSRQ #ifdef CONFIG_MAGIC_SYSRQ
{ {
.procname = "sysrq", .procname = "sysrq",
.data = &__sysrq_enabled, .data = NULL,
.maxlen = sizeof (int), .maxlen = sizeof (int),
.mode = 0644, .mode = 0644,
.proc_handler = sysrq_sysctl_handler, .proc_handler = sysrq_sysctl_handler,
...@@ -2835,6 +2818,26 @@ static int proc_dostring_coredump(struct ctl_table *table, int write, ...@@ -2835,6 +2818,26 @@ static int proc_dostring_coredump(struct ctl_table *table, int write,
} }
#endif #endif
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_sysctl_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int tmp, ret;
tmp = sysrq_mask();
ret = __do_proc_dointvec(&tmp, table, write, buffer,
lenp, ppos, NULL, NULL);
if (ret || !write)
return ret;
if (write)
sysrq_toggle_support(tmp);
return 0;
}
#endif
static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
void __user *buffer, void __user *buffer,
size_t *lenp, loff_t *ppos, size_t *lenp, loff_t *ppos,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment