From owner-freebsd-security@FreeBSD.ORG Mon May 3 23:33:22 2004 Return-Path: Delivered-To: freebsd-security@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id ECD1916A4CE for ; Mon, 3 May 2004 23:33:21 -0700 (PDT) Received: from gandalf.online.bg (gandalf.online.bg [217.75.128.9]) by mx1.FreeBSD.org (Postfix) with SMTP id F3F2D43D1D for ; Mon, 3 May 2004 23:33:19 -0700 (PDT) (envelope-from roam@ringlet.net) Received: (qmail 31945 invoked from network); 4 May 2004 06:25:55 -0000 Received: from office.sbnd.net (HELO straylight.m.ringlet.net) (217.75.140.130) by gandalf.online.bg with SMTP; 4 May 2004 06:25:54 -0000 Received: (qmail 71235 invoked by uid 1000); 4 May 2004 06:33:16 -0000 Date: Tue, 4 May 2004 09:33:16 +0300 From: Peter Pentchev To: freebsd-security@freebsd.org Message-ID: <20040504063316.GM971@straylight.m.ringlet.net> Mail-Followup-To: freebsd-security@freebsd.org References: <20040504054909.GA3119@lame.novel.ru> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="3607uds81ZQvwCD0" Content-Disposition: inline In-Reply-To: <20040504054909.GA3119@lame.novel.ru> User-Agent: Mutt/1.5.6i Subject: Re: ctags(1) command execution vulnerability X-BeenThere: freebsd-security@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Security issues [members-only posting] List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 May 2004 06:33:22 -0000 --3607uds81ZQvwCD0 Content-Type: text/plain; charset=windows-1251 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 04, 2004 at 09:49:09AM +0400, Roman Bogorodskiy wrote: > Hello, >=20 > ctags(1) uses external application sort(1) for sorting the tags file. > It calls it via system(3) function.=20 [snip] > This code will be executed when "-u" arg was given. So, if we'll execute= =20 > ctags in a such way: >=20 > ctags -u -f ';echo hi' *.c [snip] > - "mv %s OTAGS; fgrep -v '\t%s\t' OTAGS >%s; rm OTAGS", > + "mv '%s' OTAGS; fgrep -v '\t%s\t' OTAGS >'%s'; rm OTAGS", [snip] > - (void)asprintf(&cmd, "sort -o %s %s", > + (void)asprintf(&cmd, "sort -o '%s' '%s'", Unfortunately, this is still not a complete solution; the following still works, at least for me: ctags -u -f "'; echo hi; '" *.c Filtering the filename characters would be a better idea; possibly something like the attached patch. G'luck, Peter --=20 Peter Pentchev roam@ringlet.net roam@sbnd.net roam@FreeBSD.org PGP key: http://people.FreeBSD.org/~roam/roam.key.asc Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553 This sentence contradicts itself - or rather - well, no, actually it doesn'= t! Index: src/usr.bin/ctags/ctags.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/usr.bin/ctags/ctags.c,v retrieving revision 1.18 diff -u -r1.18 ctags.c --- src/usr.bin/ctags/ctags.c 28 Jul 2002 15:50:38 -0000 1.18 +++ src/usr.bin/ctags/ctags.c 4 May 2004 06:27:23 -0000 @@ -46,6 +46,7 @@ #include __FBSDID("$FreeBSD: src/usr.bin/ctags/ctags.c,v 1.18 2002/07/28 15:50:38 d= wmalone Exp $"); =20 +#include #include #include #include @@ -84,6 +85,7 @@ void init(void); void find_entries(char *); static void usage(void); +static char *validatename(const char *); =20 int main(int argc, char **argv) @@ -118,7 +120,7 @@ dflag++; break; case 'f': - outfile =3D optarg; + outfile =3D validatename(optarg); break; case 't': tflag =3D YES; @@ -201,6 +203,25 @@ exit(1); } =20 +static char * +validatename(const char *fname) +{ + char *n, *q; + const char *p, *end; + size_t len; + + len =3D strlen(fname); + n =3D malloc(len + 1); + if (n =3D=3D NULL) + errx(1, "out of memory"); + end =3D n + len; + for (p =3D fname, q =3D n; *p !=3D '\0' && q !=3D end; p++) + if (isalnum(*p) || strchr("-_./", *p) !=3D NULL) + *q++ =3D *p; + *q =3D '\0'; + return (n); +} + /* * init -- * this routine sets up the boolean pseudo-functions which work by --3607uds81ZQvwCD0 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (FreeBSD) iD8DBQFAlzks7Ri2jRYZRVMRAgQ4AJ9LEE0VNee8HhLbHAsbYYhr7+potgCfU48a U3Zm3CwU67Chz1MsWVZMglM= =RRar -----END PGP SIGNATURE----- --3607uds81ZQvwCD0--