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