From owner-freebsd-ports-bugs@FreeBSD.ORG Wed Aug 18 15:20:27 2004 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DB94016A4CE for ; Wed, 18 Aug 2004 15:20:26 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id BCE3C43D31 for ; Wed, 18 Aug 2004 15:20:26 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i7IFKQvj031558 for ; Wed, 18 Aug 2004 15:20:26 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i7IFKQiO031557; Wed, 18 Aug 2004 15:20:26 GMT (envelope-from gnats) Resent-Date: Wed, 18 Aug 2004 15:20:26 GMT Resent-Message-Id: <200408181520.i7IFKQiO031557@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Rudolf Polzer Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5078B16A4CE for ; Wed, 18 Aug 2004 15:13:27 +0000 (GMT) Received: from ccc-offenbach.org (pD9EA63EB.dip.t-dialin.net [217.234.99.235]) by mx1.FreeBSD.org (Postfix) with SMTP id 3C09443D58 for ; Wed, 18 Aug 2004 15:13:25 +0000 (GMT) (envelope-from rpolzer@durchnull.ath.cx) Received: (qmail 64322 invoked by uid 1000); 18 Aug 2004 15:13:22 -0000 Message-Id: <20040818151322.64321.qmail@durchnull.ath.cx> Date: 18 Aug 2004 15:13:22 -0000 From: Rudolf Polzer To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: mhatta@debian.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 X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Aug 2004 15:20:27 -0000 >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: