This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

getopt() argument permuting considered risky


Gidday,

The glibc getopt() function contains what I 
would characterise as a potentially dangerous 
(see below) mis-feature: by default, it permutes 
the command-line arguments in search of 
command-line options.  Thus, the following are 
equivalent:

    $ ls -l file

    $ ls file -l

This behaviour (which SUSv3 does not permit) can 
be disabled in two ways:

1) Place a plus sign (+) at the start of the optstring 
   argument.  
   (Note: this works because other getopt() implementations 
   ignore a '+' in optstring.)

2) Set the environment variable POSIXLY_CORRECT to any 
   value, either

   a) from the code using putenv(3) or setenv(3)

   b) from the shell:

          $ export POSIXLY_CORRECT=y

As a general principle, one could probably argue that 
method 2b is the best approach since it doesn't 
require changes to the application source code.

The problems occur if the user doesn't know to set 
this variable (and this is to some extent 
independent of portability considerations).  And as 
far as I can see the problems are actually security 
risks for programs and scripts ported to glibc 
platforms from other Unix implementations.  These 
problems can arise in at least the following ways:

Problem 1: command-line arguments starting with a dash

A program argument (notably a program that takes 
negative numeric command-line arguments), can have 
its argument misinterpreted as an option.  For 
example, suppose we have a program as follows

    prog [options] arg1 arg2 arg3-num

where arg3-num is can be a negative number.  When 
ported to a glibc platform, this argument will be 
misinterpreted as an option, unless the user 
defines POSIXLY_CORRECT.

Problem 2: malicious use of arguments in shell scripts

(Thanks to Geoff Clare for pointing this out to me; 
the example below largely derives from a formulation 
of his.)

A mischievous user can cause shell scripts to misbehave 
by creating files whose names start with a dash. On 
other systems, experienced shell scripters avoid such 
problems by placing a "--" in any command line where 
the *first* non-option argument is some sort of 
substitution or expansion, to ensure it can't be 
interpreted as an option, for example:

    $ ls -l -- "$user_supplied_filename"
    $ rm -- *.old

With commands that use glibc's getopt() this has to be 
done if there is a substitution or expansion *anywhere* 
on the command line. For example, 

    $ grep string "$user_supplied_filename"

would normally be safe, but on glibc platforms it 
needs to be:

    $ grep -- string "$user_supplied_filename"

Of course, portable shell scripts (i.e., portable on 
all other Unix systems) do not know to do this, and 
are thus vulnerable on glibc systems.

===

Some suggestions:

1. What are the chances of having this feature removed 
    from glibc's getopt()?

   I realise that the argument is probably: "it will 
   break existing applications".  Some responses:

   a) Is that really true: are there really applications
      that depend on this non-standard behaviour?

   b) The existing behaviour is a security risk, as 
      described above.

2. Perhaps Linux distributors should be setting 
   POSIXLY_CORRECT in their default shell start-up 
   files?

Cheers,

Michael



-- 
Michael Kerrisk
mtk-lists@gmx.net

NEU: WLAN-Router für 0,- EUR* - auch für DSL-Wechsler!
GMX DSL = supergünstig & kabellos http://www.gmx.net/de/go/dsl


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]