All of lore.kernel.org
 help / color / mirror / Atom feed
From: Flavio Leitner <fbl@redhat.com>
To: Prarit Bhargava <prarit@redhat.com>
Cc: netdev@vger.kernel.org, davem@davemloft.net, agospoda@redhat.com,
	nhorman@redhat.com, lwoodman@redhat.com
Subject: Re: [PATCH]: Add Network Sysrq Support
Date: Tue, 21 Jun 2011 19:05:39 -0300	[thread overview]
Message-ID: <4E0115B3.2030802@redhat.com> (raw)
In-Reply-To: <20110621130040.12035.62533.sendpatchset@prarit.bos.redhat.com>

On 06/21/2011 10:00 AM, Prarit Bhargava wrote:
> Add Network Sysrq Support
> 
> In some circumstances, a system can hang/lockup in such a way that the system
> is completely unresponsive to keyboard or console input but is still
> responsive to ping.  The config option, CONFIG_SYSRQ_PING, builds
> net/ipv4/sysrq-ping.ko which allows a root user to configure the system for
> a remote sysrq.
> 
> To use this do:
> 
> mount -t debugfs none /sys/kernel/debug/
> echo 1 > /proc/sys/kernel/sysrq
> echo <hex digit val> > /sys/kernel/debug/network_sysrq_magic
> echo 1 > /sys/kernel/debug/network_sysrq_enable
> 
> Then on another system on the network you can do:
> 
> ping -c 1 -p <up to 30 hex digit val><hex val of sysrq> <target_system_name>
> 
> ex) sysrq-m, m is ascii 0x6d
> 
> ping -c 1 p 1623a06f554d46d676d <target_system_name>

missing '-' in front of 'p'


> 
> Note that the network sysrq automatically disables after the receipt of
> the ping, ie) it is single-shot mode.  If you want to use this again, you
> must complete the above four steps again.
> 
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
> 
> diff --git a/Documentation/networking/sysrq-ping.txt b/Documentation/networking/sysrq-ping.txt
> new file mode 100644
> index 0000000..efa8be3
> --- /dev/null
> +++ b/Documentation/networking/sysrq-ping.txt
> @@ -0,0 +1,26 @@
> +In some circumstances, a system can hang/lockup in such a way that the system
> +is completely unresponsive to keyboard or console input but is still
> +responsive to ping.  The config option, CONFIG_SYSRQ_PING, builds
> +net/ipv4/sysrq-ping.ko which allows a root user to configure the system for a
> +remote sysrq.
> +
> +To use this do:
> +
> +mount -t debugfs none /sys/kernel/debug/
> +echo 1 > /proc/sys/kernel/sysrq
> +echo <hex digit val> > /sys/kernel/debug/network_sysrq_magic
> +echo 1 > /sys/kernel/debug/network_sysrq_enable
> +
> +Then on another system you can do:
> +
> +ping -c 1 -p <hex digit val><hex val of sysrq> <target_system_name>
> +
> +ex) sysrq-m, m is ascii 0x6d
> +
> +    ping -c 1 p 1623a06f554d46d676d <target_system_name>

again -p

> +
> +Note that the network sysrq automatically disables after the receipt of
> +the ping, ie) it is single-shot mode.  If you want to use this again, you
> +must complete the above four steps again.
> +
> +Hint: 'man ascii' ;)
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> index cbb505b..03bb7b1 100644
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -624,3 +624,11 @@ config TCP_MD5SIG
>  	  on the Internet.
>  
>  	  If unsure, say N.
> +
> +config SYSRQ_PING
> +	tristate
> +	default m

prompt?


