From nobody@FreeBSD.org  Fri Jan 25 09:24:23 2002
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 725D137B404
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 25 Jan 2002 09:24:22 -0800 (PST)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.6/8.11.6) id g0PHOMW73157;
	Fri, 25 Jan 2002 09:24:22 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200201251724.g0PHOMW73157@freefall.freebsd.org>
Date: Fri, 25 Jan 2002 09:24:22 -0800 (PST)
From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
To: freebsd-gnats-submit@FreeBSD.org
Subject: man -k could be used to execute any command.
X-Send-Pr-Version: www-1.0

>Number:         34270
>Category:       bin
>Synopsis:       man(1) -k could be used to execute any command.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jan 25 09:30:00 PST 2002
>Closed-Date:    Sat Jul 28 20:03:26 UTC 2012
>Last-Modified:  Sat Jul 28 20:03:26 UTC 2012
>Originator:     Hironori SAKAMOTO
>Release:        
>Organization:
>Environment:
>Description:
"man -k" could be used to execute any command.

For example:
  $ man -k 'echo "; ls"'
  executes "ls"

I could not investigate how dangerous this behavior is.
At least, when web-CGI uses "man -k" with query string,
even if the string is quoted for /bin/sh, any command
could be executed.

>How-To-Repeat:
$ export PAGER=cat
$ ls
a       b
$ man -k 'echo "; ls"'
echo(1)                  - write arguments to the standard output
a       b

>Fix:
In do_apropos() in man/man.c, apropos name is only quoted with `"'.

  sprintf (command, "%s \"%s\"", APROPOS, name);

Any special characters for /bin/sh should be escaped with `\'.

>Release-Note:
>Audit-Trail:

From: Mike Makonnen <mike_makonnen@yahoo.com>
To: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Fri, 25 Jan 2002 11:02:14 -0800

 > >Fix:
 > In do_apropos() in man/man.c, apropos name is only quoted with `"'.
 > 
 >   sprintf (command, "%s \"%s\"", APROPOS, name);
 > 
 > Any special characters for /bin/sh should be escaped with `\'.
 
 I think the command should be single quoted instead of double quoted.
 
 Index: gnu/usr.bin/man/man/man.c
 ===================================================================
 RCS file: /home/ncvs/src/gnu/usr.bin/man/man/man.c,v
 retrieving revision 1.53
 diff -u -r1.53 man.c
 --- gnu/usr.bin/man/man/man.c	22 Jan 2002 15:15:38 -0000	1.53
 +++ gnu/usr.bin/man/man/man.c	25 Jan 2002 18:50:49 -0000
 @@ -533,7 +533,7 @@
    if ((command = (char *) malloc(len)) == NULL)
      gripe_alloc (len, "command");
  
 -  sprintf (command, "%s \"%s\"", APROPOS, name);
 +  sprintf (command, "%s \'%s\'", APROPOS, name);
  
    (void) do_system_command (command);
  
 
 cheers,
 mike makonnen

From: Giorgos Keramidas <keramida@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/34270: man -k could be used to execute any command. (fwd)
Date: Fri, 25 Jan 2002 23:29:04 +0200 (EET)

 Mike Makonnen wrote:
 
 >  > >Fix:
 >  > In do_apropos() in man/man.c, apropos name is only quoted with `"'.
 >  >
 >  >   sprintf (command, "%s \"%s\"", APROPOS, name);
 >  >
 >  > Any special characters for /bin/sh should be escaped with `\'.
 >
 >  I think the command should be single quoted instead of double quoted.
 
     $ pwd
     /c/0/gnu/usr.bin/man/man
     $ ./man -k "echo '; ls'"
     ng_echo(4)               - netgraph echo node type
     CVS             man             man.man         version.h
     Makefile        man.1           man.o
     glob.c          man.1.gz        manpath.o
     glob.o          man.c           ndir.h
 
 Other combinations of man -k arguments can cause all sorts of weird errors:
 
     $ ./man -k "echo \\'; ls\\'"
     Syntax error: Unterminated quoted string
     Error executing formatting or display command.
     system command exited with status 512
 
 -- 
 Giorgos Keramidas . . . . . . . . . keramida@{ceid.upatras.gr,freebsd.org}
 FreeBSD Documentation Project . . . http://www.freebsd.org/docproj/
 FreeBSD: The power to serve . . . . http://www.freebsd.org/
 

