Skip site navigation (1)Skip section navigation (2)
Date:      18 Aug 2004 15:13:22 -0000
From:      Rudolf Polzer <freebsd-dr@durchnull.de>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        bug-a2ps@gnu.org
Subject:   ports/70618: print/a2ps-* using "file -L %s" as shell argument --> dangerous to use it in world-writable directories
Message-ID:  <20040818151322.64321.qmail@durchnull.ath.cx>
Resent-Message-ID: <200408181520.i7IFKQiO031557@freefall.freebsd.org>

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

>Number:         70618
>Category:       ports
>Synopsis:       print/a2ps-* using "file -L %s" as shell argument --> dangerous to use it in world-writable directories
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 18 15:20:26 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Rudolf Polzer
>Release:        FreeBSD 5.2.1-RELEASE-p9 i386
>Organization:
>Environment:
System: FreeBSD katsuragi.durchnull.ath.cx 5.2.1-RELEASE-p9 FreeBSD 5.2.1-RELEASE-p9 #19: Thu Jul 1 11:20:21 CEST 2004 root@katsuragi.durchnull.ath.cx:/usr/src/sys/i386/compile/DIV0_KERNEL i386


>Description:
a2ps builds a command line for file() containing an unescaped version of
the file name, thus might call external programs described by the file name.
Running a cronjob over a public writable directory a2ps-ing all files in it
- or simply typing "a2ps *.txt" in /tmp - is therefore dangerous.

>How-To-Repeat:
rpolzer:/tmp 7> touch 'x`echo>&2 42`'                                      
rpolzer:/tmp 8> a2ps -o /dev/null 'x`echo>&2 42`'
42
[x`echo>&2 42` (plain): 0 pages on 0 sheets]
[Total: 0 pages on 0 sheets] saved into the file `/dev/null'

>Fix:
Apply this patch (can be directly put into files/):

diff -ru ../a2ps-4.13.orig/src/select.c ./src/select.c
--- ../a2ps-4.13.orig/src/select.c	Wed Aug 18 16:32:09 2004
+++ ./src/select.c	Wed Aug 18 16:49:12 2004
@@ -131,6 +131,36 @@
   return 1;
 }
 
+/* escapes the name of a file so that the shell groks it in 'single' q.marks. 
+   The resulting pointer has to be free()ed when not longer used. */
+char *
+shell_escape(const char *fn)
+{
+  size_t len = 0;
+  const char *inp;
+  char *retval, *outp;
+
+  for(inp = fn; *inp; ++inp)
+    switch(*inp)
+    {
+      case '\'': len += 4; break;
+      default:   len += 1; break;
+    }
+
+  outp = retval = malloc(len + 1);
+  if(!outp)
+    return ""; /* perhaps one should do better error handling here */
+  for(inp = fn; *inp; ++inp)
+    switch(*inp)
+    {
+      case '\'': *outp++ = '\''; *outp++ = '\\'; *outp++ = '\'', *outp++ = '\''; break;
+      default:   *outp++ = *inp; break;
+    }
+  *outp = 0;
+
+  return retval;
+}
+
 /* What says file about the type of a file (result is malloc'd).  NULL
   if could not be run.  */
 
@@ -144,11 +174,13 @@
   if (IS_EMPTY (job->file_command))
     return NULL;
 
+  filename = shell_escape(filename);
   /* Call file(1) with the correct option */
-  command = ALLOCA (char, (2
+  command = ALLOCA (char, (4
 			   + strlen (job->file_command)
 			   + ustrlen (filename)));
-  sprintf (command, "%s %s", job->file_command, (const char *) filename);
+  sprintf (command, "%s '%s'", job->file_command, (const char *) filename);
+  free(filename);
   message (msg_tool, (stderr, "Reading pipe: `%s'\n", command));
   file_out = popen (command, "r");
 
>Release-Note:
>Audit-Trail:
>Unformatted:



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