Patchwork [4/4] netfilter: xtables: inclusion of xt_SYSRQ

login
register
mail settings
Submitter Jan Engelhardt
Date July 10, 2012, 11:52 p.m.
Message ID <1341964350-13809-5-git-send-email-jengelh@inai.de>
Download mbox | patch
Permalink /patch/170305/
State RFC
Headers show

Comments

Jan Engelhardt - July 10, 2012, 11:52 p.m.
The SYSRQ target will allow to remotely invoke sysrq on the local
machine. Authentication is by means of a pre-shared key that can
either be transmitted plaintext or digest-secured.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 net/netfilter/Kconfig    |   12 ++
 net/netfilter/Makefile   |    1 +
 net/netfilter/xt_SYSRQ.c |  361 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 net/netfilter/xt_SYSRQ.c
Pablo Neira - July 12, 2012, 3:49 p.m.
On Wed, Jul 11, 2012 at 01:52:30AM +0200, Jan Engelhardt wrote:
> The SYSRQ target will allow to remotely invoke sysrq on the local
> machine. Authentication is by means of a pre-shared key that can
> either be transmitted plaintext or digest-secured.
> 
> Signed-off-by: Jan Engelhardt <jengelh@inai.de>
> ---
>  net/netfilter/Kconfig    |   12 ++
>  net/netfilter/Makefile   |    1 +
>  net/netfilter/xt_SYSRQ.c |  361 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 374 insertions(+), 0 deletions(-)
>  create mode 100644 net/netfilter/xt_SYSRQ.c
> 
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index c19b214..fbe8e40 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -644,6 +644,18 @@ config NETFILTER_XT_TARGET_RATEEST
>  
>  	  To compile it as a module, choose M here.  If unsure, say N.
>  
> +config NETFILTER_XT_TARGET_SYSRQ
> +	tristate '"SYSRQ" - remote sysrq invocation'
> +	depends on NETFILTER_ADVANCED
> +	---help---
> +	This option enables the "SYSRQ" target which can be used to trigger
> +	sysrq from a remote machine using a magic UDP packet with a pre-shared
> +	password. This is useful when the receiving host has locked up in an
> +	Oops yet still can process incoming packets.
> +
> +	Besides plaintext packets, digest-secured SYSRQ requests will be
> +	supported when CONFIG_CRYPTO is enabled.

I guess this is useful for user, eg. you can reboot your crashed
system from your office in case that cheap comodity hardware without
remote management tools (eg. HP's ILO or Dell's iDRAC).

Still, I think that including this in Netfilter is a bit of abuse
since this is out of the scope of providing some firewalling feature.

People willing to use this should be able to use without requiring
Netfilter at all.

If you have interest in pushing this into mainline, I think this
deserves to be generalized and included somewhere into the networking
tree and provide some genetlink interface to configure it.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Engelhardt - July 12, 2012, 4:25 p.m.
On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
>> +config NETFILTER_XT_TARGET_SYSRQ
>> +	tristate '"SYSRQ" - remote sysrq invocation'
>
>I guess this is useful for user, eg. you can reboot your crashed
>system from your office in case that cheap comodity hardware without
>remote management tools (eg. HP's ILO or Dell's iDRAC).
>
>Still, I think that including this in Netfilter is a bit of abuse
>since this is out of the scope of providing some firewalling feature.

David Miller has stated his opinion already last year, and he's
for the Netfilter variant:
http://markmail.org/message/d7kpczdbtpcxwli6
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Florian Westphal - July 12, 2012, 8:26 p.m.
Jan Engelhardt <jengelh@inai.de> wrote:
> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
> >> +config NETFILTER_XT_TARGET_SYSRQ
> >> +	tristate '"SYSRQ" - remote sysrq invocation'
> >
> >I guess this is useful for user, eg. you can reboot your crashed
> >system from your office in case that cheap comodity hardware without
> >remote management tools (eg. HP's ILO or Dell's iDRAC).
> >
> >Still, I think that including this in Netfilter is a bit of abuse
> >since this is out of the scope of providing some firewalling feature.
> 
> David Miller has stated his opinion already last year, and he's
> for the Netfilter variant:
> http://markmail.org/message/d7kpczdbtpcxwli6

