File: patch-2.4.0-test13-pre2

package info (click to toggle)
modutils 2.4.26-1.2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,724 kB
  • ctags: 1,708
  • sloc: ansic: 16,932; sh: 2,998; makefile: 549; lex: 490; yacc: 375
file content (199 lines) | stat: -rw-r--r-- 7,773 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
Index: 0-test13-pre2.1/kernel/module.c
--- 0-test13-pre2.1/kernel/module.c Wed, 29 Nov 2000 15:29:52 +1100 kaos (linux-2.4/j/28_module.c 1.1.2.1.1.1.7.1.1.1.1.2 644)
+++ 0-test13-pre2.1(w)/kernel/module.c Sun, 17 Dec 2000 10:32:20 +1100 kaos (linux-2.4/j/28_module.c 1.1.2.1.1.1.7.1.1.1.1.2 644)
@@ -23,6 +23,7 @@
  * Fix sys_init_module race, Andrew Morton <andrewm@uow.edu.au> Oct 2000
  *     http://www.uwsg.iu.edu/hypermail/linux/kernel/0008.3/0379.html
  * Replace xxx_module_symbol with inter_module_xxx.  Keith Owens <kaos@ocs.com.au> Oct 2000
+ * Redefine persist_start/end as read_start/end.  Keith Owens <kaos@ocs.com.au> November 2000
  *
  * This source is covered by the GNU GPL, the same as all kernel sources.
  */
@@ -324,8 +325,54 @@ err0:
 	return error;
 }
 
+/* A negative mod_user_size to sys_init_module indicates that the caller wants
+ * to read data out of an existing module instead of initializing a new module.
+ * This usage overloads the meaning of sys_init_module, but the alternative was
+ * yet another system call and changes to glibc.  sys_init_module already does
+ * much of the work needed to read from an existing module so it was easier to
+ * extend that syscall.  Keith Owens <kaos@ocs.com.au> November 2000
+ */
+
+static int
+read_module_data(unsigned long mod_user_size, struct module *mod_user, struct module *mod_exist)
+{
+	struct module mod;
+	int error;
+	if (!try_inc_mod_count(mod_exist))
+		return(-ENOENT);
+	error = copy_from_user(&mod, mod_user, mod_user_size);
+	if (error) {
+		error = -EFAULT;
+		goto err1;
+	}
+	mod.size_of_struct = mod_user_size;
+	error = -EINVAL;
+	/* read_start and read_end must be present and must point inside the
+	 * existing module.  The module data from read_start to read_end-1 is
+	 * copied back to the user, immediately after the user's struct module.
+	 */
+	if (!mod_member_present(&mod, read_end) ||
+	    !mod_bound(mod.read_start, 0, mod_exist) ||
+	    !mod_bound(mod.read_end, -1, mod_exist) ||
+	    mod.read_start >= mod.read_end) {
+		printk(KERN_ERR "init_module: mod->read_xxx data out of bounds.\n");
+		goto err1;
+	}
+	error = copy_to_user(((char *)mod_user)+mod_user_size,
+		mod.read_start,
+		mod.read_end - mod.read_start);
+	if (error) {
+		error = -EFAULT;
+		goto err1;
+	}
+	error = 0;
+err1:
+	__MOD_DEC_USE_COUNT(mod_exist);
+	return(error);
+}
+
 /*
- * Initialize a module.
+ * Initialize a module or read from an existing module.
  */
 
 asmlinkage long
@@ -354,11 +401,23 @@ sys_init_module(const char *name_user, s
 	   for a newer kernel.  But don't over do it. */
 	if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
 		goto err1;
-	if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
-	    || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
+	/* A negative mod_user_size indicates reading data from an
+	 * existing module.
+	 */
+	for (i = 0; i < 2; ++i) {
+		if (mod_user_size >= (unsigned long)&((struct module *)0L)->read_start
+		    && mod_user_size <= sizeof(struct module) + 16*sizeof(void*))
+			break;
+		mod_user_size = -mod_user_size;	/* Try with negated size */
+	}
+	if (i == 1) {
+		/* Negative size, read from existing module */
+		error = read_module_data(mod_user_size, mod_user, mod);
+		goto err1;
+	}
+	if (i == 2) {
 		printk(KERN_ERR "init_module: Invalid module header size.\n"
-		       KERN_ERR "A new version of the modutils is likely "
-				"needed.\n");
+		       KERN_ERR "A new version of modutils may be needed.\n");
 		error = -EINVAL;
 		goto err1;
 	}