From: Giorgos Keramidas <keramida@freebsd.org>
To: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
Cc: bug-followup@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 00:39:11 +0200 (EET)

   This message is in MIME format.  The first part should be readable text,
   while the remaining parts are likely unreadable without MIME-aware tools.
   Send mail to mime@docserver.cac.washington.edu for more info.
 
 --0-1465720898-1011998351=:10216
 Content-Type: TEXT/PLAIN; charset=US-ASCII
 
 
 Hello Hironori,
 
 Can you try the attached patch?
 It seems to work for me.
 
 I changed the quotes used by system() to quote the command to double
 quotes, and escape all double quotes in the shell command executed by
 system() with a backslash.
 
 	$ ./man -k lala
 	lala: nothing appropriate
 	$ ./man -k lala\'
 	lala': nothing appropriate
 	$ ./man -k lala\"
 	lala": nothing appropriate
 
 -- 
 Giorgos Keramidas . . . . . . . . . keramida@{ceid.upatras.gr,freebsd.org}
 FreeBSD Documentation Project . . . http://www.freebsd.org/docproj/
 FreeBSD: The power to serve . . . . http://www.freebsd.org/
 
 --0-1465720898-1011998351=:10216
 Content-Type: TEXT/PLAIN; charset=US-ASCII; name="man.diff"
 Content-Transfer-Encoding: BASE64
 Content-ID: <20020126003911.C10216@hades>
 Content-Description: gnu/usr.bin/man patch
 Content-Disposition: attachment; filename="man.diff"
 
 SW5kZXg6IGdudS91c3IuYmluL21hbi9tYW4vbWFuLmMNCj09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT0NClJDUyBmaWxlOiAvaG9tZS9uY3ZzL3NyYy9nbnUvdXNy
 LmJpbi9tYW4vbWFuL21hbi5jLHYNCnJldHJpZXZpbmcgcmV2aXNpb24gMS41
 Mw0KZGlmZiAtMiAtdSAtcjEuNTMgbWFuLmMNCi0tLSBnbnUvdXNyLmJpbi9t
 YW4vbWFuL21hbi5jCTIyIEphbiAyMDAyIDE1OjE1OjM4IC0wMDAwCTEuNTMN
 CisrKyBnbnUvdXNyLmJpbi9tYW4vbWFuL21hbi5jCTI1IEphbiAyMDAyIDIy
 OjM0OjM4IC0wMDAwDQpAQCAtNTIwLDQgKzUyMCw1NCBAQA0KIA0KIC8qDQor
 ICogQ291bnQgdGhlIG51bWJlciBvZiBkb3VibGUgcXVvdGUgY2hhcmFjdGVy
 cyBpbiBgc3RyaW5nJy4NCisgKi8NCitpbnQNCitjb3VudF9xdW90ZXMgKHN0
 cmluZykNCisgICAgIGNoYXIgKnN0cmluZzsNCit7DQorICBjaGFyICpwOw0K
 KyAgaW50IGNvdW50Ow0KKyAgY2hhciBjaCA9ICciJzsNCisNCisgIGlmIChz
 dHJpbmcgPT0gTlVMTCkNCisgICAgcmV0dXJuIC0xOw0KKw0KKyAgcCA9IHN0
 cmluZzsNCisgIGNvdW50ID0gMDsNCisgIHdoaWxlICgocCA9IHN0cmNocihw
 LCBjaCkpICE9IE5VTEwpIHsNCisgICAgY291bnQrKzsNCisgICAgcCsrOw0K
 KyAgfQ0KKw0KKyAgcmV0dXJuIGNvdW50Ow0KK30NCisNCisvKg0KKyAqIENv
 cHkgYHNyYycgdG8gYGRzdCcgZXNjYXBpbmcgYWxsIGRvdWJsZSBxdW90ZXMg
 d2l0aCBhIGJhY2tzbGFzaC4NCisgKi8NCitjaGFyICoNCitlc2NhcGVfcXVv
 dGVzIChzcmMpDQorICAgICAgY2hhciAqc3JjOw0KK3sNCisgIGNoYXIgKmRz
 dDsNCisgIGludCBsZW47DQorICBpbnQgaiwgazsNCisNCisgIGxlbiA9IHN0
 cmxlbiAoc3JjKSArIGNvdW50X3F1b3RlcyAoc3JjKSArIDE7DQorICBpZiAo
 KGRzdCA9IChjaGFyICopIG1hbGxvYyAobGVuKSkgPT0gTlVMTCkNCisgICAg
 Z3JpcGVfYWxsb2MgKGxlbiwgImRzdCIpOw0KKw0KKyAgZm9yIChqID0gayA9
 IDA7IGogPD0gc3RybGVuIChzcmMpOyBqKyssIGsrKykgew0KKyAgICBpZiAo
 c3JjW2pdID09ICciJykgew0KKyAgICAgIGRzdFtrXSA9ICdcXCc7DQorICAg
 ICAgaysrOw0KKyAgICB9DQorICAgIGRzdFtrXSA9IHNyY1tqXTsNCisgIH0N
 CisNCisgIHJldHVybiBkc3Q7DQorfQ0KKw0KKy8qDQogICogSGFuZGxlIHRo
 ZSBhcHJvcG9zIG9wdGlvbi4gIENoZWF0IGJ5IHVzaW5nIGFub3RoZXIgcHJv
 Z3JhbS4NCiAgKi8NCkBAIC01MjgsMTEgKzU3OCwxNiBAQA0KICAgcmVnaXN0
 ZXIgaW50IGxlbjsNCiAgIHJlZ2lzdGVyIGNoYXIgKmNvbW1hbmQ7DQorICBj
 aGFyICpzOw0KKw0KKyAgaWYgKChzID0gZXNjYXBlX3F1b3RlcyhuYW1lKSkg
 PT0gTlVMTCkNCisgICAgcmV0dXJuOw0KIA0KLSAgbGVuID0gc3RybGVuIChB
 UFJPUE9TKSArIHN0cmxlbiAobmFtZSkgKyA0Ow0KKyAgbGVuID0gc3RybGVu
 IChBUFJPUE9TKSArIHN0cmxlbiAocykgKyA0Ow0KIA0KICAgaWYgKChjb21t
 YW5kID0gKGNoYXIgKikgbWFsbG9jKGxlbikpID09IE5VTEwpDQogICAgIGdy
 aXBlX2FsbG9jIChsZW4sICJjb21tYW5kIik7DQogDQotICBzcHJpbnRmIChj
 b21tYW5kLCAiJXMgXCIlc1wiIiwgQVBST1BPUywgbmFtZSk7DQorICBzcHJp
 bnRmIChjb21tYW5kLCAiJXMgXCIlc1wiIiwgQVBST1BPUywgcyk7DQorICBm
 cmVlIChzKTsNCiANCiAgICh2b2lkKSBkb19zeXN0ZW1fY29tbWFuZCAoY29t
 bWFuZCk7DQo=
 --0-1465720898-1011998351=:10216--

