ctags(1) command execution vulnerability
Peter Pentchev
roam at ringlet.net
Mon May 3 23:33:22 PDT 2004
On Tue, May 04, 2004 at 09:49:09AM +0400, Roman Bogorodskiy wrote:
> Hello,
>
> ctags(1) uses external application sort(1) for sorting the tags file.
> It calls it via system(3) function.
[snip]
> This code will be executed when "-u" arg was given. So, if we'll execute
> ctags in a such way:
>
> 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
--
Peter Pentchev roam at ringlet.net roam at sbnd.net roam at 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
===================================================================
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 dwmalone Exp $");
+#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 *);
int
main(int argc, char **argv)
@@ -118,7 +120,7 @@
dflag++;
break;
case 'f':
- outfile = optarg;
+ outfile = validatename(optarg);
break;
case 't':
tflag = YES;
@@ -201,6 +203,25 @@
exit(1);
}
+static char *
+validatename(const char *fname)
+{
+ char *n, *q;
+ const char *p, *end;
+ size_t len;
+
+ len = strlen(fname);
+ n = malloc(len + 1);
+ if (n == NULL)
+ errx(1, "out of memory");
+ end = n + len;
+ for (p = fname, q = n; *p != '\0' && q != end; p++)
+ if (isalnum(*p) || strchr("-_./", *p) != NULL)
+ *q++ = *p;
+ *q = '\0';
+ return (n);
+}
+
/*
* init --
* this routine sets up the boolean pseudo-functions which work by
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-security/attachments/20040504/6c3d5a0c/attachment.bin
More information about the freebsd-security
mailing list