1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "defs.h" 32 #include <fcntl.h> 33 #include <sys/stat.h> 34 #include <sys/wait.h> 35 #include <sys/resource.h> 36 #include <sys/utsname.h> 37 #include <sys/user.h> 38 39 /* Bits of module.flags. */ 40 41 #define MOD_UNINITIALIZED 0 42 #define MOD_RUNNING 1 43 #define MOD_DELETED 2 44 #define MOD_AUTOCLEAN 4 45 #define MOD_VISITED 8 46 #define MOD_USED_ONCE 16 47 #define MOD_JUST_FREED 32 48 #define MOD_INITIALIZING 64 49 50 /* Values for query_module's which. */ 51 52 #define QM_MODULES 1 53 #define QM_DEPS 2 54 #define QM_REFS 3 55 #define QM_SYMBOLS 4 56 #define QM_INFO 5 57 58 struct module_symbol 59 { 60 unsigned long value; 61 const char *name; 62 }; 63 64 struct module_info 65 { 66 unsigned long addr; 67 unsigned long size; 68 unsigned long flags; 69 long usecount; 70 }; 71 72 #include "xlat/qm_which.h" 73 #include "xlat/modflags.h" 74 #include "xlat/delete_module_flags.h" 75 76 int 77 sys_query_module(struct tcb *tcp) 78 { 79 if (entering(tcp)) { 80 printstr(tcp, tcp->u_arg[0], -1); 81 tprints(", "); 82 printxval(qm_which, tcp->u_arg[1], "QM_???"); 83 tprints(", "); 84 } else { 85 size_t ret; 86 87 if (!verbose(tcp) || syserror(tcp) || 88 umove(tcp, tcp->u_arg[4], &ret) < 0) { 89 tprintf("%#lx, %lu, %#lx", tcp->u_arg[2], 90 tcp->u_arg[3], tcp->u_arg[4]); 91 } else if (tcp->u_arg[1]==QM_INFO) { 92 struct module_info mi; 93 if (umove(tcp, tcp->u_arg[2], &mi) < 0) { 94 tprintf("%#lx, ", tcp->u_arg[2]); 95 } else { 96 tprintf("{address=%#lx, size=%lu, flags=", 97 mi.addr, mi.size); 98 printflags(modflags, mi.flags, "MOD_???"); 99 tprintf(", usecount=%lu}, ", mi.usecount); 100 } 101 tprintf("%lu", (unsigned long)ret); 102 } else if ((tcp->u_arg[1]==QM_MODULES) || 103 (tcp->u_arg[1]==QM_DEPS) || 104 (tcp->u_arg[1]==QM_REFS)) { 105 tprints("{"); 106 if (!abbrev(tcp)) { 107 char* data = malloc(tcp->u_arg[3]); 108 char* mod = data; 109 size_t idx; 110 111 if (!data) { 112 fprintf(stderr, "out of memory\n"); 113 tprintf(" /* %lu entries */ ", (unsigned long)ret); 114 } else { 115 if (umoven(tcp, tcp->u_arg[2], 116 tcp->u_arg[3], data) < 0) { 117 tprintf(" /* %lu entries */ ", (unsigned long)ret); 118 } else { 119 for (idx = 0; idx < ret; idx++) { 120 tprintf("%s%s", 121 (idx ? ", " : ""), 122 mod); 123 mod += strlen(mod)+1; 124 } 125 } 126 free(data); 127 } 128 } else 129 tprintf(" /* %lu entries */ ", (unsigned long)ret); 130 tprintf("}, %lu", (unsigned long)ret); 131 } else if (tcp->u_arg[1]==QM_SYMBOLS) { 132 tprints("{"); 133 if (!abbrev(tcp)) { 134 char* data = malloc(tcp->u_arg[3]); 135 struct module_symbol* sym = (struct module_symbol*)data; 136 size_t idx; 137 138 if (!data) { 139 fprintf(stderr, "out of memory\n"); 140 tprintf(" /* %lu entries */ ", (unsigned long)ret); 141 } else { 142 if (umoven(tcp, tcp->u_arg[2], 143 tcp->u_arg[3], data) < 0) { 144 tprintf(" /* %lu entries */ ", (unsigned long)ret); 145 } else { 146 for (idx = 0; idx < ret; idx++) { 147 tprintf("%s{name=%s, value=%lu}", 148 (idx ? " " : ""), 149 data+(long)sym->name, 150 sym->value); 151 sym++; 152 } 153 } 154 free(data); 155 } 156 } else 157 tprintf(" /* %lu entries */ ", (unsigned long)ret); 158 tprintf("}, %ld", (unsigned long)ret); 159 } else { 160 printstr(tcp, tcp->u_arg[2], tcp->u_arg[3]); 161 tprintf(", %#lx", tcp->u_arg[4]); 162 } 163 } 164 return 0; 165 } 166 167 int 168 sys_create_module(struct tcb *tcp) 169 { 170 if (entering(tcp)) { 171 printpath(tcp, tcp->u_arg[0]); 172 tprintf(", %lu", tcp->u_arg[1]); 173 } 174 return RVAL_HEX; 175 } 176 177 int 178 sys_delete_module(struct tcb *tcp) 179 { 180 if (entering(tcp)) { 181 printstr(tcp, tcp->u_arg[0], -1); 182 tprints(", "); 183 printflags(delete_module_flags, tcp->u_arg[1], "O_???"); 184 } 185 return 0; 186 } 187 188 int 189 sys_init_module(struct tcb *tcp) 190 { 191 if (entering(tcp)) { 192 tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]); 193 printstr(tcp, tcp->u_arg[2], -1); 194 } 195 return 0; 196 } 197 198 #define MODULE_INIT_IGNORE_MODVERSIONS 1 199 #define MODULE_INIT_IGNORE_VERMAGIC 2 200 201 #include "xlat/module_init_flags.h" 202 203 int 204 sys_finit_module(struct tcb *tcp) 205 { 206 if (exiting(tcp)) 207 return 0; 208 209 /* file descriptor */ 210 printfd(tcp, tcp->u_arg[0]); 211 tprints(", "); 212 /* param_values */ 213 printstr(tcp, tcp->u_arg[1], -1); 214 tprints(", "); 215 /* flags */ 216 printflags(module_init_flags, tcp->u_arg[2], "MODULE_INIT_???"); 217 218 return 0; 219 } 220