We now have udp encap support also for ipv6, so this could now
be solved outside of netfilter without impacting the ability to
filter sysreq packets.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Engelhardt - July 12, 2012, 8:29 p.m.
On Thursday 2012-07-12 22:26, Florian Westphal wrote:

>Jan Engelhardt <jengelh@inai.de> wrote:
>> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
>> >> +config NETFILTER_XT_TARGET_SYSRQ
>> >> +	tristate '"SYSRQ" - remote sysrq invocation'
>> >
>> >I guess this is useful for user, eg. you can reboot your crashed
>> >system from your office in case that cheap comodity hardware without
>> >remote management tools (eg. HP's ILO or Dell's iDRAC).
>> >
>> >Still, I think that including this in Netfilter is a bit of abuse
>> >since this is out of the scope of providing some firewalling feature.
>> 
>> David Miller has stated his opinion already last year, and he's
>> for the Netfilter variant:
>> http://markmail.org/message/d7kpczdbtpcxwli6
>
>We now have udp encap support also for ipv6, so this could now
>be solved outside of netfilter without impacting the ability to
>filter sysreq packets.

How does xt_SYSRQ inhibit filtering sysrq packets?
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Florian Westphal - July 12, 2012, 8:35 p.m.
Jan Engelhardt <jengelh@inai.de> wrote:
> >Jan Engelhardt <jengelh@inai.de> wrote:
> >> David Miller has stated his opinion already last year, and he's
> >> for the Netfilter variant:
> >> http://markmail.org/message/d7kpczdbtpcxwli6
> >
> >We now have udp encap support also for ipv6, so this could now
> >be solved outside of netfilter without impacting the ability to
> >filter sysreq packets.
> 
> How does xt_SYSRQ inhibit filtering sysrq packets?

Not at all.  But the last 'do it outside of netfilter' approaches
suffered from that.  With encap sockets this should no longer be a
problem.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Engelhardt - July 12, 2012, 9:25 p.m.
On Thursday 2012-07-12 22:35, Florian Westphal wrote:

>Jan Engelhardt <jengelh@inai.de> wrote:
>> >Jan Engelhardt <jengelh@inai.de> wrote:
>> >> David Miller has stated his opinion already last year, and he's
>> >> for the Netfilter variant:
>> >> http://markmail.org/message/d7kpczdbtpcxwli6
>> >
>> >We now have udp encap support also for ipv6, so this could now
>> >be solved outside of netfilter without impacting the ability to
>> >filter sysreq packets.
>> 
>> How does xt_SYSRQ inhibit filtering sysrq packets?
>
>Not at all.  But the last 'do it outside of netfilter' approaches
>suffered from that.  With encap sockets this should no longer be a
>problem.

People like using Xtables because it's simple and they know how to
use it (or at least, the frontend). The biggest strength is that
users can _combine it with existing extensions_. All that seems
impossible with the sysrq-ping patch.

(You know how they hate it when they have to cross a "boundary" like
iptables-nfmark-tc and iptables-nfmark-iproute).
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pablo Neira - July 13, 2012, 9:16 a.m.
On Thu, Jul 12, 2012 at 06:25:13PM +0200, Jan Engelhardt wrote:
> 
> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
> >> +config NETFILTER_XT_TARGET_SYSRQ
> >> +	tristate '"SYSRQ" - remote sysrq invocation'
> >
> >I guess this is useful for user, eg. you can reboot your crashed
> >system from your office in case that cheap comodity hardware without
> >remote management tools (eg. HP's ILO or Dell's iDRAC).
> >
> >Still, I think that including this in Netfilter is a bit of abuse
> >since this is out of the scope of providing some firewalling feature.
> 
> David Miller has stated his opinion already last year, and he's
> for the Netfilter variant:
> http://markmail.org/message/d7kpczdbtpcxwli6

