1 /* $OpenBSD: isexec.c,v 1.4 1998/06/26 21:21:12 millert Exp $ */ 2 3 /* 4 * Copyright (c) 1983 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 #ifndef lint 36 #if 0 37 static char RCSid[] = 38 "$From: isexec.c,v 6.21 1994/04/01 23:44:10 mcooper Exp $"; 39 #else 40 static char RCSid[] = 41 "$OpenBSD: isexec.c,v 1.4 1998/06/26 21:21:12 millert Exp $"; 42 #endif 43 44 static char sccsid[] = "@(#)client.c"; 45 46 static char copyright[] = 47 "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 48 All rights reserved.\n"; 49 #endif /* not lint */ 50 51 52 #include "defs.h" 53 54 #if EXE_TYPE == EXE_AOUT 55 /* 56 * BSD style A.OUT 57 */ 58 #include <a.out.h> 59 60 static int _isexec(fd) 61 int fd; 62 { 63 struct exec ehdr; 64 65 if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) && 66 !N_BADMAG(ehdr)) 67 return(TRUE); 68 else 69 return(FALSE); 70 } 71 #endif /* EXE_AOUT */ 72 73 74 #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF 75 /* 76 * Elf 77 */ 78 #include <elf.h> 79 #define ISELF(h) (h.e_type == ET_EXEC) 80 #endif /* EXE_ELF_AND_COFF || EXE_ELF */ 81 82 #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF 83 84 /* 85 * COFF 86 */ 87 #if defined(FILEHDR_H) 88 #include FILEHDR_H 89 #endif /* FILEHDR_H */ 90 91 #if !defined(ISCOFF) 92 93 /* 94 * Stupid AIX 95 */ 96 #if defined(U802WRMAGIC) && defined(U802ROMAGIC) && defined(U802TOCMAGIC) 97 #define ISCOFF(x) (((x)==U802WRMAGIC) || ((x)==U802TOCMAGIC) || \ 98 ((x)==U802TOCMAGIC)) 99 #endif /* U802... */ 100 /* 101 * Stupid Umax4.3 102 */ 103 #if defined(NS32GMAGIC) || defined(NS32SMAGIC) 104 #define ISCOFF(x) (((x)==NS32GMAGIC) || ((x)==NS32SMAGIC)) 105 #endif /* NS32 ... */ 106 107 #endif /* ISCOFF */ 108 109 #endif /* EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_COFF */ 110 111 #if EXE_TYPE == EXE_ELF_AND_COFF 112 /* 113 * ELF and COFF 114 */ 115 typedef union { 116 struct filehdr coffhdr; 117 Elf32_Ehdr elfhdr; 118 } hdr_t; 119 #endif /* EXE_TYPE == EXE_ELF_AND_COFF */ 120 121 #if EXE_TYPE == EXE_ELF 122 /* 123 * Elf 124 */ 125 #include <elf.h> 126 typedef Elf32_Ehdr hdr_t; 127 #endif /* EXE_TYPE == EXE_ELF */ 128 129 #if EXE_TYPE == EXE_COFF 130 /* 131 * COFF 132 */ 133 134 #if defined(FILEHDR_H) 135 #include FILEHDR_H 136 #endif /* FILEHDR_H */ 137 138 typedef struct filehdr hdr_t; 139 #endif /* EXE_TYPE == EXE_COFF */ 140 141 #if EXE_TYPE == EXE_ELF_AND_COFF || EXE_TYPE == EXE_ELF || EXE_TYPE == EXE_COFF 142 /* 143 * System V style COFF and System V R4 style ELF 144 */ 145 static int _isexec(fd) 146 int fd; 147 { 148 hdr_t hdr; 149 150 if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)) { 151 #if EXE_TYPE == EXE_ELF_AND_COFF 152 if (ISELF(hdr.elfhdr) || ISCOFF(hdr.coffhdr.f_magic)) 153 return(TRUE); 154 #endif 155 #if EXE_TYPE == EXE_ELF 156 if (ISELF(hdr)) 157 return(TRUE); 158 #endif 159 #if EXE_TYPE == EXE_COFF 160 if (ISCOFF(hdr.f_magic)) 161 return(TRUE); 162 #endif 163 } 164 165 return(FALSE); 166 } 167 #endif /* EXE_ELF_AND_COFF */ 168 169 170 #if EXE_TYPE == EXE_MACHO 171 /* 172 * Mach-O format 173 */ 174 175 #if defined(NEXTSTEP) && NEXTSTEP >= 3 176 # include <mach-o/loader.h> 177 #else 178 # include <sys/loader.h> 179 #endif /* NEXTSTEP */ 180 181 #ifndef MH_CIGAM 182 #define MH_CIGAM 0xcefaedfe 183 #endif 184 #ifndef FAT_MAGIC 185 #define FAT_MAGIC 0xcafebabe 186 #endif 187 #ifndef FAT_CIGAM 188 #define FAT_CIGAM 0xbebafeca 189 #endif 190 191 static int _isexec(fd) 192 int fd; 193 { 194 struct mach_header ehdr; 195 196 if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) && 197 (ehdr.magic == MH_MAGIC || ehdr.magic == MH_CIGAM || 198 ehdr.magic == FAT_MAGIC || ehdr.magic == FAT_CIGAM)) 199 return(TRUE); 200 else 201 return(FALSE); 202 } 203 #endif /* EXE_COFF */ 204 205 206 #if EXE_TYPE == EXE_HPEXEC 207 /* 208 * HP 9000 executable format 209 */ 210 211 #ifdef hp9000s300 212 213 #include <a.out.h> 214 #define header exec 215 #define ISEXEC(a) ((a.file_type)==EXEC_MAGIC || (a.file_type)==SHARE_MAGIC || \ 216 (a.file_type)==DEMAND_MAGIC) 217 218 #else /* ! hp9000s300 */ 219 220 #define ISEXEC(a) ((a)==EXEC_MAGIC || (a)==SHARE_MAGIC || (a)==DEMAND_MAGIC) 221 #include <filehdr.h> 222 223 #endif /* hp9000s300 */ 224 225 static int _isexec(fd) 226 int fd; 227 { 228 struct header ehdr; 229 230 if ((read(fd, &ehdr, sizeof(ehdr)) == sizeof(ehdr)) && 231 ISEXEC(ehdr.a_magic)) 232 return(TRUE); 233 else 234 return(FALSE); 235 } 236 #endif /* EXE_HPEXEC */ 237 238 239 #if !defined(EXE_TYPE) 240 /* 241 * Fake _isexec() call for unknown executable formats. 242 */ 243 static int _isexec(fd) 244 /*ARGSUSED*/ 245 int fd; 246 { 247 return(FALSE); 248 } 249 #endif /* !defined(EXE_TYPE) */ 250 251 /* 252 * Determine whether 'file' is an executable or not. 253 */ 254 extern int isexec(file, statp) 255 char *file; 256 struct stat *statp; 257 { 258 int fd, r; 259 260 /* 261 * Must be a regular file that has some executable mode bit on 262 */ 263 if (!S_ISREG(statp->st_mode) || 264 !(statp->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) 265 return(FALSE); 266 267 if ((fd = open(file, O_RDONLY, 0)) < 0) 268 return(FALSE); 269 r = _isexec(fd); 270 (void) close(fd); 271 272 return(r); 273 } 274 275