summaryrefslogtreecommitdiff
path: root/drivers/tty/sysrq.c
diff options
context:
space:
mode:
authorTomas Mudrunka <tomas.mudrunka@gmail.com>2023-11-20 12:14:51 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-25 07:23:16 +0000
commit39ff20f5fd4481c9acf3b75c7b705b1ec6604588 (patch)
tree8fcc7cd52cf910207c6544da66cc7a66803da8a4 /drivers/tty/sysrq.c
parent01c33b813864ca15a9dec22045ce1a5bb09d5e74 (diff)
/proc/sysrq-trigger: accept multiple keys at once
This way we can do: `echo _reisub > /proc/sysrq-trigger` Instead of: `for i in r e i s u b; do echo "$i" > /proc/sysrq-trigger; done;` This can be very useful when trying to execute sysrq combo remotely or from userspace. When sending keys in multiple separate writes, userspace (eg. bash or ssh) can be killed before whole combo is completed. Therefore putting all keys in single write is more robust approach. Signed-off-by: Tomas Mudrunka <tomas.mudrunka@gmail.com> Reviewed-by: Jiri Slaby <jirislaby@kernel.org> Link: https://lore.kernel.org/r/20231120111451.527952-1-tomas.mudrunka@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/sysrq.c')
-rw-r--r--drivers/tty/sysrq.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 6b4a28bcf2f5..02217e3c916b 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -1150,16 +1150,29 @@ EXPORT_SYMBOL(unregister_sysrq_key);
#ifdef CONFIG_PROC_FS
/*
* writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ * Normally, only the first character written is processed.
+ * However, if the first character is an underscore,
+ * all characters are processed.
*/
static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- if (count) {
+ bool bulk = false;
+ size_t i;
+
+ for (i = 0; i < count; i++) {
char c;
- if (get_user(c, buf))
+ if (get_user(c, buf + i))
return -EFAULT;
- __handle_sysrq(c, false);
+
+ if (c == '_')
+ bulk = true;
+ else
+ __handle_sysrq(c, false);
+
+ if (!bulk)
+ break;
}
return count;