I think that affirmation is true in the context of:

[PATCH]: Add Network Sysrq Support

but not sure it's out of it.

He probably prefered the Netfilter option because, comparing it to the
Netfilter approach, it looks nicer. Well, just look at all those sysfs
and proc interfaces he was proposing for that approach (it seems quite
ugly to me).

You can use the udp_encap hook (that Florian mentioned) plus some
genetlink interface and little user-space tool to make it out of
netfilter. Most of the xt_SYSRQ code can be reused and the genetlink
interface plus one library can be added with little extra work.

@David: just to put you into context. Jan is proposing to merge
xt_SYSRQ into mainstream, we are discussing if it would be better to
make it out of it (so people do not depend on the firewalling
utilities to get it working) based on a different proposal described
above.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maciej Żenczykowski - July 14, 2012, 1:43 a.m.
On Fri, Jul 13, 2012 at 2:16 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Thu, Jul 12, 2012 at 06:25:13PM +0200, Jan Engelhardt wrote:
>>
>> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
>> >> +config NETFILTER_XT_TARGET_SYSRQ
>> >> +  tristate '"SYSRQ" - remote sysrq invocation'
>> >
>> >I guess this is useful for user, eg. you can reboot your crashed
>> >system from your office in case that cheap comodity hardware without
>> >remote management tools (eg. HP's ILO or Dell's iDRAC).
>> >
>> >Still, I think that including this in Netfilter is a bit of abuse
>> >since this is out of the scope of providing some firewalling feature.
>>
>> David Miller has stated his opinion already last year, and he's
>> for the Netfilter variant:
>> http://markmail.org/message/d7kpczdbtpcxwli6
>
> I think that affirmation is true in the context of:
>
> [PATCH]: Add Network Sysrq Support
>
> but not sure it's out of it.
>
> He probably prefered the Netfilter option because, comparing it to the
> Netfilter approach, it looks nicer. Well, just look at all those sysfs
> and proc interfaces he was proposing for that approach (it seems quite
> ugly to me).
>
> You can use the udp_encap hook (that Florian mentioned) plus some
> genetlink interface and little user-space tool to make it out of
> netfilter. Most of the xt_SYSRQ code can be reused and the genetlink
> interface plus one library can be added with little extra work.
>
> @David: just to put you into context. Jan is proposing to merge
> xt_SYSRQ into mainstream, we are discussing if it would be better to
> make it out of it (so people do not depend on the firewalling
> utilities to get it working) based on a different proposal described
> above.
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

For this to be truly useful, it has to work when all of userspace is
dead and unresponsive (oom hell, swap hell, hdd disconnected, etc),
and as such from the moment the magic packet gets received, to the
command (reboot/etc) being executed it has to be a fully kernel based
solution - preferably within the network softirq.