> +	help
> +	  Allows execution of sysrq-X commands via ping over ipv4.  This is a
> +	  known security hazard and should not be used in unsecure
> +	  environments.
> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
> index f2dc69c..c23c15e 100644
> --- a/net/ipv4/Makefile
> +++ b/net/ipv4/Makefile
> @@ -48,6 +48,7 @@ obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
>  obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
>  obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
>  obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
> +obj-$(CONFIG_SYSRQ_PING) += sysrq-ping.o
>  
>  obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
>  		      xfrm4_output.o
> diff --git a/net/ipv4/sysrq-ping.c b/net/ipv4/sysrq-ping.c
> new file mode 100644
> index 0000000..67a6d0e
> --- /dev/null
> +++ b/net/ipv4/sysrq-ping.c
> @@ -0,0 +1,207 @@
> +/*
> + * network_sysrq.c - allow sysrq to be executed over a network via ping
> + *
> + * written by:  Prarit Bhargava <prarit@redhat.com>
> + *		Andy Gospodarek <agospoda@redhat.com>
> + *		Neil Horman <nhorman@redhat.com>
> + *
> + * based on work by:	Larry Woodman <lwoodman@redhat.com>
> + *
> + * To use this do:
> + *
> + *	mount -t debugfs none /sys/kernel/debug/
> + *	echo 1 > /proc/sys/kernel/sysrq
> + *	echo <hex digit val> > /sys/kernel/debug/network_sysrq_magic
> + *	echo 1 > /sys/kernel/debug/network_sysrq_enable
> + *
> + * Then on another system you can do:
> + *
> + *	ping -c 1 -p <hex digit val><hex val of sysrq> <target_system_name>
> + *
> + *	ex) sysrq-m, m is 0x6d
> + *
> + *	    ping -c 1 p 1623a06f554d46d676d <target_system_name>

again -p

> + *
> + * Note that the network sysrq automatically disables after the receipt of
> + * *ANY* ping.  If you want to use this again, you must complete the
> + * above four steps again.

why not leave it running? perhaps disable it for some time to
filter any ping retransmission, for instance netsysrq_reenable=10 seconds. 
and then do if (time_after(jiffies, last_ping + netsysrq_reenable))...

I have an USB KVM console, so often when testing workload, the USB takes
ages to register the keyboard and I'd like to shot some sysrq+t or w,
so if it disables after the first one, I can't get more traces because
I simply can't enable it again.


> + *
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/icmp.h>
> +#include <linux/init.h>
> +#include <linux/ip.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/sysrq.h>
> +
> +#include <net/xfrm.h>
> +
> +static u8 network_sysrq_enable; /* set in debugfs network_sysrq_enable */
> +static u16 network_sysrq_magic[16]; /* 15 bytes leaves 1 feature byte */
> +static int network_sysrq_magic_len;
> +
> +static int to_hex(int val)
> +{
> +	if ((val >= '0') && (val <= '9'))
> +		return val - 0x30;
> +
> +	if ((val >= 'a') && (val <= 'f'))
> +		return val - 0x37;
> +
> +	if ((val >= 'A') && (val <= 'F'))
> +		return val - 0x57;
> +
> +	return -1;
> +}
> +
> +static bool network_sysrq_armed(void)
> +{
> +	int i;
> +
> +	if (!network_sysrq_enable)
> +		return false;
> +	if (!network_sysrq_magic_len)
> +		return false;
> +	for (i = 0; i < 16; i++)
> +		if (network_sysrq_magic[i] != 0)
> +			return true;
> +	return false;
> +}
> +
> +static void network_sysrq_disable(void)
> +{
> +	network_sysrq_enable = 0;
> +	memset(network_sysrq_magic, 0, 32);
> +	network_sysrq_magic_len = 0;
> +}
> +
> +static ssize_t network_sysrq_seq_write(struct file *file,
> +				       const char __user *ubuf,
> +				       size_t count, loff_t *ppos)
> +{
> +	int i, j, hi, lo;
> +	char buf[33];
> +	memset(buf, 0, sizeof(buf));
> +
> +	if (count >= 33)
> +		return -EINVAL;
> +
> +	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
> +		return -EFAULT;
> +
> +	for (i = 0, j = 0; i < count - 2 ; i += 2, j++) {
> +		hi = to_hex(buf[i]);
> +		lo = to_hex(buf[i+1]) & 0x0f;
> +		if ((hi == -1) || (lo == -1)) {
> +			network_sysrq_disable();
> +			return -EINVAL;
> +		}
> +		network_sysrq_magic[j] = (u16)(hi << 4) + lo;
> +	}
> +	network_sysrq_magic_len = j;
> +
> +	return count;
> +}
> +
> +static int network_sysrq_seq_show(struct seq_file *m, void *p)
> +{
> +	int i;
> +
> +	for (i = 0; i < network_sysrq_magic_len; i++)
> +		seq_printf(m, "%02x", network_sysrq_magic[i]);
> +	seq_printf(m, "\n");
> +	return 0;
> +}
> +
> +static int network_sysrq_fops_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, network_sysrq_seq_show, inode->i_private);
> +}
> +
> +static const struct file_operations xnetwork_sysrq_fops = {
> +	.open		= network_sysrq_fops_open,
> +	.write		= network_sysrq_seq_write,
> +	.read		= seq_read,
> +	.llseek		= seq_lseek,
> +};
> +
> +static int network_sysrq_func(struct sk_buff *skb, struct net_device *dev,
> +			      struct packet_type *pt,
> +			      struct net_device *orig_dev)
> +{
> +	struct icmphdr *icmph;
> +	char *found;
> +
> +	if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
> +		goto end;
> +
> +	if (!skb_pull(skb, sizeof(struct iphdr)))
> +		goto end;
> +
> +	skb_reset_transport_header(skb);
> +	icmph = icmp_hdr(skb);
> +
> +	if (!skb_pull(skb, sizeof(*icmph)))
> +		goto end;
> +
> +	/* is this a ping? */
> +	if (icmph->type != ICMP_ECHO)
> +		goto end;


What about a whitelist of source MAC or IP addresses to accept the sysrq?

I'm thinking on a situation where we leave the systems with this enabled
and then an ordinary user starts pinging the network guessing the hexa to
cause reboots.

Tested here and it works.
Tested-by: Flavio Leitner <fbl@redhat.com>

fbl

> +	if (network_sysrq_armed()) {
> +		found = strnstr(skb->data, (char *)network_sysrq_magic,
> +				skb->len - skb->data_len);
> +		if (found)
> +			handle_sysrq(found[network_sysrq_magic_len]);
> +		network_sysrq_disable();
> +	}
> +end:
> +	kfree_skb(skb);
> +	return 0;
> +}
> +
> +static struct packet_type network_sysrq_type = {
> +	.type = cpu_to_be16(ETH_P_IP),
> +	.func = network_sysrq_func,
> +};
> +
> +static struct dentry *network_sysrq_enable_dentry;
> +static struct dentry *network_sysrq_magic_dentry;
> +
> +int __init init_network_sysrq(void)
> +{
> +	network_sysrq_enable_dentry = debugfs_create_u8("network_sysrq_enable",
> +							S_IWUGO | S_IRUGO,
> +							NULL,
> +							&network_sysrq_enable);
> +	if (!network_sysrq_enable_dentry)
> +		return -EIO;
> +
> +	network_sysrq_magic_dentry = debugfs_create_file("network_sysrq_magic",
> +							S_IWUGO | S_IRUGO,
> +							NULL,
> +							&network_sysrq_magic,
> +							&xnetwork_sysrq_fops);
> +	if (!network_sysrq_magic_dentry) {
> +		debugfs_remove(network_sysrq_enable_dentry);
> +		return -EIO;
> +	}
> +
> +	dev_add_pack(&network_sysrq_type);
> +	return 0;
> +}
> +
> +void __exit cleanup_network_sysrq(void)
> +{
> +	dev_remove_pack(&network_sysrq_type);
> +	debugfs_remove(network_sysrq_enable_dentry);
> +	debugfs_remove(network_sysrq_magic_dentry);
> +}
> +
> +module_init(init_network_sysrq);
> +module_exit(cleanup_network_sysrq);
> +
> +MODULE_LICENSE("GPL");
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


  parent reply	other threads:[~2011-06-21 22:05 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-21 13:00 [PATCH]: Add Network Sysrq Support Prarit Bhargava
2011-06-21 17:08 ` Stephen Hemminger
2011-06-21 18:30   ` Neil Horman
2011-06-21 20:09 ` Randy Dunlap
2011-06-21 20:37   ` Florian Westphal
2011-06-21 20:46     ` Randy Dunlap
2011-06-21 22:12   ` Prarit Bhargava
2011-06-21 22:05 ` Flavio Leitner [this message]
2011-06-21 22:26   ` Prarit Bhargava
2011-06-21 23:32     ` Flavio Leitner
2011-06-21 22:56   ` Florian Westphal
2011-06-21 22:58     ` David Miller
2011-06-22 10:26       ` Prarit Bhargava
2011-06-22 10:35         ` David Miller
2011-06-22 10:42           ` Prarit Bhargava
2011-06-22 10:54         ` Florian Westphal
2011-06-22 12:19           ` Prarit Bhargava
2011-06-22 12:37           ` John Haxby
2011-06-22 17:39             ` Prarit Bhargava
2011-06-22 18:46               ` John Haxby
2011-06-22 20:29                 ` David Miller
2011-06-22 18:57               ` John Haxby
2011-06-22 20:27               ` David Miller
2011-06-24 14:37           ` John Haxby
2011-06-22  7:55 ` WANG Cong
2011-06-22 15:29 ` Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E0115B3.2030802@redhat.com \
    --to=fbl@redhat.com \
    --cc=agospoda@redhat.com \
    --cc=davem@davemloft.net \
    --cc=lwoodman@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@redhat.com \
    --cc=prarit@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.