This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
getopt() argument permuting considered risky
- From: "Michael T Kerrisk" <mtk-lists at gmx dot net>
- To: libc-alpha at sources dot redhat dot com
- Cc: Geoff Clare <geoff at gclare dot org dot uk>
- Date: Wed, 4 Aug 2004 11:09:29 +0200 (MEST)
- Subject: 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