Anything relying on userspace (outside of initial configuration) is
not acceptable.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pablo Neira - July 14, 2012, 1:11 p.m.
On Fri, Jul 13, 2012 at 06:43:36PM -0700, Maciej Żenczykowski wrote:
> On Fri, Jul 13, 2012 at 2:16 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> > On Thu, Jul 12, 2012 at 06:25:13PM +0200, Jan Engelhardt wrote:
> >>
> >> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
> >> >> +config NETFILTER_XT_TARGET_SYSRQ
> >> >> +  tristate '"SYSRQ" - remote sysrq invocation'
> >> >
> >> >I guess this is useful for user, eg. you can reboot your crashed
> >> >system from your office in case that cheap comodity hardware without
> >> >remote management tools (eg. HP's ILO or Dell's iDRAC).
> >> >
> >> >Still, I think that including this in Netfilter is a bit of abuse
> >> >since this is out of the scope of providing some firewalling feature.
> >>
> >> David Miller has stated his opinion already last year, and he's
> >> for the Netfilter variant:
> >> http://markmail.org/message/d7kpczdbtpcxwli6
> >
> > I think that affirmation is true in the context of:
> >
> > [PATCH]: Add Network Sysrq Support
> >
> > but not sure it's out of it.
> >
> > He probably prefered the Netfilter option because, comparing it to the
> > Netfilter approach, it looks nicer. Well, just look at all those sysfs
> > and proc interfaces he was proposing for that approach (it seems quite
> > ugly to me).
> >
> > You can use the udp_encap hook (that Florian mentioned) plus some
> > genetlink interface and little user-space tool to make it out of
> > netfilter. Most of the xt_SYSRQ code can be reused and the genetlink
> > interface plus one library can be added with little extra work.
> >
> > @David: just to put you into context. Jan is proposing to merge
> > xt_SYSRQ into mainstream, we are discussing if it would be better to
> > make it out of it (so people do not depend on the firewalling
> > utilities to get it working) based on a different proposal described
> > above.
> > --
> > To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> For this to be truly useful, it has to work when all of userspace is
> dead and unresponsive (oom hell, swap hell, hdd disconnected, etc),
> and as such from the moment the magic packet gets received, to the
> command (reboot/etc) being executed it has to be a fully kernel based
> solution - preferably within the network softirq.
> 
> Anything relying on userspace (outside of initial configuration) is
> not acceptable.

So far, nobody mentioned the possibility any sort of user-space daemon
;-).

That user-space tool would be used to configure it through genetlink
outside of netfilter. That's all.

And I think everybody here still think this is useful, what we're
discussing is the nicer approach.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Aft nix - July 14, 2012, 2:49 p.m.
On Sat, Jul 14, 2012 at 7:11 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> On Fri, Jul 13, 2012 at 06:43:36PM -0700, Maciej Żenczykowski wrote:
>> On Fri, Jul 13, 2012 at 2:16 AM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>> > On Thu, Jul 12, 2012 at 06:25:13PM +0200, Jan Engelhardt wrote:
>> >>
>> >> On Thursday 2012-07-12 17:49, Pablo Neira Ayuso wrote:
>> >> >> +config NETFILTER_XT_TARGET_SYSRQ
>> >> >> +  tristate '"SYSRQ" - remote sysrq invocation'
>> >> >
>> >> >I guess this is useful for user, eg. you can reboot your crashed
>> >> >system from your office in case that cheap comodity hardware without
>> >> >remote management tools (eg. HP's ILO or Dell's iDRAC).
>> >> >
>> >> >Still, I think that including this in Netfilter is a bit of abuse
>> >> >since this is out of the scope of providing some firewalling feature.
>> >>
>> >> David Miller has stated his opinion already last year, and he's
>> >> for the Netfilter variant:
>> >> http://markmail.org/message/d7kpczdbtpcxwli6
>> >
>> > I think that affirmation is true in the context of:
>> >
>> > [PATCH]: Add Network Sysrq Support
>> >
>> > but not sure it's out of it.
>> >
>> > He probably prefered the Netfilter option because, comparing it to the
>> > Netfilter approach, it looks nicer. Well, just look at all those sysfs
>> > and proc interfaces he was proposing for that approach (it seems quite
>> > ugly to me).
>> >
>> > You can use the udp_encap hook (that Florian mentioned) plus some
>> > genetlink interface and little user-space tool to make it out of
>> > netfilter. Most of the xt_SYSRQ code can be reused and the genetlink
>> > interface plus one library can be added with little extra work.
>> >
>> > @David: just to put you into context. Jan is proposing to merge
>> > xt_SYSRQ into mainstream, we are discussing if it would be better to
>> > make it out of it (so people do not depend on the firewalling
>> > utilities to get it working) based on a different proposal described
>> > above.
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
>> > the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>> For this to be truly useful, it has to work when all of userspace is
>> dead and unresponsive (oom hell, swap hell, hdd disconnected, etc),
>> and as such from the moment the magic packet gets received, to the
>> command (reboot/etc) being executed it has to be a fully kernel based
>> solution - preferably within the network softirq.
>>
>> Anything relying on userspace (outside of initial configuration) is
>> not acceptable.
>
> So far, nobody mentioned the possibility any sort of user-space daemon
> ;-).
>
> That user-space tool would be used to configure it through genetlink
> outside of netfilter. That's all.
>
> And I think everybody here still think this is useful, what we're
> discussing is the nicer approach.
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Hi Jan,