From: Giorgos Keramidas <keramida@freebsd.org>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 00:47:03 +0200

 On 2002-01-25 14:40:01, Giorgos Keramidas wrote:
 >  Can you try the attached patch?
 >  It seems to work for me.
 
 Although now that I think of it, all shell-metacharacters should be
 escaped in the system() string :-(
 
 -- 
 Giorgos Keramidas . . . . . . . . . keramida@{ceid.upatras.gr,freebsd.org}
 FreeBSD Documentation Project . . . http://www.freebsd.org/docproj/
 FreeBSD: The power to serve . . . . http://www.freebsd.org/

From: hsaka@mth.biglobe.ne.jp (Hironori Sakamoto)
To: freebsd-gnats-submit@freebsd.org
Cc: hsaka@mth.biglobe.ne.jp, mike_makonnen@yahoo.com
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 11:20:49 +0900 (JST)

 Hello,
 
 > From: Mike Makonnen <mike_makonnen@yahoo.com>
 > > >Fix:
 > > In do_apropos() in man/man.c, apropos name is only quoted with `"'.
 > >   sprintf (command, "%s \"%s\"", APROPOS, name);
 > > Any special characters for /bin/sh should be escaped with `\'.
 > I think the command should be single quoted instead of double quoted.
 > -  sprintf (command, "%s \"%s\"", APROPOS, name);
 > +  sprintf (command, "%s \'%s\'", APROPOS, name);
 
 No! It has the same problem.
 
 $ man -k "echo '; ls'"
 -------------------------------------------
 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
  http://www2u.biglobe.ne.jp/~hsaka/

From: hsaka@mth.biglobe.ne.jp (Hironori Sakamoto)
To: keramida@freebsd.org
Cc: bug-followup@freebsd.org, hsaka@mth.biglobe.ne.jp
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 11:20:50 +0900 (JST)

 Hello, 
 
 > From: Giorgos Keramidas <keramida@freebsd.org>
 > I changed the quotes used by system() to quote the command to double
 > quotes, and escape all double quotes in the shell command executed by
 > system() with a backslash.
 
 At least, '$', '`' and '\' should be quoted.
 
 I propose that all symbols and spaces (at lease, speical characters 
 of /bin/sh) are quoted with '\' and the shell command is executed
 by system() without single/double quotes.
 
 Thank you,
 -------------------------------------------
 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
  http://www2u.biglobe.ne.jp/~hsaka/

From: "Crist J. Clark" <cjc@FreeBSD.ORG>
To: Giorgos Keramidas <keramida@FreeBSD.ORG>
Cc: bug-followup@FreeBSD.ORG
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Fri, 25 Jan 2002 18:23:17 -0800

 On Fri, Jan 25, 2002 at 02:50:01PM -0800, Giorgos Keramidas wrote:
 > The following reply was made to PR misc/34270; it has been noted by GNATS.
 > 
 > From: Giorgos Keramidas <keramida@freebsd.org>
 > To: bug-followup@freebsd.org
 > Cc:  
 > Subject: Re: misc/34270: man -k could be used to execute any command.
 > Date: Sat, 26 Jan 2002 00:47:03 +0200
 > 
 >  On 2002-01-25 14:40:01, Giorgos Keramidas wrote:
 >  >  Can you try the attached patch?
 >  >  It seems to work for me.
 >  
 >  Although now that I think of it, all shell-metacharacters should be
 >  escaped in the system() string :-(
 
 This is not a security issue for a shell user,
 
   man -k 'echo "; id"'
   ng_echo(4) - netgraph echo node type
   ng_echo(8)               - netgraph echo node type
   uid=1001(cjc) gid=1001(cjc) groups=1001(cjc)
 
 Since they can only execute commands with their own privileges.
 
 But this is still not a Good Thing. system(3) bad. system(3) very,
 very bad. It should probably be turned into an execvp(2).
 -- 
 Crist J. Clark                     |     cjclark@alum.mit.edu
                                    |     cjclark@jhu.edu
 http://people.freebsd.org/~cjc/    |     cjc@freebsd.org

From: Giorgos Keramidas <keramida@freebsd.org>
To: "Crist J. Clark" <cjc@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 19:30:47 +0200

 Adding to my last post, since I forgot it.  There are other ways to
 coerce man(1) into executing commands, but I don't know how paranoid
 we want to get.  For instance try this command:
 
     $ PAGER="cat >/dev/null; echo T KERAMIDA DIE NOW K PLZ THX" man ls
     T KERAMIDA DIE NOW K PLZ THX
 
 Obviously the full power of a shell interpreter is a rather versatile
 thing to have in the PAGER environment variable, but do we really want
 this?  I would suggest dropping everything after the first ';'
 character but quoting and other stuff can make this fail too.
 
 Any other ideas?
 
 -- 
 Giorgos Keramidas . . . . . . . . . keramida@{ceid.upatras.gr,freebsd.org}
 FreeBSD Documentation Project . . . http://www.freebsd.org/docproj/
 FreeBSD: The power to serve . . . . http://www.freebsd.org/

From: Giorgos Keramidas <keramida@freebsd.org>
To: "Crist J. Clark" <cjc@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 19:23:40 +0200

 Here's a partial fix for the "apropos" and "whatis" options of man(1).
 This leaves still 4 places where man/man.c uses do_system_command(),
 since I need to understand the code before I make any changes.  The
 code of man.c is still vulnerable to environment variable tricks, but
 at least it works with -f and -k options without problems:
 
 My current /usr/bin/man executable:
 
 	$ man -k 'firewalls"; echo --- hi giorgos! ---; "'
 	firewall(7)              - simple firewalls under FreeBSD
 	--- hi giorgos! ---
 	: permission denied
 	execution of the shell failed in function system()
 
 The patched man.c version works correctly:
 
 	$ ./man -k 'firewalls"; echo --- hi giorgos! ---; "'
 	firewalls"; echo --- hi giorgos! ---; ": nothing appropriate
 
 Here's the diff...
 
 --- patch begins here ---
 Index: man/man.c
 ===================================================================
 RCS file: /home/ncvs/src/gnu/usr.bin/man/man/man.c,v
 retrieving revision 1.53
 diff -2 -u -r1.53 man.c
 --- man/man.c	22 Jan 2002 15:15:38 -0000	1.53
 +++ man/man.c	26 Jan 2002 17:02:15 -0000
 @@ -19,4 +19,6 @@
  #define MAN_MAIN
  
 +#include <sys/types.h>
 +#include <sys/wait.h>
  #include <sys/file.h>
  #include <sys/stat.h>
 @@ -526,17 +528,16 @@
       register char *name;
  {
 -  register int len;
 -  register char *command;
 -
 -  len = strlen (APROPOS) + strlen (name) + 4;
 -
 -  if ((command = (char *) malloc(len)) == NULL)
 -    gripe_alloc (len, "command");
 -
 -  sprintf (command, "%s \"%s\"", APROPOS, name);
 -
 -  (void) do_system_command (command);
 +  pid_t pid;
 +  int status;
  
 -  free (command);
 +  if ((pid = fork()) < 0) {
 +    return;
 +  } else if (pid > 0) {
 +    waitpid(pid, &status, 0);
 +  } else {
 +    /* Run the "apropos" command. */
 +    execlp(APROPOS, APROPOS, name, (char *) NULL);
 +    exit(1);
 +  }
  }
  
 @@ -548,17 +549,16 @@
       register char *name;
  {
 -  register int len;
 -  register char *command;
 -
 -  len = strlen (WHATIS) + strlen (name) + 4;
 -
 -  if ((command = (char *) malloc(len)) == NULL)
 -    gripe_alloc (len, "command");
 -
 -  sprintf (command, "%s \"%s\"", WHATIS, name);
 -
 -  (void) do_system_command (command);
 +  pid_t pid;
 +  int status;
  
 -  free (command);
 +  if ((pid = fork()) < 0) {
 +    return;
 +  } else if (pid > 0) {
 +    waitpid(pid, &status, 0);
 +  } else {
 +    /* Run the "whatis" command. */
 +    execlp(WHATIS, WHATIS, name, (char *) NULL);
 +    exit(1);
 +  }
  }
  
 --- patch ends here ---

From: Giorgos Keramidas <keramida@freebsd.org>
To: "Crist J. Clark" <cjc@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Sat, 26 Jan 2002 18:18:17 +0200 (EET)

 Crist J. Clark wrote:
 
 > Since they can only execute commands with their own privileges.
 >
 > But this is still not a Good Thing. system(3) bad. system(3) very,
 > very bad. It should probably be turned into an execvp(2).
 
 Agreed.  I don't like system() at all either. The gnu/usr.bin/man
 source though seems to use it in more than a few places.  I'll try
 replacing system() with execlp() or execvp() tonight in all of
 gnu/usr.bin/man/.
 
 - Giorgos
 

From: Giorgos Keramidas <keramida@ceid.upatras.gr>
To: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Cc: bug-followup@freebsd.org
Subject: Re: misc/34270: man -k could be used to execute any command.
Date: Tue, 29 Jan 2002 01:04:36 +0200

 On 2002-01-28 16:15:48, Garrett Wollman wrote:
 > <<On Sat, 26 Jan 2002 09:40:06 -0800 (PST), Giorgos Keramidas <keramida@FreeBSD.ORG> said:
 > 
 > >  Here's a partial fix for the "apropos" and "whatis" options of man(1).
 > >  This leaves still 4 places where man/man.c uses do_system_command(),
 > >  since I need to understand the code before I make any changes.  The
 > >  code of man.c is still vulnerable to environment variable tricks, but
 > >  at least it works with -f and -k options without problems:
 >  
 > I would suggest that the apropos and whatis commands be run by their
 > full path names, avoiding the exec?p functions.  If they are running
 > with privilege, the environment should be cleaned out as well.
 
 OK, although the commands are not run with elevated priviledges, so
 they're not dangerous (at least not in ways that I could think during
 the past few days).
 
 -- 
 Giorgos Keramidas . . . . . . . . . keramida@{ceid.upatras.gr,freebsd.org}
 FreeBSD Documentation Project . . . http://www.freebsd.org/docproj/
 FreeBSD: The power to serve . . . . http://www.freebsd.org/
State-Changed-From-To: open->patched 
State-Changed-By: arundel 
State-Changed-When: Sat Nov 13 10:19:44 UTC 2010 
State-Changed-Why:  
I cannot reproduce this under HEAD with the new man shell script. So it seems 
this issue only exists for the GNU version of man. Although GNU man still exists 
in HEAD, i think there is no WITH_* or WITHOUT_* variable to force buildworld to 
rely on it instead of the man shell script. 
Eventually GNU man will vanish from the src tree. I'm not sure whether there are 
any plans to MFC it to FreeBSD 8.x, but I doubt it will be MFC'ed to 
FreeBSD 7.x. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=34270 
State-Changed-From-To: patched->closed 
State-Changed-By: gnn 
State-Changed-When: Sat Jul 28 20:01:12 UTC 2012 
State-Changed-Why:  
This can no longer reproduced, as pointed out earlier, and also does 
not have any sort of privilege escalation.   

http://www.freebsd.org/cgi/query-pr.cgi?pr=34270 
>Unformatted:
