Subject: A possible solution to ftpd port 20 binding
To: None <>
From: Todd Vierling <>
List: tech-net
Date: 11/22/2000 01:11:30
From other, separate discussion with simonb about security issues with ftpd
needing to "twiddle" the euid to bind to port 20 (ftp-data), the following
possible solutions came up, which I'm posting here to gather possible

Both methods involve ftpd *permanently* revoking root privileges after
authentication (and possible chroot).  What I'm hoping to gather here are
people shooting holes in the security implications of these possible

1. A process flag, cleared on exec, allowing reserved port binding.

   This would entail somehow setting this privilege flag on the struct proc
   before revoking privileges, but the process could still bind privileged

2. A socket option that creates a duplicate of a bound socket.

   This approach allows ftpd to create its data socket before revoking
   privileges, prebound, but not connected to a remote system.  It could
   have other useful non-security-related applications as well.

   The basic usage in userland would be, in pseudo:

     fd = socket(family, type, proto);
     setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &1, sizeof 1);
     bind(fd, addr_and_port);

     setuid(geteuid()); /* revoke privileges */

     loop {
       int newfd;

       connect(fd, dest_addr_and_port);

       newfd = socket(family, type, proto);
       setsockopt(newfd, SOL_SOCKET, SO_REUSENAME, &fd, sizeof fd);
       shutdown(fd, 2);

       fd = newfd;

   Here, the required port binding is established while the process still
   has privileges, and the binding is duplicated in another socket, which
   is then connected.  A bonus here is that even a connected socket could
   have its binding (name) copied, so ftpd need not have two sockets open
   whenever a transfer is in progress.


-- Todd Vierling <>  *
-- Speed, stability, security, and support.  Wasabi NetBSD:  Run with it.