2006-09-22 05:56:14

by William Pitcock

[permalink] [raw]
Subject: [patch] sysctl to allow non-superusers to use ports <= 1023 without setpcaps

Hello everyone,

This is a patch that adds a sysctl,
net.ipv4.allow_lowport_nonsuperuser_bind, which removes the setpcaps/
sucaps/etc requirement for allowing a non-superuser process to use
ports <= 1023.

The patch is below:

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e4b1a4d..c3f7c3c 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -411,6 +411,7 @@ enum
NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
NET_TCP_DMA_COPYBREAK=116,
NET_TCP_SLOW_START_AFTER_IDLE=117,
+ NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER=118,
};
enum {
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c84a320..a2ea829 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -394,6 +394,11 @@ int inet_release(struct socket *sock)
/* It is off by default, see below. */
int sysctl_ip_nonlocal_bind;
+/* When this is enabled, it allows normal users to bind to ports <=
1023.
+ * This is set by the net.ipv4.allow_lowport_bind_nonsuperuser
sysctl value.
+ */
+int sysctl_ip_allow_lowport_bind_nonsuperuser;
+
int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
@@ -432,7 +437,8 @@ int inet_bind(struct socket *sock, struc
snum = ntohs(addr->sin_port);
err = -EACCES;
- if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+ if (!sysctl_ip_allow_lowport_bind_nonsuperuser && snum && snum <
PROT_SOCK &&
+ !capable(CAP_NET_BIND_SERVICE))
goto out;
/* We keep a pair of addresses. rcv_saddr is the one
@@ -1412,3 +1418,4 @@ EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw);
EXPORT_SYMBOL(net_statistics);
EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
+EXPORT_SYMBOL(sysctl_ip_allow_lowport_bind_nonsuperuser);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 70cea9d..c57ef3a 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -20,6 +20,7 @@ #include <net/tcp.h>
/* From af_inet.c */
extern int sysctl_ip_nonlocal_bind;
+extern int sysctl_ip_allow_lowport_bind_nonsuperuser;
#ifdef CONFIG_SYSCTL
static int zero;
@@ -197,6 +198,14 @@ ctl_table ipv4_table[] = {
.proc_handler = &proc_dointvec
},
{
+ .ctl_name = NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER,
+ .procname = "allow_lowport_bind_nonsuperuser",
+ .data = &sysctl_ip_allow_lowport_bind_nonsuperuser,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
.ctl_name = NET_IPV4_TCP_SYN_RETRIES,
.procname = "tcp_syn_retries",
.data = &sysctl_tcp_syn_retries,


2006-09-22 06:06:24

by William Pitcock

[permalink] [raw]
Subject: Re: [patch] sysctl to allow non-superusers to use ports <= 1023 without setpcaps

Hello again,

Hmm, it seems that my mail client mangled that.
I think I've fixed it, if not, you can get it from:
http://people.atheme.org/~nenolod/linux-
allow_lowport_bind_nonsuperuser_sysctl-1.diff

Sorry about that.

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e4b1a4d..c3f7c3c 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -411,6 +411,7 @@ enum
NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
NET_TCP_DMA_COPYBREAK=116,
NET_TCP_SLOW_START_AFTER_IDLE=117,
+ NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER=118,
};
enum {
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c84a320..a2ea829 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -394,6 +394,11 @@ int inet_release(struct socket *sock)
/* It is off by default, see below. */
int sysctl_ip_nonlocal_bind;

+/* When this is enabled, it allows normal users to bind to ports <=
1023.
+ * This is set by the net.ipv4.allow_lowport_bind_nonsuperuser
sysctl value.
+ */
+int sysctl_ip_allow_lowport_bind_nonsuperuser;
+
int inet_bind(struct socket *sock, struct sockaddr *uaddr, int
addr_len)
{
struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
@@ -432,7 +437,8 @@ int inet_bind(struct socket *sock, struc
snum = ntohs(addr->sin_port);
err = -EACCES;
- if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+ if (!sysctl_ip_allow_lowport_bind_nonsuperuser && snum && snum <
PROT_SOCK &&
+ !capable(CAP_NET_BIND_SERVICE))
goto out;
/* We keep a pair of addresses. rcv_saddr is the one
@@ -1412,3 +1418,4 @@ EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw);
EXPORT_SYMBOL(net_statistics);
EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
+EXPORT_SYMBOL(sysctl_ip_allow_lowport_bind_nonsuperuser);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 70cea9d..c57ef3a 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -20,6 +20,7 @@ #include <net/tcp.h>
/* From af_inet.c */
extern int sysctl_ip_nonlocal_bind;
+extern int sysctl_ip_allow_lowport_bind_nonsuperuser;
#ifdef CONFIG_SYSCTL
static int zero;
@@ -197,6 +198,14 @@ ctl_table ipv4_table[] = {
.proc_handler = &proc_dointvec
},
{
+ .ctl_name = NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER,
+ .procname = "allow_lowport_bind_nonsuperuser",
+ .data = &sysctl_ip_allow_lowport_bind_nonsuperuser,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
.ctl_name = NET_IPV4_TCP_SYN_RETRIES,
.procname = "tcp_syn_retries",
.data = &sysctl_tcp_syn_retries,


On Sep 22, 2006, at 12:56 AM, William Pitcock wrote:

> Hello everyone,
>
> This is a patch that adds a sysctl,
> net.ipv4.allow_lowport_nonsuperuser_bind, which removes the
> setpcaps/sucaps/etc requirement for allowing a non-superuser
> process to use ports <= 1023.
>
> The patch is below:
>
> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index e4b1a4d..c3f7c3c 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
> @@ -411,6 +411,7 @@ enum
> NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
> NET_TCP_DMA_COPYBREAK=116,
> NET_TCP_SLOW_START_AFTER_IDLE=117,
> + NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER=118,
> };
> enum {
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index c84a320..a2ea829 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -394,6 +394,11 @@ int inet_release(struct socket *sock)
> /* It is off by default, see below. */
> int sysctl_ip_nonlocal_bind;
> +/* When this is enabled, it allows normal users to bind to ports
> <= 1023.
> + * This is set by the net.ipv4.allow_lowport_bind_nonsuperuser
> sysctl value.
> + */
> +int sysctl_ip_allow_lowport_bind_nonsuperuser;
> +
> int inet_bind(struct socket *sock, struct sockaddr *uaddr, int
> addr_len)
> {
> struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
> @@ -432,7 +437,8 @@ int inet_bind(struct socket *sock, struc
> snum = ntohs(addr->sin_port);
> err = -EACCES;
> - if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
> + if (!sysctl_ip_allow_lowport_bind_nonsuperuser && snum && snum <
> PROT_SOCK &&
> + !capable(CAP_NET_BIND_SERVICE))
> goto out;
> /* We keep a pair of addresses. rcv_saddr is the one
> @@ -1412,3 +1418,4 @@ EXPORT_SYMBOL(inet_stream_ops);
> EXPORT_SYMBOL(inet_unregister_protosw);
> EXPORT_SYMBOL(net_statistics);
> EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
> +EXPORT_SYMBOL(sysctl_ip_allow_lowport_bind_nonsuperuser);
> diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
> index 70cea9d..c57ef3a 100644
> --- a/net/ipv4/sysctl_net_ipv4.c
> +++ b/net/ipv4/sysctl_net_ipv4.c
> @@ -20,6 +20,7 @@ #include <net/tcp.h>
> /* From af_inet.c */
> extern int sysctl_ip_nonlocal_bind;
> +extern int sysctl_ip_allow_lowport_bind_nonsuperuser;
> #ifdef CONFIG_SYSCTL
> static int zero;
> @@ -197,6 +198,14 @@ ctl_table ipv4_table[] = {
> .proc_handler = &proc_dointvec
> },
> {
> + .ctl_name = NET_IPV4_ALLOW_LOWPORT_BIND_NONSUPERUSER,
> + .procname = "allow_lowport_bind_nonsuperuser",
> + .data = &sysctl_ip_allow_lowport_bind_nonsuperuser,
> + .maxlen = sizeof(int),
> + .mode = 0644,
> + .proc_handler = &proc_dointvec
> + },
> + {
> .ctl_name = NET_IPV4_TCP_SYN_RETRIES,
> .procname = "tcp_syn_retries",
> .data = &sysctl_tcp_syn_retries,
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/