1 /* -*- mode: C; c-basic-offset: 3; -*- */ 2 3 /*--------------------------------------------------------------------*/ 4 /*--- User-mode execve() for #! scripts. m_ume_script.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2015 Julian Seward 12 jseward (at) acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 #include "pub_core_basics.h" 33 #include "pub_core_vki.h" 34 35 #include "pub_core_libcbase.h" 36 #include "pub_core_libcassert.h" // VG_(exit), vg_assert 37 #include "pub_core_libcfile.h" // VG_(close) et al 38 #include "pub_core_libcprint.h" 39 #include "pub_core_clientstate.h" // VG_(args_the_exename) 40 #include "pub_core_mallocfree.h" // VG_(strdup) 41 #include "pub_core_ume.h" // self 42 43 #include "priv_ume.h" 44 45 /* Return true, if the first line begins with #! and contains an 46 interpreter. */ 47 Bool VG_(match_script)(const void *hdr, SizeT len) 48 { 49 const HChar* script = hdr; 50 const HChar* end = script + len; 51 const HChar* interp = script + 2; 52 53 if (len < 2) return False; 54 if (0 != VG_(memcmp)(hdr, "#!", 2)) return False; 55 56 // Find interpreter name, which may be absolute or relative. 57 // First, skip over any space between the #! and the start of the 58 // interpreter name 59 while (interp < end && (*interp == ' ' || *interp == '\t')) interp++; 60 61 // overrun? 62 if (interp >= end) return False; // can't find start of interp name 63 64 // No interpreter found. 65 if (*interp == '\n') return False; 66 67 return True; // looks like a #! script 68 } 69 70 71 /* returns: 0 = success, non-0 is failure */ 72 Int VG_(load_script)(Int fd, const HChar* name, ExeInfo* info) 73 { 74 HChar hdr[4096]; 75 Int len = sizeof hdr; 76 Int eol; 77 HChar* interp; 78 HChar* end; 79 HChar* cp; 80 HChar* arg = NULL; 81 SysRes res; 82 83 // Read the first part of the file. 84 res = VG_(pread)(fd, hdr, len, 0); 85 if (sr_isError(res)) { 86 VG_(close)(fd); 87 return VKI_EACCES; 88 } else { 89 len = sr_Res(res); 90 } 91 92 vg_assert('#' == hdr[0] && '!' == hdr[1]); 93 94 end = hdr + len; 95 interp = hdr + 2; 96 while (interp < end && (*interp == ' ' || *interp == '\t')) 97 interp++; 98 99 /* skip over interpreter name */ 100 for (cp = interp; cp < end && !VG_(isspace)(*cp); cp++) 101 ; 102 103 eol = (*cp == '\n'); 104 105 *cp++ = '\0'; 106 107 if (!eol && cp < end) { 108 /* skip space before arg */ 109 while (cp < end && VG_(isspace)(*cp) && *cp != '\n') 110 cp++; 111 112 /* arg is from here to eol */ 113 arg = cp; 114 while (cp < end && *cp != '\n') 115 cp++; 116 *cp = '\0'; 117 } 118 119 info->interp_name = VG_(strdup)("ume.ls.1", interp); 120 vg_assert(NULL != info->interp_name); 121 if (arg != NULL && *arg != '\0') { 122 info->interp_args = VG_(strdup)("ume.ls.2", arg); 123 vg_assert(NULL != info->interp_args); 124 } 125 126 if (info->argv && info->argv[0] != NULL) 127 info->argv[0] = name; 128 129 VG_(args_the_exename) = name; 130 131 if (0) 132 VG_(printf)("#! script: interp_name=\"%s\" interp_args=\"%s\"\n", 133 info->interp_name, info->interp_args); 134 135 return VG_(do_exec_inner)(interp, info); 136 } 137 138 /*--------------------------------------------------------------------*/ 139 /*--- end ---*/ 140 /*--------------------------------------------------------------------*/ 141