From owner-freebsd-security Fri Mar 28 01:38:45 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id BAA00154 for security-outgoing; Fri, 28 Mar 1997 01:38:45 -0800 (PST) Received: from scanner.worldgate.com (scanner.worldgate.com [198.161.84.3]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id BAA00149 for ; Fri, 28 Mar 1997 01:38:42 -0800 (PST) Received: from znep.com (uucp@localhost) by scanner.worldgate.com (8.8.5/8.7.3) with UUCP id CAA28556; Fri, 28 Mar 1997 02:38:39 -0700 (MST) Received: from localhost (marcs@localhost) by alive.znep.com (8.7.5/8.7.3) with SMTP id CAA19194; Fri, 28 Mar 1997 02:25:54 -0700 (MST) Date: Fri, 28 Mar 1997 02:25:53 -0700 (MST) From: Marc Slemko To: "Thomas H. Ptacek" cc: freebsd-security@FreeBSD.ORG Subject: Re: Privileged ports... In-Reply-To: <199703271941.NAA23050@enteract.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk On Thu, 27 Mar 1997, Thomas H. Ptacek wrote: > > I agree completely with you. It is a very bad thing. Start with the fact > > that, by default, inetd limits services to being called 256 times a minute > > and then shuts them off and then move on to more devious ways you could > > inetd doesn't release the socket address when it shuts the port off, so I > doubt you'd be able to bind over something inetd's handling. You do have a Yes it does. It close()es the socket. Try it. If it didn't, it would have no nice way of refusing connections other than accepting and rejecting them. $ nc -vv -l -p 1025 retrying local 0.0.0.0:1025 : Address already in use retrying local 0.0.0.0:1025 : Address already in use retrying local 0.0.0.0:1025 : Address already in use retrying local 0.0.0.0:1025 : Address already in use Can't grab 0.0.0.0:1025 with bind $ while true; do nc -z localhost 1025 Mar 28 02:18:45 host inetd[190]: blackjack/tcp server failing (looping), service terminated ^C $ nc -vv -l -p 1025 listening on [any] 1025 ... > potential problem with specific binds (over inetd's INADDR_ANY) in this > configuration, though. Yes. I had thought that this was fixed up, but I guess I was perhaps thinking of Linux. Not sure what solution is in place there, don't follow Linux networking any more. I know I have an archived message from Aleph One around here on the subject from one of the mailing lists around the start of '96. It was discussed on several FreeBSD lists at the time, but I'm not sure anything came of it. If inetd did not set SO_REUSEADDR, it wouldn't be a problem because anyone else would be prevented from binding. However, I don't think that inetd really has much choice. OpenBSD has the following in netinet/in_pcb.c: if (so->so_uid) { t = in_pcblookup(table, zeroin_addr, 0, sin->sin_addr, lport, INPLOOKUP_WILDCARD); if (t && (so->so_uid != t->inp_socket->so_uid)) return (EADDRINUSE); } ...which prevents a process running as a different user from binding to the same port. The other option is to simply disallow multiple processes from binding to the same port entirely, but that is a bit extreme and over restrictive. To emphasize; right now, anyone can steal any connections going to an unprivileged port that inetd listens on, unless you use something like the -a option to inetd. That is bad. I think something resembling the above OpenBSD change is a good idea. Anyone? It is a minor waste to add another in_pcblookup call, but a quick glance shows that it appears to be necessary. > The real problem, as I see it, is that if reserved ports are enough of a > security concern for you that you'd dramatically complicate your inetd > configuration to handle them, you're going to have a real security concern > if inetd dies. I think it's bad to assume that an unprivileged user can't > cause a daemon to die. Yup. All the issues above are simply examples; fixing them would not make it worthwhile setting up inetd to prevent other processes from binding to the port. > > > are set to a particular default but still allow them to be changed) that > > handles setting it then add a few lines of code to the kernel to allow you > > to set the uid who can bind to each priv'd port. There are 1764 other > > things that it would be useful to be able to set in a similar way, > > Why do you want a UID per reserved port? What is this getting you? It lets me run my mailer on port 25 as "mail". It lets me run my web server on port 80 as "www". It lets me run my print spooler on port 515 as "print". It lets me run my cybercash (whatever that is...) on port 551 as "cash". If someone compromises my www user, my web service is compromised but my ever-important cybercash service on port 551 is not. For many of these programs there are legit reasons why it needs root for other things and it is normally not as easy as just allowing a non-root uid to bind to the port, but you have to start somewhere.