• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@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
sys_query_module(struct tcb * tcp)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
sys_create_module(struct tcb * tcp)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
sys_delete_module(struct tcb * tcp)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
sys_init_module(struct tcb * tcp)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
sys_finit_module(struct tcb * tcp)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