Index: 0-test13-pre2.1/include/linux/module.h
--- 0-test13-pre2.1/include/linux/module.h Tue, 12 Dec 2000 14:20:49 +1100 kaos (linux-2.4/W/33_module.h 1.1.2.1.2.1.2.1.2.1.1.3.1.1.1.1 644)
+++ 0-test13-pre2.1(w)/include/linux/module.h Sun, 17 Dec 2000 10:32:20 +1100 kaos (linux-2.4/W/33_module.h 1.1.2.1.2.1.2.1.2.1.1.3.1.1.1.1 644)
@@ -47,9 +47,6 @@ struct module_ref
 	struct module_ref *next_ref;
 };
 
-/* TBD */
-struct module_persist;
-
 struct module
 {
 	unsigned long size_of_struct;	/* == sizeof(module) */
@@ -81,8 +78,8 @@ struct module
 	/* Members past this point are extensions to the basic
 	   module support and are optional.  Use mod_member_present()
 	   to examine them.  */
-	const struct module_persist *persist_start;
-	const struct module_persist *persist_end;
+	const char *read_start;		/* Read data from existing module */
+	const char *read_end;
 	int (*can_unload)(void);
 	int runsize;			/* In modutils, not currently used */
 	const char *kallsyms_start;	/* All symbols for kernel debugging */
@@ -132,7 +129,7 @@ struct module_info
 
 /* Check if an address p with number of entries n is within the body of module m */
 #define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \
-	         (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
+		 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
 
 /* Backwards compatibility definition.  */
 
@@ -208,15 +205,43 @@ const char __module_device[] __attribute
 
 /* Used to verify parameters given to the module.  The TYPE arg should
    be a string in the following format:
-   	[min[-max]]{b,h,i,l,s}
+	[min[-max]]{b,h,i,l}[p]
+	[min[-max]]s
+	[min[-max]]csize[p]
    The MIN and MAX specifiers delimit the length of the array.  If MAX
    is omitted, it defaults to MIN; if both are omitted, the default is 1.
-   The final character is a type specifier:
+   The first character is a type specifier:
 	b	byte
 	h	short
 	i	int
 	l	long
-	s	string
+	s	string.  The variable must be char *foo or char *foo[max].
+		max is the number of strings, not the maximum string size, the
+		maximum string size is only limited by memory.  Strings cannot
+		be persistent data, use 'c' instead.
+
+   A type of 'c' is a special case, it must be followed by an array size.  The
+   variable must be char foo[size] or char foo[max][size], size includes the
+   trailing nul.
+
+   If the data is persistent (to be saved across module unload and reload),
+   append 'p' to the end of the TYPE string.
+
+   Strings (type 's') cannot be persistent data.  If no string is supplied then
+   the code has nowhere to store any new data.  Even if a string is supplied, it
+   may be too short to hold the new text.  Allocating a new string will not work.
+
+     char *parm_str;
+     MODULE_PARM(parm_str, "sp");	INVALID!
+     parm_str = (char *) kmalloc(...);
+
+   The resulting string is outside the module body and cannot be read by user
+   space utilities, see sys_init_module().  If you need to store text as a
+   persistent parameter then use type 'c', for example
+
+     #define PARM_STR_SIZE 65
+     char parm_str[PARM_STR_SIZE];
+     MODULE_PARM(parm_str, "c" __MODULE_STRING(PARM_STR_SIZE) "p");
 */
 
 #define MODULE_PARM(var,type)			\
@@ -249,12 +274,10 @@ static const struct gtype##_id * __modul
   __attribute__ ((unused)) = name
 #define MODULE_DEVICE_TABLE(type,name)		\
   MODULE_GENERIC_TABLE(type##_device,name)
-/* not put to .modinfo section to avoid section type conflicts */
-
-/* The attributes of a section are set the first time the section is
-   seen; we want .modinfo to not be allocated.  */
 
-__asm__(".section .modinfo\n\t.previous");
+#define MODULE_GENERIC_STRING(name, string) \
+static const char __module_generic_string_##name## [] \
+  __attribute__ ((section(".modstring"))) = #name "=" string;
 
 /* Define the module variable, and usage macros.  */
 extern struct module __this_module;
@@ -281,6 +304,7 @@ static const char __module_using_checksu
 #define MODULE_PARM_DESC(var,desc)
 #define MODULE_GENERIC_TABLE(gtype,name)
 #define MODULE_DEVICE_TABLE(type,name)
+#define MODULE_GENERIC_STRING(name, string)
 
 #ifndef __GENKSYMS__