COMMAND
vhost
SYSTEMS AFFECTED
Linux (vhost v0.4)
PROBLEM
Solar Designer posted following about simple problem in vhost
v0.4, available at:
ftp://ftp.solucorp.qc.ca/pub/linuxconf/devel/vhost-0.4.tar.gz
Its README says:
For each "nowait" service in /etc/inetd.conf, you "insert"
/usr/sbin/vhost before the command (before /usr/sbin/tcpd
generally). After doing a "killall -HUP inetd", you will be
able to setup virtual hosts. Normal operation won't be
affected.
This is wrong, normal operation IS affected, in such a way that
tcpd is simply not used. This means no connection logging for many
services, and no hosts.allow/hosts.deny access control. However,
the services continue working, so it's possible the admin will not
notice the problem. There're also buffer overflows, and missing
syscall return value checks. If, for some reason, chroot()
succeeds, but chdir() doesn't, then someone might be able to login
with their virtual host password, and then break out of chroot().
SOLUTION
Below is a quick and dirty patch that fixes the above problems.
The real fix would be re-coding, since the whole thing (which is
only 4 Kb of C source) looks quite broken. For example, it updates
password files with no locking, while there can be multiple
connections at a time.
--- vhost.c.orig Wed Aug 20 07:53:39 1997
+++ vhost.c Tue Dec 30 07:40:54 1997
@@ -163,7 +163,7 @@
int main (int argc, char *argv[])
{
- char domain[PATH_MAX];
+ char domain[PATH_MAX - 80];
openlog ("vhost",LOG_PID,LOG_DAEMON);
if (vhost_getourname(domain,sizeof(domain))!=-1
&& vhost_finddomain (domain)!=-1){
@@ -174,14 +174,13 @@
if (file_date(pathetc)!=0){
vhost_setuppasswd (domain);
syslog (LOG_NOTICE,"Changing directory/root to %s",path);
- chdir (path);
- chroot (path);
+ if (chdir (path) || chroot (path)) return 1;
}else{
syslog (LOG_NOTICE,"No /etc directory for vdomain %s: using main domain"
,domain);
}
}
- execv (argv[1],argv+1);
+ execv (argv[0],argv+1);
return 1;
}
Wietse Venema pointed out that TCP Wrappers can do virtual
hosting. Here's a sample /etc/hosts.allow that enables a sample
virtual service:
# hosts.allow
in.telnetd@127.0.0.2 : ALL : twist /bin/echo "Go away"
( set this up just for testing access from localhost.
All you have to do to test this was issue the following commands:
ifconfig lo:1 127.0.0.2 up
telnet 127.0.0.2
This assumes you have the PROCESS_OPTIONS compile time option
defined in TCP Wrappers -- and, of course, you have TCP Wrappers
wrappers installed in inetd.conf.