/proc/sysrq-trigger: accept multiple keys at once
authorTomas Mudrunka <tomas.mudrunka@gmail.com>
Mon, 20 Nov 2023 11:14:51 +0000 (12:14 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 25 Nov 2023 07:23:16 +0000 (07:23 +0000)
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>
Documentation/admin-guide/sysrq.rst
drivers/tty/sysrq.c

index 51906e47327b62e1f7e1eabfb69ddce055d82ee7..2f2e5bd440f9b340f1ffb910996b592ef79f645e 100644 (file)
@@ -75,10 +75,19 @@ On other
        submit a patch to be included in this section.
 
 On all
-       Write a character to /proc/sysrq-trigger.  e.g.::
+       Write a single character to /proc/sysrq-trigger.
+       Only the first character is processed, the rest of the string is
+       ignored. However, it is not recommended to write any extra characters
+       as the behavior is undefined and might change in the future versions.
+       E.g.::
 
                echo t > /proc/sysrq-trigger
 
+       Alternatively, write multiple characters prepended by underscore.
+       This way, all characters will be processed. E.g.::
+
+               echo _reisub > /proc/sysrq-trigger
+
 The :kbd:`<command key>` is case sensitive.
 
 What are the 'command' keys?
index 6b4a28bcf2f5f5406799a44bafa3891ef7d60f02..02217e3c916b560b782a32164e3fbf146570f712 100644 (file)
@@ -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;