1 /* 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, 20 * CA 94065 USA or visit www.oracle.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 #include <link.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <fcntl.h> 32 #include <limits.h> 33 #include <varargs.h> 34 35 // This class sets up an interposer on open calls from libproc.so to 36 // support a pathmap facility in the SA. 37 38 static uintptr_t* libproc_cookie; 39 static uintptr_t* libc_cookie; 40 static uintptr_t* libsaproc_cookie; 41 42 43 uint_t 44 la_version(uint_t version) 45 { 46 return (LAV_CURRENT); 47 } 48 49 50 uint_t 51 la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t * cookie) 52 { 53 if (strstr(lmp->l_name, "/libproc.so") != NULL) { 54 libproc_cookie = cookie; 55 return LA_FLG_BINDFROM; 56 } 57 if (strstr(lmp->l_name, "/libc.so") != NULL) { 58 libc_cookie = cookie; 59 return LA_FLG_BINDTO; 60 } 61 if (strstr(lmp->l_name, "/libsaproc.so") != NULL) { 62 libsaproc_cookie = cookie; 63 return LA_FLG_BINDTO | LA_FLG_BINDFROM; 64 } 65 return 0; 66 } 67 68 69 #if defined(_LP64) 70 uintptr_t 71 la_symbind64(Elf64_Sym *symp, uint_t symndx, uintptr_t *refcook, 72 uintptr_t *defcook, uint_t *sb_flags, const char *sym_name) 73 #else 74 uintptr_t 75 la_symbind32(Elf32_Sym *symp, uint_t symndx, uintptr_t *refcook, 76 uintptr_t *defcook, uint_t *sb_flags) 77 #endif 78 { 79 #if !defined(_LP64) 80 const char *sym_name = (const char *)symp->st_name; 81 #endif 82 if (strcmp(sym_name, "open") == 0 && refcook == libproc_cookie) { 83 // redirect all open calls from libproc.so through libsaproc_open which will 84 // try the alternate library locations first. 85 void* handle = dlmopen(LM_ID_BASE, "libsaproc.so", RTLD_NOLOAD); 86 if (handle == NULL) { 87 fprintf(stderr, "libsaproc_audit.so: didn't find libsaproc.so during linking\n"); 88 } else { 89 uintptr_t libsaproc_open = (uintptr_t)dlsym(handle, "libsaproc_open"); 90 if (libsaproc_open == 0) { 91 fprintf(stderr, "libsaproc_audit.so: didn't find libsaproc_open during linking\n"); 92 } else { 93 return libsaproc_open; 94 } 95 } 96 } 97 return symp->st_value; 98 }