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