Commit 39ff20f5 authored by Tomas Mudrunka's avatar Tomas Mudrunka Committed by Greg Kroah-Hartman
Browse files

/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: default avatarTomas Mudrunka <tomas.mudrunka@gmail.com>
Reviewed-by: default avatarJiri Slaby <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20231120111451.527952-1-tomas.mudrunka@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 01c33b81
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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?
+16 −3
Original line number Diff line number Diff line
@@ -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;

		if (c == '_')
			bulk = true;
		else
			__handle_sysrq(c, false);

		if (!bulk)
			break;
	}

	return count;