I don't know if it goes to main line kernel eventually, i want this feature
right now. Right now i have to physically go the office rack to reboot in a
case of kernel crash. Office IT people don't provide IPKVM stuffs in development
servers, they only give it to "production" severs.

I really think its nice touch. Is it available in xtable-addons, or i
just apply your patch directly?

Cheers.
Jan Engelhardt - July 14, 2012, 3:24 p.m.
On Saturday 2012-07-14 16:49, Aft nix wrote:
>>> > @David: just to put you into context. Jan is proposing to merge
>>> > xt_SYSRQ into mainstream, we are discussing if it would be better to
>>> > make it out of it (so people do not depend on the firewalling
>>> > utilities to get it working) based on a different proposal described
>>> > above.
>
>Hi Jan,
>
>I don't know if it goes to main line kernel eventually, i want this feature
>right now. Right now i have to physically go the office rack to reboot in a
>case of kernel crash. Office IT people don't provide IPKVM stuffs in development
>servers, they only give it to "production" severs.
>
>I really think its nice touch. Is it available in xtable-addons, or i
>just apply your patch directly?

It is in Xt-a, and I try to upstream it.

Again, I emphasize that xt_SYSRQ can be combined with other matches
of Xtables, and that why it should be merged rather than a separate
subsystem of some kind.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c19b214..fbe8e40 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -644,6 +644,18 @@  config NETFILTER_XT_TARGET_RATEEST
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_SYSRQ
+	tristate '"SYSRQ" - remote sysrq invocation'
+	depends on NETFILTER_ADVANCED
+	---help---
+	This option enables the "SYSRQ" target which can be used to trigger
+	sysrq from a remote machine using a magic UDP packet with a pre-shared
+	password. This is useful when the receiving host has locked up in an
+	Oops yet still can process incoming packets.
+
+	Besides plaintext packets, digest-secured SYSRQ requests will be
+	supported when CONFIG_CRYPTO is enabled.
+
 config NETFILTER_XT_TARGET_TEE
 	tristate '"TEE" - packet cloning to alternate destination'
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 1c5160f..68881c8 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -70,6 +70,7 @@  obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_SYSRQ) += xt_SYSRQ.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
diff --git a/net/netfilter/xt_SYSRQ.c b/net/netfilter/xt_SYSRQ.c
new file mode 100644
index 0000000..885b902
--- /dev/null
+++ b/net/netfilter/xt_SYSRQ.c
@@ -0,0 +1,361 @@ 
+/*
+ *	"SYSRQ" target extension for Xtables
+ *	Copyright © Jan Engelhardt, 2008-2012
+ *
+ *	Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
+ *	Security additions John Haxby <john.haxby [at] oracle com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	version 2 or later as published by the Free Software Foundation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/sysrq.h>
+#include <linux/udp.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <net/ip.h>
+
+#if defined(CONFIG_CRYPTO) || defined(CRYPTO_CONFIG_MODULE)
+#	define WITH_CRYPTO 1
+#endif
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#	define WITH_IPV6 1
+#endif
+
+static bool sysrq_once;
+static char sysrq_password[64];
+static char sysrq_hash[16] = "sha1";
+static long sysrq_seqno;
+static int sysrq_debug;
+module_param_string(password, sysrq_password, sizeof(sysrq_password),
+		    S_IRUSR | S_IWUSR);
+module_param_string(hash, sysrq_hash, sizeof(sysrq_hash), S_IRUSR);
+module_param_named(seqno, sysrq_seqno, long, S_IRUSR | S_IWUSR);
+module_param_named(debug, sysrq_debug, int, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(password, "password for remote sysrq");
+MODULE_PARM_DESC(hash, "hash algorithm, default sha1");
+MODULE_PARM_DESC(seqno, "sequence number for remote sysrq");
+MODULE_PARM_DESC(debug, "debugging: 0=off, 1=on");
+
+#ifdef WITH_CRYPTO
+static struct crypto_hash *sysrq_tfm;
+static int sysrq_digest_size;
+static unsigned char *sysrq_digest_password;
+static unsigned char *sysrq_digest;
+static char *sysrq_hexdigest;
+
+/*
+ * The data is of the form "<requests>,<seqno>,<salt>,<hash>" where <requests>
+ * is a series of sysrq requests; <seqno> is a sequence number that must be
+ * greater than the last sequence number; <salt> is some random bytes; and
+ * <hash> is the hash of everything up to and including the preceding ","
+ * together with "<dstaddr>,<password>".
+ *
+ * For example
+ *
+ *   salt=$RANDOM
+ *   req="s,$(date +%s),$salt"
+ *   echo "$req,$(echo -n $req,10.10.25.1,secret | sha1sum | cut -c1-40)"
+ *
+ * You will want a better salt and password than that though :-)
+ */
+static unsigned int sysrq_tg(const void *pdata, uint16_t len)
+{
+	const char *data = pdata;
+	int i, n;
+	struct scatterlist sg[2];
+	struct hash_desc desc;
+	int ret;
+	long new_seqno = 0;
+
+	if (*sysrq_password == '\0') {
+		if (!sysrq_once)
+			pr_info("No password set\n");
+		sysrq_once = true;
+		return NF_DROP;
+	}
+	if (len == 0)
+		return NF_DROP;
+
+	for (i = 0; sysrq_password[i] != '\0' &&
+	     sysrq_password[i] != '\n'; ++i)
+		/* loop */;
+	sysrq_password[i] = '\0';
+
+	i = 0;
+	for (n = 0; n < len - 1; ++n) {
+		if (i == 1 && '0' <= data[n] && data[n] <= '9')
+			new_seqno = 10L * new_seqno + data[n] - '0';
+		if (data[n] == ',' && ++i == 3)
+			break;
+	}
+	++n;
+	if (i != 3) {
+		if (sysrq_debug)
+			pr_info("badly formatted request\n");
+		return NF_DROP;
+	}
+	if (sysrq_seqno >= new_seqno) {
+		if (sysrq_debug)
+			pr_info("old sequence number ignored\n");
+		return NF_DROP;
+	}
+
+	desc.tfm   = sysrq_tfm;
+	desc.flags = 0;
+	ret = crypto_hash_init(&desc);
+	if (ret != 0)
+		goto hash_fail;
+	sg_init_table(sg, 2);
+	sg_set_buf(&sg[0], data, n);
+	i = strlen(sysrq_digest_password);
+	sg_set_buf(&sg[1], sysrq_digest_password, i);
+	ret = crypto_hash_digest(&desc, sg, n + i, sysrq_digest);
+	if (ret != 0)
+		goto hash_fail;
+
+	for (i = 0; i < sysrq_digest_size; ++i) {
+		sysrq_hexdigest[2*i] =
+			"0123456789abcdef"[(sysrq_digest[i] >> 4) & 0xf];
+		sysrq_hexdigest[2*i+1] =
+			"0123456789abcdef"[sysrq_digest[i] & 0xf];
+	}
+	sysrq_hexdigest[2*sysrq_digest_size] = '\0';
+	if (len - n < sysrq_digest_size * 2) {
+		if (sysrq_debug)
+			pr_info("Short digest, expected %s\n",
+				sysrq_hexdigest);
+		return NF_DROP;
+	}
+	if (strncmp(data + n, sysrq_hexdigest, sysrq_digest_size * 2) != 0) {
+		if (sysrq_debug)
+			pr_info("Bad digest, expected %s\n", sysrq_hexdigest);
+		return NF_DROP;
+	}
+
+	/* Now we trust the requester */
+	sysrq_seqno = new_seqno;
+	for (i = 0; i < len && data[i] != ','; ++i) {
+		pr_info("SysRq %c\n", data[i]);
+		handle_sysrq(data[i]);
+	}
+	return NF_ACCEPT;
+
+ hash_fail:
+	pr_warning("digest failure\n");
+	return NF_DROP;
+}
+#else
+static unsigned int sysrq_tg(const void *pdata, uint16_t len)
+{
+	const char *data = pdata;
+	char c;
+
+	if (*sysrq_password == '\0') {
+		if (!sysrq_once)
+			pr_info("No password set\n");
+		sysrq_once = true;
+		return NF_DROP;
+	}
+
+	if (len == 0)
+		return NF_DROP;
+
+	c = *data;
+	if (strncmp(&data[1], sysrq_password, len - 1) != 0) {
+		pr_warning("Failed attempt - password mismatch\n");
+		return NF_DROP;
+	}
+
+	handle_sysrq(c, NULL);
+	return NF_ACCEPT;
+}
+#endif
+
+static unsigned int
+sysrq_tg4(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	const struct iphdr *iph;
+	const struct udphdr *udph;
+	uint16_t len;
+
+	if (skb_linearize(skb) < 0)
+		return NF_DROP;
+
+	iph = ip_hdr(skb);
+	if (iph->protocol != IPPROTO_UDP && iph->protocol != IPPROTO_UDPLITE)
+		return NF_DROP;
+
+	udph = (const void *)iph + ip_hdrlen(skb);
+	len  = ntohs(udph->len) - sizeof(struct udphdr);
+
+	if (sysrq_debug)
+		pr_info(": %pI4:%u -> :%u len=%u\n", &iph->saddr,
+			htons(udph->source), htons(udph->dest), len);
+#ifdef WITH_CRYPTO
+	sprintf(sysrq_digest_password, "%pI4,%s", &iph->daddr, sysrq_password);
+#endif
+	return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
+}
+
+#ifdef WITH_IPV6
+static unsigned int
+sysrq_tg6(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	const struct ipv6hdr *iph;
+	const struct udphdr *udph;
+	unsigned short frag_off;
+	unsigned int th_off;
+	uint16_t len;
+
+	if (skb_linearize(skb) < 0)
+		return NF_DROP;
+
+	iph = ipv6_hdr(skb);
+	if (ipv6_find_hdr(skb, &th_off, IPPROTO_UDP, &frag_off, NULL) < 0 ||
+	    ipv6_find_hdr(skb, &th_off, IPPROTO_UDPLITE,
+	                  &frag_off, NULL) < 0 ||
+	    frag_off > 0)
+		return NF_DROP;
+
+	udph = (const void *)iph + th_off;
+	len  = ntohs(udph->len) - sizeof(struct udphdr);
+
+	if (sysrq_debug)
+		pr_info("%pI6:%hu -> :%hu len=%u\n", &iph->saddr,
+			ntohs(udph->source), ntohs(udph->dest), len);
+#ifdef WITH_CRYPTO
+	sprintf(sysrq_digest_password, "%pI6,%s", &iph->daddr, sysrq_password);
+#endif
+	return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
+}
+#endif
+
+static int sysrq_tg_check(const struct xt_tgchk_param *par)
+{
+	if (par->target->family == NFPROTO_IPV4) {
+		const struct ipt_entry *entry = par->entryinfo;
+
+		if ((entry->ip.proto != IPPROTO_UDP &&
+		    entry->ip.proto != IPPROTO_UDPLITE) ||
+		    entry->ip.invflags & XT_INV_PROTO)
+			goto out;
+	} else if (par->target->family == NFPROTO_IPV6) {
+		const struct ip6t_entry *entry = par->entryinfo;
+
+		if ((entry->ipv6.proto != IPPROTO_UDP &&
+		    entry->ipv6.proto != IPPROTO_UDPLITE) ||
+		    entry->ipv6.invflags & XT_INV_PROTO)
+			goto out;
+	}
+
+	return 0;
+
+ out:
+	pr_info("only available for UDP and UDP-Lite");
+	return -EINVAL;
+}
+
+static struct xt_target sysrq_tg_reg[] __read_mostly = {
+	{
+		.name       = "SYSRQ",
+		.revision   = 1,
+		.family     = NFPROTO_IPV4,
+		.target     = sysrq_tg4,
+		.checkentry = sysrq_tg_check,
+		.me         = THIS_MODULE,
+	},
+#ifdef WITH_IPV6
+	{
+		.name       = "SYSRQ",
+		.revision   = 1,
+		.family     = NFPROTO_IPV6,
+		.target     = sysrq_tg6,
+		.checkentry = sysrq_tg_check,
+		.me         = THIS_MODULE,
+	},
+#endif
+};
+
+static void sysrq_crypto_exit(void)
+{
+#ifdef WITH_CRYPTO
+	if (sysrq_tfm)
+		crypto_free_hash(sysrq_tfm);
+	if (sysrq_digest)
+		kfree(sysrq_digest);
+	if (sysrq_hexdigest)
+		kfree(sysrq_hexdigest);
+	if (sysrq_digest_password)
+		kfree(sysrq_digest_password);
+#endif
+}
+
+static int __init sysrq_crypto_init(void)
+{
+#if defined(WITH_CRYPTO)
+	struct timeval now;
+	int ret;
+
+	sysrq_tfm = crypto_alloc_hash(sysrq_hash, 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(sysrq_tfm)) {
+		pr_err("Could not find or load %s hash\n", sysrq_hash);
+		sysrq_tfm = NULL;
+		ret = PTR_ERR(sysrq_tfm);
+		goto fail;
+	}
+	sysrq_digest_size = crypto_hash_digestsize(sysrq_tfm);
+	sysrq_digest = kmalloc(sysrq_digest_size, GFP_KERNEL);
+	ret = -ENOMEM;
+	if (sysrq_digest == NULL)
+		goto fail;
+	sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
+	if (sysrq_hexdigest == NULL)
+		goto fail;
+	sysrq_digest_password = kmalloc(sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") +
+					sizeof(sysrq_password), GFP_KERNEL);
+	if (sysrq_digest_password == NULL)
+		goto fail;
+	do_gettimeofday(&now);
+	sysrq_seqno = now.tv_sec;
+	return 0;
+
+ fail:
+	sysrq_crypto_exit();
+	return ret;
+#else
+	pr_info("compiled without crypto\n");
+#endif
+	return -EINVAL;
+}
+
+static int __init sysrq_tg_init(void)
+{
+	if (sysrq_crypto_init() < 0)
+		pr_info("starting without crypto\n");
+	return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
+}
+
+static void __exit sysrq_tg_exit(void)
+{
+	sysrq_crypto_exit();
+	xt_unregister_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
+}
+
+module_init(sysrq_tg_init);
+module_exit(sysrq_tg_exit);
+MODULE_DESCRIPTION("Xtables: triggering SYSRQ remotely");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@inai.de>");
+MODULE_AUTHOR("John Haxby <john.haxby@oracle.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_SYSRQ");
+MODULE_ALIAS("ip6t_SYSRQ");