Date: Wed, 8 Jan 1997 15:10:55 -0800 (PST) From: Steve Reid <steve@edmweb.com> To: freebsd-isp@freebsd.org Subject: Re: serious security bug in wu-ftpd v2.4 (fwd) Message-ID: <Pine.BSF.3.95.970108150849.256B-100000@bitbucket.edmweb.com>
next in thread | raw e-mail | index | archive | help
Since David Greenman's patch was posted here, I figure this should be posted here as well... ---------- Forwarded message ---------- Date: Tue, 7 Jan 1997 23:02:51 -0500 (EST) From: Wietse Venema <wietse@porcupine.org> Reply-To: best-of-security@suburbia.net To: best-of-security@suburbia.net Cc: wu-ftpd-bugs@academ.com, best-of-security@suburbia.net Subject: BoS: serious security bug in wu-ftpd v2.4 Resent-Date: Wed, 8 Jan 1997 18:44:21 +1100 (EST) Resent-From: best-of-security@suburbia.net Two brief comments on the patches that were suggested sofar. - The patch proposed by David Greenman (clear the transflag variable in function dologout()) makes the window of opportunity much smaller, but does not close it. The hole still exists. It's just smaller. - The patch posted by Dave Kinchlea ignores signals entirely and thus may cause loss of information. It is system-call intensive. This is the same approach that I took for an initial fix in my logdaemon utilities. Here is an alternative solution that delays signal delivery without ignoring signals. It minimizes system calls (one syscall to delay all signals, and one to undo the delay). Tested on: BSD/OS 2.1, SunOS 5.5, SunOS 4.1.3_U1, FreeBSD 2.1.5, IRIX 5.3, and HP-UX 9.5. I wonder what UNIX ftpd implementations did NOT have this hole. Wietse /* * delay_signaling(), enable_signaling - delay signal delivery for a while * * Author: Wietse Venema */ #include <sys/types.h> #include <sys/signal.h> #include <syslog.h> static sigset_t saved_sigmask; static sigset_t block_sigmask; static int delaying; static int init_done; /* init_mask - compute signal mask only once */ static void init_mask() { int sig; init_done = 1; sigemptyset(&block_sigmask); for (sig = 1; sig < NSIG; sig++) sigaddset(&block_sigmask, sig); } /* enable_signaling - deliver delayed signals and disable signal delay */ int enable_signaling() { if (delaying != 0) { delaying = 0; if (sigprocmask(SIG_SETMASK, &saved_sigmask, (sigset_t *) 0) < 0) { syslog(LOG_ERR, "sigprocmask: %m"); return (-1); } } return (0); } /* delay_signaling - save signal mask and block all signals */ int delay_signaling() { if (init_done == 0) init_mask(); if (delaying == 0) { delaying = 1; if (sigprocmask(SIG_BLOCK, &block_sigmask, &saved_sigmask) < 0) { syslog(LOG_ERR, "sigprocmask: %m"); return (-1); } } return (0); } #ifdef TEST #include <stdio.h> void gotsig(sig) int sig; { printf("Got signal %d\n", sig); } main(argc, argv) int argc; char **argv; { signal(SIGINT, gotsig); signal(SIGQUIT, gotsig); delay_signaling(); sleep(5); enable_signaling(); exit(0); } #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.970108150849.256B-100000>