Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 May 2004 09:33:16 +0300
From:      Peter Pentchev <roam@ringlet.net>
To:        freebsd-security@freebsd.org
Subject:   Re: ctags(1) command execution vulnerability
Message-ID:  <20040504063316.GM971@straylight.m.ringlet.net>
In-Reply-To: <20040504054909.GA3119@lame.novel.ru>
References:  <20040504054909.GA3119@lame.novel.ru>

next in thread | previous in thread | raw e-mail | index | archive | help

--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 <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/usr.bin/ctags/ctags.c,v 1.18 2002/07/28 15:50:38 d=
wmalone Exp $");
=20
+#include <ctype.h>
 #include <err.h>
 #include <limits.h>
 #include <locale.h>
@@ -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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040504063316.GM971>