xref: /netbsd-src/share/man/man7/script.7 (revision 5e015e5e29314963f594bd9787e9b818f2f2c494)
1*5e015e5eSjoerg.\"	$NetBSD: script.7,v 1.6 2010/03/22 18:58:32 joerg Exp $
252b72367Sperry.\"
352b72367Sperry.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
452b72367Sperry.\" All rights reserved.
552b72367Sperry.\"
652b72367Sperry.\" This document was originally contributed to The NetBSD Foundation
752b72367Sperry.\" by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC.
852b72367Sperry.\"
952b72367Sperry.\" Redistribution and use in source and binary forms, with or without
1052b72367Sperry.\" modification, are permitted provided that the following conditions
1152b72367Sperry.\" are met:
1252b72367Sperry.\" 1. Redistributions of source code must retain the above copyright
1352b72367Sperry.\"    notice, this list of conditions and the following disclaimer.
1452b72367Sperry.\" 2. Redistributions in binary form must reproduce the above copyright
1552b72367Sperry.\"    notice, this list of conditions and the following disclaimer in the
1652b72367Sperry.\"    documentation and/or other materials provided with the distribution.
1752b72367Sperry.\"
1852b72367Sperry.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1952b72367Sperry.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2052b72367Sperry.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2152b72367Sperry.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2252b72367Sperry.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2352b72367Sperry.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2452b72367Sperry.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2552b72367Sperry.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2652b72367Sperry.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2752b72367Sperry.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2852b72367Sperry.\" POSSIBILITY OF SUCH DAMAGE.
2952b72367Sperry.\"
3052b72367Sperry.Dd May 6, 2005
3152b72367Sperry.Dt SCRIPT 7
3252b72367Sperry.Os
3352b72367Sperry.Sh NAME
3452b72367Sperry.Nm script
3552b72367Sperry.Nd interpreter script execution
3652b72367Sperry.Sh DESCRIPTION
3752b72367SperryThe system is capable of treating a text file containing commands
3852b72367Sperryintended for an interpreter, such as
3952b72367Sperry.Xr sh 1
4052b72367Sperryor
4152b72367Sperry.Xr awk 1 ,
4252b72367Sperryas an executable program.
4352b72367Sperry.Pp
4452b72367SperryAn
4552b72367Sperry.Dq interpreter script
4652b72367Sperryis a file which has been set executable (see
4752b72367Sperry.Xr chmod 2 )
4852b72367Sperryand which has a first line of the form:
4952b72367Sperry.Pp
5052b72367Sperry.D1 Li #! Ar pathname Op Ar argument
5152b72367Sperry.Pp
5252b72367SperryThe
5352b72367Sperry.Dq #!
5452b72367Sperrymust appear as the first two characters of the file.
5552b72367SperryA space between the
5652b72367Sperry.Dq #!
5752b72367Sperryand
5852b72367Sperry.Ar pathname
5952b72367Sperryis optional.
6052b72367SperryAt most one
6152b72367Sperry.Ar argument
6252b72367Sperrymay follow
6352b72367Sperry.Ar pathname ,
6452b72367Sperryand the length of the entire line is limited (see below).
6552b72367Sperry.Pp
6652b72367SperryIf such a file is executed (such as via the
6752b72367Sperry.Xr execve 2
6852b72367Sperrysystem call), the interpreter specified by the
6952b72367Sperry.Ar pathname
7052b72367Sperryis executed by the system.
7152b72367Sperry(The
7252b72367Sperry.Ar pathname
7352b72367Sperryis executed without regard to the
7452b72367Sperry.Ev PATH
7552b72367Sperryvariable, so in general
7652b72367Sperry.Ar pathname
7752b72367Sperryshould be an absolute path.)
7852b72367Sperry.Pp
7952b72367SperryThe arguments passed to the interpreter will be as follows.
8052b72367Sperry.Va argv[0]
8152b72367Sperrywill be the path to the interpreter itself, as specified on the first
8252b72367Sperryline of the script.
8352b72367SperryIf there is an
8452b72367Sperry.Ar argument
8552b72367Sperryfollowing
8652b72367Sperry.Ar pathname
8752b72367Sperryon the first line of the script, it will be passed as
8852b72367Sperry.Va argv[1] .
8952b72367SperryThe subsequent elements of
9052b72367Sperry.Va argv
9152b72367Sperrywill be the path to the interpreter script file itself (i.e. the
9252b72367Sperryoriginal
9352b72367Sperry.Va argv[0] )
9452b72367Sperryfollowed by any further arguments passed when
9552b72367Sperry.Xr execve 2
9652b72367Sperrywas invoked to execute the script file.
9752b72367Sperry.Pp
9852b72367SperryBy convention, it is expected that an interpreter will open the script
9952b72367Sperryfile passed as an argument and process the commands within it.
10052b72367SperryTypical interpreters treat
101e14c57c8Swiz.Sq #
10252b72367Sperryas a comment character, and thus will ignore the initial line of the script
10352b72367Sperrybecause it begins
10452b72367Sperry.Dq #! ,
10552b72367Sperrybut there is no requirement for this per se.
10652b72367Sperry.Pp
10752b72367SperryOn
10852b72367Sperry.Nx ,
10952b72367Sperrythe length of the
11052b72367Sperry.Dq #!
11152b72367Sperryline, excluding the
11252b72367Sperry.Dq #!
11352b72367Sperryitself, is limited to
11452b72367Sperry.Dv PATH_MAX
11552b72367Sperry(as defined in
116*5e015e5eSjoerg.In limits.h ) .
11752b72367SperryOther operating systems impose much smaller limits on the length of
11852b72367Sperrythe
11952b72367Sperry.Dq #!
12052b72367Sperryline (see below).
12152b72367Sperry.Pp
12252b72367SperryNote that the interpreter may not itself be an interpreter script.
12352b72367SperryIf
12452b72367Sperry.Ar pathname
12552b72367Sperrydoes not point to an executable binary, execution of the interpreter
12652b72367Sperryscript will fail.
12752b72367Sperry.Ss Trampolines and Portable Scripts
12852b72367SperryDifferent operating systems often have interpreters located in
12952b72367Sperrydifferent locations, and the kernel executes the passed interpreter
13052b72367Sperrywithout regard to the setting of environment variables such as
13152b72367Sperry.Ev PATH .
13252b72367SperryThis makes it somewhat challenging to set the
13352b72367Sperry.Dq #!
13452b72367Sperryline of a script so that it will run identically on different systems.
13552b72367Sperry.Pp
13652b72367SperrySince the
13752b72367Sperry.Xr env 1
13852b72367Sperryutility executes a command passed to it on its command line, it is
13952b72367Sperryoften used as a
14052b72367Sperry.Dq trampoline
14152b72367Sperryto render scripts portable.
14252b72367SperryIf the leading line of a script reads
14352b72367Sperry.Dl #! /usr/bin/env interp
14452b72367Sperrythen the
14552b72367Sperry.Xr env 1
14652b72367Sperrycommand will execute the
14752b72367Sperry.Dq interp
14852b72367Sperrycommand it finds in its
14952b72367Sperry.Ev PATH ,
15052b72367Sperrypassing on to it all subsequent arguments with which it itself was called.
15152b72367SperrySince
15252b72367Sperry.Pa /usr/bin/env
15352b72367Sperryis found on almost all
15452b72367Sperry.Tn POSIX
15552b72367Sperrystyle systems, this trick is frequently exploited by authors who need
15652b72367Sperrya script to execute without change on multiple systems.
15752b72367Sperry.Ss Historical Note: Scripts without Dq #!
15852b72367SperryShell scripts predate the invention of the
15952b72367Sperry.Dq #!
16052b72367Sperryconvention, which is implemented in the kernel.
16152b72367SperryIn the days of
16252b72367Sperry.At v7 ,
16352b72367Sperrythere was only one interpreter used on the system,
16452b72367Sperry.Pa /bin/sh ,
16552b72367Sperryand the shell treated any file that failed to execute with an
16652b72367Sperry.Er ENOEXEC
16752b72367Sperryerror
16852b72367Sperry(see
16952b72367Sperry.Xr intro 2 )
17052b72367Sperryas a shell script.
17152b72367Sperry.Pp
17252b72367SperryMost shells (such as
17352b72367Sperry.Xr sh 1 )
17452b72367Sperryand certain other facilities (including
17552b72367Sperry.Xr execlp 3
17652b72367Sperryand
17752b72367Sperry.Xr execvp 3
17852b72367Sperrybut not other types of
17952b72367Sperry.Xr exec 3
18052b72367Sperrycalls) still pass
18152b72367Sperryinterpreter scripts that do not include the
18252b72367Sperry.Dq #!
18352b72367Sperry(and thus fail to execute with
18452b72367Sperry.Er ENOEXEC )
18552b72367Sperryto
18652b72367Sperry.Pa /bin/sh .
18752b72367Sperry.Pp
18852b72367SperryAs this behavior is implemented outside the kernel, there is no
18952b72367Sperrymechanism that forces it to be respected by all programs that execute
19052b72367Sperryother programs.
19152b72367SperryIt is thus not completely reliable.
19252b72367SperryIt is therefore important to always include
19352b72367Sperry.Dl #!/bin/sh
19452b72367Sperryin front of Bourne shell scripts, and to treat the traditional
19552b72367Sperrybehavior as obsolete.
19652b72367Sperry.Sh EXAMPLES
19752b72367SperrySuppose that an executable binary exists in
19852b72367Sperry.Pa /bin/interp
19952b72367Sperryand that the file
20052b72367Sperry.Pa /tmp/script
20152b72367Sperrycontains:
20252b72367Sperry.Bd -literal -offset indent
20352b72367Sperry#!/bin/interp -arg
20452b72367Sperry
20552b72367Sperry[...]
20652b72367Sperry.Ed
20752b72367Sperry.Pp
20852b72367Sperryand that
20952b72367Sperry.Pa /tmp/script
21052b72367Sperryis set mode 755.
21152b72367Sperry.Pp
21252b72367SperryExecuting
21352b72367Sperry.Pp
21452b72367Sperry.Dl $ /tmp/script one two three
21552b72367Sperry.Pp
21652b72367Sperryat the shell will result in
21752b72367Sperry.Pa /bin/interp
21852b72367Sperrybeing executed, receiving the following arguments in
21952b72367Sperry.Va argv
22052b72367Sperry(numbered from 0):
22152b72367Sperry.Pp
22252b72367Sperry.Bd -ragged -offset indent
22352b72367Sperry.Qq /bin/interp ,
22452b72367Sperry.Qq "-arg" ,
22552b72367Sperry.Qq /tmp/script ,
22652b72367Sperry.Qq one ,
22752b72367Sperry.Qq two ,
22852b72367Sperry.Qq three
22952b72367Sperry.Ed
23052b72367Sperry.Ss Portability Note: Multiple arguments
23152b72367SperryThe behavior of multiple arguments on the
23252b72367Sperry.Dq #!
233e14c57c8Swizline is highly non-portable between different systems.
234e14c57c8SwizIn general, only one argument can be assumed to work consistently.
23552b72367Sperry.Pp
236e14c57c8SwizConsider the following variation on the previous example.
237e14c57c8SwizSuppose that an executable binary exists in
23852b72367Sperry.Pa /bin/interp
23952b72367Sperryand that the file
24052b72367Sperry.Pa /tmp/script
24152b72367Sperrycontains:
24252b72367Sperry.Bd -literal -offset indent
24352b72367Sperry#!/bin/interp -x -y
24452b72367Sperry
24552b72367Sperry[...]
24652b72367Sperry.Ed
24752b72367Sperry.Pp
24852b72367Sperryand that
24952b72367Sperry.Pa /tmp/script
25052b72367Sperryis set mode 755.
25152b72367Sperry.Pp
25252b72367SperryExecuting
25352b72367Sperry.Pp
25452b72367Sperry.Dl $ /tmp/script one two three
25552b72367Sperry.Pp
25652b72367Sperryat the shell will result in
25752b72367Sperry.Pa /bin/interp
25852b72367Sperrybeing executed, receiving the following arguments in
25952b72367Sperry.Va argv
26052b72367Sperry(numbered from 0):
26152b72367Sperry.Pp
26252b72367Sperry.Bd -ragged -offset indent
26352b72367Sperry.Qq /bin/interp ,
26452b72367Sperry.Qq "-x -y" ,
26552b72367Sperry.Qq /tmp/script ,
26652b72367Sperry.Qq one ,
26752b72367Sperry.Qq two ,
26852b72367Sperry.Qq three
26952b72367Sperry.Ed
27052b72367Sperry.Pp
27152b72367SperryNote that
27252b72367Sperry.Qq "-x -y"
27352b72367Sperrywill be passed on
27452b72367Sperry.Nx
27552b72367Sperryas a single argument.
27652b72367Sperry.Pp
27752b72367SperryAlthough most
27852b72367Sperry.Tn POSIX
27952b72367Sperrystyle operating systems will pass only one
28052b72367Sperry.Ar argument ,
2817cbffa94Swizthe behavior when multiple arguments are included is not
28252b72367Sperryconsistent between platforms.
28352b72367SperrySome, such as current releases of
28452b72367Sperry.Nx ,
28552b72367Sperrywill concatenate multiple arguments into a single argument (as above),
28652b72367Sperrysome will truncate them, and at least one will pass them as multiple
28752b72367Sperryarguments.
28852b72367Sperry.Pp
28952b72367SperryThe
29052b72367Sperry.Nx
29152b72367Sperrybehavior is common but not universal.
29252b72367SperrySun's
29352b72367Sperry.Tn Solaris
29452b72367Sperrywould present the above argument as
29552b72367Sperry.Qq -x ,
29652b72367Sperrydropping the
29752b72367Sperry.Qq " -y"
29852b72367Sperryentirely.
29952b72367SperryPerhaps uniquely, recent versions of Apple's
30052b72367Sperry.Tn OS X
30152b72367Sperrywill actually pass multiple arguments properly, i.e.:
30252b72367Sperry.Bd -ragged -offset indent
30352b72367Sperry.Qq /bin/interp ,
30452b72367Sperry.Qq -x ,
30552b72367Sperry.Qq -y ,
30652b72367Sperry.Qq /tmp/script ,
30752b72367Sperry.Qq one ,
30852b72367Sperry.Qq two ,
30952b72367Sperry.Qq three
31052b72367Sperry.Ed
31152b72367Sperry.Pp
31252b72367SperryThe behavior of the system in the face of multiple arguments is thus
31352b72367Sperrynot currently standardized, should not be relied on, and may be
31452b72367Sperrychanged in future releases.
31552b72367SperryIn general, pass at most one argument, and do not rely on multiple
31652b72367Sperryarguments being concatenated.
31752b72367Sperry.Sh SEE ALSO
31852b72367Sperry.Xr awk 1 ,
319e14c57c8Swiz.Xr csh 1 ,
320e14c57c8Swiz.Xr ksh 1 ,
32152b72367Sperry.Xr sh 1 ,
32252b72367Sperry.Xr chmod 2 ,
32352b72367Sperry.Xr execve 2 ,
32452b72367Sperry.Xr intro 2 ,
32552b72367Sperry.Xr execlp 3 ,
32652b72367Sperry.Xr execvp 3 ,
32752b72367Sperry.Xr fd 4 ,
32852b72367Sperry.Xr options 4 ,
32952b72367Sperry.Xr setuid 7
33052b72367Sperry.Sh STANDARDS
33152b72367SperryThe behavior of interpreter scripts is obliquely referred to, but
33252b72367Sperrynever actually described in,
33352b72367Sperry.St -p1003.1-2004 .
33452b72367Sperry.Pp
33552b72367SperryThe behavior is partially (but not completely) described in the
33652b72367Sperry.St -svid4 .
33752b72367Sperry.Pp
33852b72367SperryAlthough it has never been formally standardized, the behavior
33952b72367Sperrydescribed is largely portable across
34052b72367Sperry.Tn POSIX
34152b72367Sperrystyle systems, with two significant exceptions: the maximum length of the
34252b72367Sperry.Dq #!
34352b72367Sperryline, and the behavior if multiple arguments are passed.
34452b72367SperryPlease be aware that some operating systems limit the line to 32
34552b72367Sperryor 64 characters, and that (as described above) the behavior in the
34652b72367Sperryface of multiple arguments is not consistent across systems.
34752b72367Sperry.Sh HISTORY
34852b72367SperryThe behavior of the kernel when encountering scripts that start in
34952b72367Sperry.Dq #!
35052b72367Sperrywas not present in
35152b72367Sperry.At v7 .
35252b72367SperryA Usenet posting to net.unix by Guy Harris on October 16, 1984 claims
35352b72367Sperrythat the idea for the
35452b72367Sperry.Dq #!
35552b72367Sperrybehavior was first proposed by Dennis Ritchie but that the first
35652b72367Sperryimplementation was on
35752b72367Sperry.Bx .
35852b72367Sperry.Pp
35952b72367SperryHistorical manuals (specifically the exec man page) indicate that the
36052b72367Sperrybehavior was present in
36152b72367Sperry.Bx 4
36252b72367Sperryat least as early as April, 1981.
36352b72367SperryInformation on precisely when it was first implemented, and in which
36452b72367Sperryversion of
36552b72367Sperry.Ux ,
36652b72367Sperryis solicited.
367abaa11daSwiz.Sh SECURITY CONSIDERATIONS
368abaa11daSwizNumerous security problems are associated with setuid interpreter
369abaa11daSwizscripts.
370abaa11daSwiz.Pp
371abaa11daSwizIn addition to the fact that many interpreters (and scripts) are
372abaa11daSwizsimply not designed to be robust in a setuid context, a race condition
373abaa11daSwizexists between the moment that the kernel examines the interpreter
374abaa11daSwizscript file and the moment that the newly invoked interpreter opens
375abaa11daSwizthe file itself.
376abaa11daSwiz.Pp
377abaa11daSwizBecause of these security issues,
378abaa11daSwiz.Nx
379abaa11daSwizdoes not allow setuid interpreter scripts by default.
380abaa11daSwizIn order to turn on setuid interpreter scripts,
381abaa11daSwiz.D1 Cd options SETUIDSCRIPTS
382abaa11daSwizmust be set in the configuration of the running kernel.
383abaa11daSwizSetting this option implies the
384abaa11daSwiz.Cd FDSCRIPTS
385abaa11daSwizoption, which causes the kernel to open the script file on behalf of
386abaa11daSwizthe interpreter and pass it in
387abaa11daSwiz.Va argv
388abaa11daSwizas
389abaa11daSwiz.Pa /dev/fd/[fdnum] .
390abaa11daSwiz(See
391abaa11daSwiz.Xr fd 4
392abaa11daSwizfor an explanation of the
393abaa11daSwiz.Pa /dev/fd/[fdnum]
394abaa11daSwizdevices.)
395abaa11daSwizThis design avoids the race condition, at the cost of denying the
396abaa11daSwizinterpreter the actual name of the script file.
397abaa11daSwizSee
398abaa11daSwiz.Xr options 4
399abaa11daSwizfor more information.
400abaa11daSwiz.Pp
401abaa11daSwizHowever, the
402abaa11daSwiz.Cd FDSCRIPTS
403abaa11daSwizmechanism is not a cure-all for security issues in setuid interpreters
404abaa11daSwizand scripts.
405abaa11daSwizSubtle techniques can be used to subvert even seemingly well written scripts.
406abaa11daSwizScripts executed by Bourne type shells can be subverted in numerous
407abaa11daSwizways, such as by setting the
408abaa11daSwiz.Ev IFS
409abaa11daSwizvariable before executing the script.
410abaa11daSwizOther interpreters possess their own vulnerabilities.
411abaa11daSwizTurning on
412abaa11daSwiz.Cd SETUIDSCRIPTS
413abaa11daSwizis therefore very dangerous, and should not be done lightly if at all.
414