Default: Empty
 
+ip_unprivileged_port_start - INTEGER
+       This is a per-namespace sysctl.  It defines the first
+       unprivileged port in the network namespace.  Privileged ports
+       require root or CAP_NET_BIND_SERVICE in order to bind to them.
+       To disable all privileged ports, set this to 0.  It may not
+       overlap with the ip_local_reserved_ports range.
+
+       Default: 1024
+
 ip_nonlocal_bind - BOOLEAN
        If set, allows processes to bind() to non-local IP addresses,
        which can be quite useful - but may break some applications.
 
        return strcmp(name, "default") != 0  && strcmp(name, "all") != 0;
 }
 
+static inline int inet_prot_sock(struct net *net)
+{
+       return net->ipv4.sysctl_ip_prot_sock;
+}
+
 #else
 static inline int inet_is_local_reserved_port(struct net *net, int port)
 {
        return 0;
 }
+
+static inline int inet_prot_sock(struct net *net)
+{
+       return PROT_SOCK;
+}
 #endif
 
 __be32 inet_current_timestamp(void);
 
 
 #ifdef CONFIG_SYSCTL
        unsigned long *sysctl_local_reserved_ports;
+       int sysctl_ip_prot_sock;
 #endif
 
 #ifdef CONFIG_IP_MROUTE
 
 
        snum = ntohs(addr->sin_port);
        err = -EACCES;
-       if (snum && snum < PROT_SOCK &&
+       if (snum && snum < inet_prot_sock(net) &&
            !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
                goto out;
 
        net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
        net->ipv4.sysctl_ip_dynaddr = 0;
        net->ipv4.sysctl_ip_early_demux = 1;
+#ifdef CONFIG_SYSCTL
+       net->ipv4.sysctl_ip_prot_sock = PROT_SOCK;
+#endif
 
        return 0;
 }
 
 static int ip_local_port_range_max[] = { 65535, 65535 };
 static int tcp_adv_win_scale_min = -31;
 static int tcp_adv_win_scale_max = 31;
+static int ip_privileged_port_min;
+static int ip_privileged_port_max = 65535;
 static int ip_ttl_min = 1;
 static int ip_ttl_max = 255;
 static int tcp_syn_retries_min = 1;
        ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
 
        if (write && ret == 0) {
-               if (range[1] < range[0])
+               /* Ensure that the upper limit is not smaller than the lower,
+                * and that the lower does not encroach upon the privileged
+                * port limit.
+                */
+               if ((range[1] < range[0]) ||
+                   (range[0] < net->ipv4.sysctl_ip_prot_sock))
                        ret = -EINVAL;
                else
                        set_local_port_range(net, range);
        return ret;
 }
 
+/* Validate changes from /proc interface. */
+static int ipv4_privileged_ports(struct ctl_table *table, int write,
+                               void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       struct net *net = container_of(table->data, struct net,
+           ipv4.sysctl_ip_prot_sock);
+       int ret;
+       int pports;
+       int range[2];
+       struct ctl_table tmp = {
+               .data = &pports,
+               .maxlen = sizeof(pports),
+               .mode = table->mode,
+               .extra1 = &ip_privileged_port_min,
+               .extra2 = &ip_privileged_port_max,
+       };
+
+       pports = net->ipv4.sysctl_ip_prot_sock;
+
+       ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+
+       if (write && ret == 0) {
+               inet_get_local_port_range(net, &range[0], &range[1]);
+               /* Ensure that the local port range doesn't overlap with the
+                * privileged port range.
+                */
+               if (range[0] < pports)
+                       ret = -EINVAL;
+               else
+                       net->ipv4.sysctl_ip_prot_sock = pports;
+       }
+
+       return ret;
+}
 
 static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
 {
                .extra2         = &one,
        },
 #endif
+       {
+               .procname       = "ip_unprivileged_port_start",
+               .maxlen         = sizeof(int),
+               .data           = &init_net.ipv4.sysctl_ip_prot_sock,
+               .mode           = 0644,
+               .proc_handler   = ipv4_privileged_ports,
+       },
        { }
 };
 
 
                return -EINVAL;
 
        snum = ntohs(addr->sin6_port);
-       if (snum && snum < PROT_SOCK && !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
+       if (snum && snum < inet_prot_sock(net) &&
+           !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
                return -EACCES;
 
        lock_sock(sk);
 
         */
        svc = __ip_vs_service_find(ipvs, af, protocol, vaddr, vport);
 
-       if (svc == NULL
-           && protocol == IPPROTO_TCP
-           && atomic_read(&ipvs->ftpsvc_counter)
-           && (vport == FTPDATA || ntohs(vport) >= PROT_SOCK)) {
+       if (!svc && protocol == IPPROTO_TCP &&
+           atomic_read(&ipvs->ftpsvc_counter) &&
+           (vport == FTPDATA || ntohs(vport) >= inet_prot_sock(ipvs->net))) {
                /*
                 * Check if ftp service entry exists, the packet
                 * might belong to FTP data connections.
 
                }
        }
 
-       if (snum && snum < PROT_SOCK &&
+       if (snum && snum < inet_prot_sock(net) &&
            !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
                return -EACCES;
 
                                 * accept new associations, but it SHOULD NOT
                                 * be permitted to open new associations.
                                 */
-                               if (ep->base.bind_addr.port < PROT_SOCK &&
-                                   !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
+                               if (ep->base.bind_addr.port <
+                                   inet_prot_sock(net) &&
+                                   !ns_capable(net->user_ns,
+                                   CAP_NET_BIND_SERVICE)) {
                                        err = -EACCES;
                                        goto out_free;
                                }
                         * but it SHOULD NOT be permitted to open new
                         * associations.
                         */
-                       if (ep->base.bind_addr.port < PROT_SOCK &&
+                       if (ep->base.bind_addr.port < inet_prot_sock(net) &&
                            !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
                                err = -EACCES;
                                goto out_unlock;
 
 
                        inet_get_local_port_range(sock_net(sk), &low, &high);
 
-                       if (snum < max(PROT_SOCK, low) || snum > high) {
+                       if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
+                           snum > high) {
                                err = sel_netport_sid(sk->sk_protocol,
                                                      snum, &sid);
                                if (err)