diff -cr linux-2.4.9-31/include/net/ip.h linux-2.4.9-31-user-port-hack/include/net/ip.h *** linux-2.4.9-31/include/net/ip.h Tue Feb 26 11:54:22 2002 --- linux-2.4.9-31-user-port-hack/include/net/ip.h Fri Mar 15 15:57:55 2002 *************** *** 155,161 **** #define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field) #define NET_INC_STATS_USER(field) SNMP_INC_STATS_USER(net_statistics, field) ! extern int sysctl_local_port_range[2]; extern int sysctl_ip_default_ttl; #ifdef CONFIG_INET --- 155,161 ---- #define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field) #define NET_INC_STATS_USER(field) SNMP_INC_STATS_USER(net_statistics, field) ! extern int sysctl_local_port_range[6]; extern int sysctl_ip_default_ttl; #ifdef CONFIG_INET diff -cr linux-2.4.9-31/net/ipv4/af_inet.c linux-2.4.9-31-user-port-hack/net/ipv4/af_inet.c *** linux-2.4.9-31/net/ipv4/af_inet.c Tue Aug 7 16:30:50 2001 --- linux-2.4.9-31-user-port-hack/net/ipv4/af_inet.c Fri Mar 15 16:35:45 2002 *************** *** 528,533 **** --- 528,549 ---- goto out; } + /* + * User port range restrictions + */ + if (current->euid >= sysctl_local_port_range[4] + && sysctl_local_port_range[2] > 0) { + int user_base = sysctl_local_port_range[2] + + (current->euid - sysctl_local_port_range[4]) + * sysctl_local_port_range[3]; + if (snum < user_base + || snum >= user_base + sysctl_local_port_range[3]) { + sk->saddr = sk->rcv_saddr = 0; + err = -EADDRINUSE; + goto out; + } + } + if (sk->rcv_saddr) sk->userlocks |= SOCK_BINDADDR_LOCK; if (snum) diff -cr linux-2.4.9-31/net/ipv4/sysctl_net_ipv4.c linux-2.4.9-31-user-port-hack/net/ipv4/sysctl_net_ipv4.c *** linux-2.4.9-31/net/ipv4/sysctl_net_ipv4.c Tue Feb 26 10:49:57 2002 --- linux-2.4.9-31-user-port-hack/net/ipv4/sysctl_net_ipv4.c Fri Mar 15 16:03:51 2002 *************** *** 47,54 **** #ifdef CONFIG_SYSCTL static int tcp_retr1_max = 255; ! static int ip_local_port_range_min[] = { 1, 1 }; ! static int ip_local_port_range_max[] = { 65535, 65535 }; #endif struct ipv4_config ipv4_config; --- 47,54 ---- #ifdef CONFIG_SYSCTL static int tcp_retr1_max = 255; ! static int ip_local_port_range_min[] = { 1, 1, 0, 0, 0, 0 }; ! static int ip_local_port_range_max[] = { 65535, 65535, 65535, 65535, 65535, 65535}; #endif struct ipv4_config ipv4_config; diff -cr linux-2.4.9-31/net/ipv4/tcp_ipv4.c linux-2.4.9-31-user-port-hack/net/ipv4/tcp_ipv4.c *** linux-2.4.9-31/net/ipv4/tcp_ipv4.c Tue Feb 26 10:50:13 2002 --- linux-2.4.9-31-user-port-hack/net/ipv4/tcp_ipv4.c Fri Mar 15 16:35:12 2002 *************** *** 95,102 **** * This array holds the first and last local port number. * For high-usage systems, use sysctl to change this to * 32768-61000 */ ! int sysctl_local_port_range[2] = { 1024, 4999 }; int tcp_port_rover = (1024 - 1); static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport, --- 95,111 ---- * This array holds the first and last local port number. * For high-usage systems, use sysctl to change this to * 32768-61000 + * + * 0 - bottom of emphemeral port range (unrestricted users) + * 1 - top of emphemeral port range (unrestricted users) + * 2 - start of port range for restricted users (zero to disable this + * functionality) + * 3 - number of ports per user. + * 4 - lowest restricted uid + * 5 - number of ports in each range not be allocated by get_port. */ ! ! int sysctl_local_port_range[6] = { 32768, 61000, 0, 0, 0, 0}; int tcp_port_rover = (1024 - 1); static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport, *************** *** 178,183 **** --- 187,208 ---- int remaining = (high - low) + 1; int rover; + /* + * User port range restrictions + */ + if(sysctl_local_port_range[2] > 0 && + current->euid >= sysctl_local_port_range[4] + ) { + low = sysctl_local_port_range[2] + + (current->euid - sysctl_local_port_range[4]) + * sysctl_local_port_range[3] + + sysctl_local_port_range[5]; + high = low + + sysctl_local_port_range[3] + - sysctl_local_port_range[5]; + } + + spin_lock(&tcp_portalloc_lock); rover = tcp_port_rover; do { rover++; diff -cr linux-2.4.9-31/net/ipv4/udp.c linux-2.4.9-31-user-port-hack/net/ipv4/udp.c *** linux-2.4.9-31/net/ipv4/udp.c Thu Apr 12 20:11:39 2001 --- linux-2.4.9-31-user-port-hack/net/ipv4/udp.c Fri Mar 15 16:12:30 2002 *************** *** 111,116 **** --- 111,133 ---- write_lock_bh(&udp_hash_lock); if (snum == 0) { int best_size_so_far, best, result, i; + int low = sysctl_local_port_range[0]; + int high = sysctl_local_port_range[1]; + + /* + * User port range restrictions + */ + if(sysctl_local_port_range[2] > 0 && + current->euid >= sysctl_local_port_range[4] + ) { + low = sysctl_local_port_range[2] + + (current->euid - sysctl_local_port_range[4]) + * sysctl_local_port_range[3] + + sysctl_local_port_range[5]; + high = low + + sysctl_local_port_range[3] + - sysctl_local_port_range[5]; + } if (udp_port_rover > sysctl_local_port_range[1] || udp_port_rover < sysctl_local_port_range[0]) diff -cr linux-2.4.9-31/net/netsyms.c linux-2.4.9-31-user-port-hack/net/netsyms.c *** linux-2.4.9-31/net/netsyms.c Tue Feb 26 11:45:05 2002 --- linux-2.4.9-31-user-port-hack/net/netsyms.c Fri Mar 15 16:19:08 2002 *************** *** 64,70 **** #include #include ! extern int sysctl_local_port_range[2]; extern int tcp_port_rover; extern int udp_port_rover; #endif --- 64,70 ---- #include #include ! extern int sysctl_local_port_range[6]; extern int tcp_port_rover; extern int udp_port_rover; #endif