From owner-freebsd-audit Mon Oct 28 20: 6:20 2002 Delivered-To: freebsd-audit@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 73E8837B401 for ; Mon, 28 Oct 2002 20:06:18 -0800 (PST) Received: from chiark.greenend.org.uk (chiark.greenend.org.uk [193.201.200.170]) by mx1.FreeBSD.org (Postfix) with ESMTP id BA3BD43E3B for ; Mon, 28 Oct 2002 20:06:17 -0800 (PST) (envelope-from fanf@chiark.greenend.org.uk) Received: from fanf by chiark.greenend.org.uk with local (Exim 3.12 #1) id 186Ndw-0001PD-00 (Debian); Tue, 29 Oct 2002 04:06:16 +0000 Date: Tue, 29 Oct 2002 04:06:16 +0000 From: Tony Finch To: freebsd-audit@freebsd.org Cc: dot@dotat.at Subject: uudecode paranoia Message-ID: <20021029040616.A3802@chiark.greenend.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Following on from http://www.kb.cert.org/vuls/id/336083 here is a candidate patch to make FreeBSD's uudecode paranoid about less-trusted filenames. Comments and suggestions are welcome, especially regarding the evil freopen hack. Tony. -- f.a.n.finch http://dotat.at/ WEST SOLE: SOUTHERLY VEERING NORTHEASTERLY 5 TO 7. RAIN THEN SHOWERS. MODERATE BECOMING GOOD. --- uudecode.c 11 Sep 2002 04:26:09 -0000 1.40 +++ uudecode.c 29 Oct 2002 04:01:06 -0000 @@ -59,6 +59,8 @@ #include #include +#include +#include #include #include #include @@ -152,7 +154,7 @@ int decode2(void) { - int base64, i; + int base64, i, flags; size_t n; char ch, *p, *q; void *mode; @@ -228,13 +230,42 @@ } if (!pflag) { - if (iflag && !access(buffn, F_OK)) { - warnx("not overwritten: %s", buffn); - return (0); + flags = O_WRONLY|O_CREAT|O_EXCL; + if (lstat(buffn, &st) == 0) { + if (iflag) { + warnc(EEXIST, "%s: %s", filename, buffn); + return (0); + } + switch (st.st_mode & S_IFMT) { + case S_IFREG: + case S_IFLNK: + /* avoid symlink attacks */ + if (unlink(buffn) == 0 || errno == ENOENT) + break; + warn("%s: unlink %s", filename, buffn); + return (1); + case S_IFDIR: + warnc(EISDIR, "%s: %s", filename, buffn); + return (1); + default: + if (oflag) { + /* trust command-line names */ + flags &= ~O_EXCL; + break; + } + warnc(EEXIST, "%s: %s", filename, buffn); + return (1); + } + } else if (errno != ENOENT) { + warn("%s: %s", filename, buffn); + return (1); } - if (freopen(buffn, "w", stdout) == NULL || - stat(buffn, &st) < 0 || (S_ISREG(st.st_mode) && - fchmod(fileno(stdout), getmode(mode, 0) & 0666) < 0)) { + if (fclose(stdout) != 0) + warn("problem writing output"); + /* Bah! there is no fdreopen or O_EXCL flag for fopen */ + i = open(buffn, flags, getmode(mode, 0) & 0666); + if (i < 0 || dup2(i, 1) < 0 || + freopen("/dev/stdout", "w", stdout) == NULL) { warn("%s: %s", filename, buffn); return (1); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message