aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c216
-rw-r--r--kernel/auditfilter.c9
-rw-r--r--kernel/auditsc.c40
-rw-r--r--kernel/kmod.c120
-rw-r--r--kernel/module.c47
-rw-r--r--kernel/params.c29
-rw-r--r--kernel/printk.c2
7 files changed, 367 insertions, 96 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index d9b690ac684b..76c9a11b72d6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -2,7 +2,7 @@
2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. 2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
3 * System-call specific features have moved to auditsc.c 3 * System-call specific features have moved to auditsc.c
4 * 4 *
5 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 5 * Copyright 2003-2007 Red Hat Inc., Durham, North Carolina.
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -65,7 +65,9 @@
65 * (Initialization happens after skb_init is called.) */ 65 * (Initialization happens after skb_init is called.) */
66static int audit_initialized; 66static int audit_initialized;
67 67
68/* No syscall auditing will take place unless audit_enabled != 0. */ 68/* 0 - no auditing
69 * 1 - auditing enabled
70 * 2 - auditing enabled and configuration is locked/unchangeable. */
69int audit_enabled; 71int audit_enabled;
70 72
71/* Default state when kernel boots without any parameters. */ 73/* Default state when kernel boots without any parameters. */
@@ -239,102 +241,150 @@ void audit_log_lost(const char *message)
239 241
240static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) 242static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid)
241{ 243{
242 int old = audit_rate_limit; 244 int res, rc = 0, old = audit_rate_limit;
245
246 /* check if we are locked */
247 if (audit_enabled == 2)
248 res = 0;
249 else
250 res = 1;
243 251
244 if (sid) { 252 if (sid) {
245 char *ctx = NULL; 253 char *ctx = NULL;
246 u32 len; 254 u32 len;
247 int rc; 255 if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
248 if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
249 return rc;
250 else
251 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 256 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
252 "audit_rate_limit=%d old=%d by auid=%u subj=%s", 257 "audit_rate_limit=%d old=%d by auid=%u"
253 limit, old, loginuid, ctx); 258 " subj=%s res=%d",
254 kfree(ctx); 259 limit, old, loginuid, ctx, res);
255 } else 260 kfree(ctx);
256 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 261 } else
257 "audit_rate_limit=%d old=%d by auid=%u", 262 res = 0; /* Something weird, deny request */
258 limit, old, loginuid); 263 }
259 audit_rate_limit = limit; 264 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
260 return 0; 265 "audit_rate_limit=%d old=%d by auid=%u res=%d",
266 limit, old, loginuid, res);
267
268 /* If we are allowed, make the change */
269 if (res == 1)
270 audit_rate_limit = limit;
271 /* Not allowed, update reason */
272 else if (rc == 0)
273 rc = -EPERM;
274 return rc;
261} 275}
262 276
263static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) 277static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid)
264{ 278{
265 int old = audit_backlog_limit; 279 int res, rc = 0, old = audit_backlog_limit;
280
281 /* check if we are locked */
282 if (audit_enabled == 2)
283 res = 0;
284 else
285 res = 1;
266 286
267 if (sid) { 287 if (sid) {
268 char *ctx = NULL; 288 char *ctx = NULL;
269 u32 len; 289 u32 len;
270 int rc; 290 if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
271 if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
272 return rc;
273 else
274 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 291 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
275 "audit_backlog_limit=%d old=%d by auid=%u subj=%s", 292 "audit_backlog_limit=%d old=%d by auid=%u"
276 limit, old, loginuid, ctx); 293 " subj=%s res=%d",
277 kfree(ctx); 294 limit, old, loginuid, ctx, res);
278 } else 295 kfree(ctx);
279 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 296 } else
280 "audit_backlog_limit=%d old=%d by auid=%u", 297 res = 0; /* Something weird, deny request */
281 limit, old, loginuid); 298 }
282 audit_backlog_limit = limit; 299 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
283 return 0; 300 "audit_backlog_limit=%d old=%d by auid=%u res=%d",
301 limit, old, loginuid, res);
302
303 /* If we are allowed, make the change */
304 if (res == 1)
305 audit_backlog_limit = limit;
306 /* Not allowed, update reason */
307 else if (rc == 0)
308 rc = -EPERM;
309 return rc;
284} 310}
285 311
286static int audit_set_enabled(int state, uid_t loginuid, u32 sid) 312static int audit_set_enabled(int state, uid_t loginuid, u32 sid)
287{ 313{
288 int old = audit_enabled; 314 int res, rc = 0, old = audit_enabled;
289 315
290 if (state != 0 && state != 1) 316 if (state < 0 || state > 2)
291 return -EINVAL; 317 return -EINVAL;
292 318
319 /* check if we are locked */
320 if (audit_enabled == 2)
321 res = 0;
322 else
323 res = 1;
324
293 if (sid) { 325 if (sid) {
294 char *ctx = NULL; 326 char *ctx = NULL;
295 u32 len; 327 u32 len;
296 int rc; 328 if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
297 if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
298 return rc;
299 else
300 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 329 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
301 "audit_enabled=%d old=%d by auid=%u subj=%s", 330 "audit_enabled=%d old=%d by auid=%u"
302 state, old, loginuid, ctx); 331 " subj=%s res=%d",
303 kfree(ctx); 332 state, old, loginuid, ctx, res);
304 } else 333 kfree(ctx);
305 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 334 } else
306 "audit_enabled=%d old=%d by auid=%u", 335 res = 0; /* Something weird, deny request */
307 state, old, loginuid); 336 }
308 audit_enabled = state; 337 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
309 return 0; 338 "audit_enabled=%d old=%d by auid=%u res=%d",
339 state, old, loginuid, res);
340
341 /* If we are allowed, make the change */
342 if (res == 1)
343 audit_enabled = state;
344 /* Not allowed, update reason */
345 else if (rc == 0)
346 rc = -EPERM;
347 return rc;
310} 348}
311 349
312static int audit_set_failure(int state, uid_t loginuid, u32 sid) 350static int audit_set_failure(int state, uid_t loginuid, u32 sid)
313{ 351{
314 int old = audit_failure; 352 int res, rc = 0, old = audit_failure;
315 353
316 if (state != AUDIT_FAIL_SILENT 354 if (state != AUDIT_FAIL_SILENT
317 && state != AUDIT_FAIL_PRINTK 355 && state != AUDIT_FAIL_PRINTK
318 && state != AUDIT_FAIL_PANIC) 356 && state != AUDIT_FAIL_PANIC)
319 return -EINVAL; 357 return -EINVAL;
320 358
359 /* check if we are locked */
360 if (audit_enabled == 2)
361 res = 0;
362 else
363 res = 1;
364
321 if (sid) { 365 if (sid) {
322 char *ctx = NULL; 366 char *ctx = NULL;
323 u32 len; 367 u32 len;
324 int rc; 368 if ((rc = selinux_sid_to_string(sid, &ctx, &len)) == 0) {
325 if ((rc = selinux_sid_to_string(sid, &ctx, &len)))
326 return rc;
327 else
328 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 369 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
329 "audit_failure=%d old=%d by auid=%u subj=%s", 370 "audit_failure=%d old=%d by auid=%u"
330 state, old, loginuid, ctx); 371 " subj=%s res=%d",
331 kfree(ctx); 372 state, old, loginuid, ctx, res);
332 } else 373 kfree(ctx);
333 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 374 } else
334 "audit_failure=%d old=%d by auid=%u", 375 res = 0; /* Something weird, deny request */
335 state, old, loginuid); 376 }
336 audit_failure = state; 377 audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
337 return 0; 378 "audit_failure=%d old=%d by auid=%u res=%d",
379 state, old, loginuid, res);
380
381 /* If we are allowed, make the change */
382 if (res == 1)
383 audit_failure = state;
384 /* Not allowed, update reason */
385 else if (rc == 0)
386 rc = -EPERM;
387 return rc;
338} 388}
339 389
340static int kauditd_thread(void *dummy) 390static int kauditd_thread(void *dummy)
@@ -599,6 +649,30 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
599 case AUDIT_DEL: 649 case AUDIT_DEL:
600 if (nlmsg_len(nlh) < sizeof(struct audit_rule)) 650 if (nlmsg_len(nlh) < sizeof(struct audit_rule))
601 return -EINVAL; 651 return -EINVAL;
652 if (audit_enabled == 2) {
653 ab = audit_log_start(NULL, GFP_KERNEL,
654 AUDIT_CONFIG_CHANGE);
655 if (ab) {
656 audit_log_format(ab,
657 "pid=%d uid=%u auid=%u",
658 pid, uid, loginuid);
659 if (sid) {
660 if (selinux_sid_to_string(
661 sid, &ctx, &len)) {
662 audit_log_format(ab,
663 " ssid=%u", sid);
664 /* Maybe call audit_panic? */
665 } else
666 audit_log_format(ab,
667 " subj=%s", ctx);
668 kfree(ctx);
669 }
670 audit_log_format(ab, " audit_enabled=%d res=0",
671 audit_enabled);
672 audit_log_end(ab);
673 }
674 return -EPERM;
675 }
602 /* fallthrough */ 676 /* fallthrough */
603 case AUDIT_LIST: 677 case AUDIT_LIST:
604 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 678 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
@@ -609,6 +683,30 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
609 case AUDIT_DEL_RULE: 683 case AUDIT_DEL_RULE:
610 if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) 684 if (nlmsg_len(nlh) < sizeof(struct audit_rule_data))
611 return -EINVAL; 685 return -EINVAL;
686 if (audit_enabled == 2) {
687 ab = audit_log_start(NULL, GFP_KERNEL,
688 AUDIT_CONFIG_CHANGE);
689 if (ab) {
690 audit_log_format(ab,
691 "pid=%d uid=%u auid=%u",
692 pid, uid, loginuid);
693 if (sid) {
694 if (selinux_sid_to_string(
695 sid, &ctx, &len)) {
696 audit_log_format(ab,
697 " ssid=%u", sid);
698 /* Maybe call audit_panic? */
699 } else
700 audit_log_format(ab,
701 " subj=%s", ctx);
702 kfree(ctx);
703 }
704 audit_log_format(ab, " audit_enabled=%d res=0",
705 audit_enabled);
706 audit_log_end(ab);
707 }
708 return -EPERM;
709 }
612 /* fallthrough */ 710 /* fallthrough */
613 case AUDIT_LIST_RULES: 711 case AUDIT_LIST_RULES:
614 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 712 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 87865f8b4ce3..3749193aed8c 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -937,9 +937,10 @@ static void audit_update_watch(struct audit_parent *parent,
937 } 937 }
938 938
939 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); 939 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
940 audit_log_format(ab, "audit updated rules specifying path="); 940 audit_log_format(ab, "op=updated rules specifying path=");
941 audit_log_untrustedstring(ab, owatch->path); 941 audit_log_untrustedstring(ab, owatch->path);
942 audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino); 942 audit_log_format(ab, " with dev=%u ino=%lu\n", dev, ino);
943 audit_log_format(ab, " list=%d res=1", r->listnr);
943 audit_log_end(ab); 944 audit_log_end(ab);
944 945
945 audit_remove_watch(owatch); 946 audit_remove_watch(owatch);
@@ -969,14 +970,14 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
969 e = container_of(r, struct audit_entry, rule); 970 e = container_of(r, struct audit_entry, rule);
970 971
971 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); 972 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
972 audit_log_format(ab, "audit implicitly removed rule path="); 973 audit_log_format(ab, "op=remove rule path=");
973 audit_log_untrustedstring(ab, w->path); 974 audit_log_untrustedstring(ab, w->path);
974 if (r->filterkey) { 975 if (r->filterkey) {
975 audit_log_format(ab, " key="); 976 audit_log_format(ab, " key=");
976 audit_log_untrustedstring(ab, r->filterkey); 977 audit_log_untrustedstring(ab, r->filterkey);
977 } else 978 } else
978 audit_log_format(ab, " key=(null)"); 979 audit_log_format(ab, " key=(null)");
979 audit_log_format(ab, " list=%d", r->listnr); 980 audit_log_format(ab, " list=%d res=1", r->listnr);
980 audit_log_end(ab); 981 audit_log_end(ab);
981 982
982 list_del(&r->rlist); 983 list_del(&r->rlist);
@@ -1410,7 +1411,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
1410 audit_log_format(ab, " subj=%s", ctx); 1411 audit_log_format(ab, " subj=%s", ctx);
1411 kfree(ctx); 1412 kfree(ctx);
1412 } 1413 }
1413 audit_log_format(ab, " %s rule key=", action); 1414 audit_log_format(ab, " op=%s rule key=", action);
1414 if (rule->filterkey) 1415 if (rule->filterkey)
1415 audit_log_untrustedstring(ab, rule->filterkey); 1416 audit_log_untrustedstring(ab, rule->filterkey);
1416 else 1417 else
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 298897559ca4..359955800dd2 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -170,6 +170,11 @@ struct audit_aux_data_sockaddr {
170 char a[0]; 170 char a[0];
171}; 171};
172 172
173struct audit_aux_data_fd_pair {
174 struct audit_aux_data d;
175 int fd[2];
176};
177
173struct audit_aux_data_path { 178struct audit_aux_data_path {
174 struct audit_aux_data d; 179 struct audit_aux_data d;
175 struct dentry *dentry; 180 struct dentry *dentry;
@@ -961,6 +966,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
961 audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); 966 audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
962 break; } 967 break; }
963 968
969 case AUDIT_FD_PAIR: {
970 struct audit_aux_data_fd_pair *axs = (void *)aux;
971 audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
972 break; }
973
964 } 974 }
965 audit_log_end(ab); 975 audit_log_end(ab);
966 } 976 }
@@ -1815,6 +1825,36 @@ int audit_socketcall(int nargs, unsigned long *args)
1815} 1825}
1816 1826
1817/** 1827/**
1828 * __audit_fd_pair - record audit data for pipe and socketpair
1829 * @fd1: the first file descriptor
1830 * @fd2: the second file descriptor
1831 *
1832 * Returns 0 for success or NULL context or < 0 on error.
1833 */
1834int __audit_fd_pair(int fd1, int fd2)
1835{
1836 struct audit_context *context = current->audit_context;
1837 struct audit_aux_data_fd_pair *ax;
1838
1839 if (likely(!context)) {
1840 return 0;
1841 }
1842
1843 ax = kmalloc(sizeof(*ax), GFP_KERNEL);
1844 if (!ax) {
1845 return -ENOMEM;
1846 }
1847
1848 ax->fd[0] = fd1;
1849 ax->fd[1] = fd2;
1850
1851 ax->d.type = AUDIT_FD_PAIR;
1852 ax->d.next = context->aux;
1853 context->aux = (void *)ax;
1854 return 0;
1855}
1856
1857/**
1818 * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto 1858 * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
1819 * @len: data length in user space 1859 * @len: data length in user space
1820 * @a: data address in kernel space 1860 * @a: data address in kernel space
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 796276141e51..9f923f8ce6a0 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -36,6 +36,8 @@
36#include <linux/resource.h> 36#include <linux/resource.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38 38
39extern int delete_module(const char *name, unsigned int flags);
40
39extern int max_threads; 41extern int max_threads;
40 42
41static struct workqueue_struct *khelper_wq; 43static struct workqueue_struct *khelper_wq;
@@ -46,6 +48,7 @@ static struct workqueue_struct *khelper_wq;
46 modprobe_path is set via /proc/sys. 48 modprobe_path is set via /proc/sys.
47*/ 49*/
48char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; 50char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
51struct module_kobject kmod_mk;
49 52
50/** 53/**
51 * request_module - try to load a kernel module 54 * request_module - try to load a kernel module
@@ -75,6 +78,11 @@ int request_module(const char *fmt, ...)
75 static atomic_t kmod_concurrent = ATOMIC_INIT(0); 78 static atomic_t kmod_concurrent = ATOMIC_INIT(0);
76#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ 79#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
77 static int kmod_loop_msg; 80 static int kmod_loop_msg;
81 char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
82 char *uevent_envp[2] = {
83 modalias,
84 NULL
85 };
78 86
79 va_start(args, fmt); 87 va_start(args, fmt);
80 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); 88 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -82,6 +90,12 @@ int request_module(const char *fmt, ...)
82 if (ret >= MODULE_NAME_LEN) 90 if (ret >= MODULE_NAME_LEN)
83 return -ENAMETOOLONG; 91 return -ENAMETOOLONG;
84 92
93 strcpy(&modalias[strlen("MODALIAS=")], module_name);
94 kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
95
96 if (modprobe_path[0] == '\0')
97 goto out;
98
85 /* If modprobe needs a service that is in a module, we get a recursive 99 /* If modprobe needs a service that is in a module, we get a recursive
86 * loop. Limit the number of running kmod threads to max_threads/2 or 100 * loop. Limit the number of running kmod threads to max_threads/2 or
87 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method 101 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
@@ -108,9 +122,115 @@ int request_module(const char *fmt, ...)
108 122
109 ret = call_usermodehelper(modprobe_path, argv, envp, 1); 123 ret = call_usermodehelper(modprobe_path, argv, envp, 1);
110 atomic_dec(&kmod_concurrent); 124 atomic_dec(&kmod_concurrent);
125out:
111 return ret; 126 return ret;
112} 127}
113EXPORT_SYMBOL(request_module); 128EXPORT_SYMBOL(request_module);
129
130static ssize_t store_mod_request(struct module_attribute *mattr,
131 struct module *mod,
132 const char *buffer, size_t count)
133{
134 char name[MODULE_NAME_LEN];
135 int ret;
136
137 if (count < 1 || count+1 > MODULE_NAME_LEN)
138 return -EINVAL;
139 memcpy(name, buffer, count);
140 name[count] = '\0';
141 if (name[count-1] == '\n')
142 name[count-1] = '\0';
143
144 ret = request_module(name);
145 if (ret < 0)
146 return ret;
147 return count;
148}
149
150static struct module_attribute mod_request = {
151 .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
152 .store = store_mod_request,
153};
154
155#ifdef CONFIG_MODULE_UNLOAD
156static ssize_t store_mod_unload(struct module_attribute *mattr,
157 struct module *mod,
158 const char *buffer, size_t count)
159{
160 char name[MODULE_NAME_LEN];
161 int ret;
162
163 if (count < 1 || count+1 > MODULE_NAME_LEN)
164 return -EINVAL;
165 memcpy(name, buffer, count);
166 name[count] = '\0';
167 if (name[count-1] == '\n')
168 name[count-1] = '\0';
169
170 ret = delete_module(name, O_NONBLOCK);
171 if (ret < 0)
172 return ret;
173 return count;
174}
175
176static struct module_attribute mod_unload = {
177 .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
178 .store = store_mod_unload,
179};
180#endif
181
182static ssize_t show_mod_request_helper(struct module_attribute *mattr,
183 struct module *mod,
184 char *buffer)
185{
186 return sprintf(buffer, "%s\n", modprobe_path);
187}
188
189static ssize_t store_mod_request_helper(struct module_attribute *mattr,
190 struct module *mod,
191 const char *buffer, size_t count)
192{
193 if (count < 1 || count+1 > KMOD_PATH_LEN)
194 return -EINVAL;
195 memcpy(modprobe_path, buffer, count);
196 modprobe_path[count] = '\0';
197 if (modprobe_path[count-1] == '\n')
198 modprobe_path[count-1] = '\0';
199 return count;
200}
201
202static struct module_attribute mod_request_helper = {
203 .attr = {
204 .name = "mod_request_helper",
205 .mode = S_IWUSR | S_IRUGO,
206 .owner = THIS_MODULE
207 },
208 .show = show_mod_request_helper,
209 .store = store_mod_request_helper,
210};
211
212void __init kmod_sysfs_init(void)
213{
214 int ret;
215
216 kmod_mk.mod = THIS_MODULE;
217 kobj_set_kset_s(&kmod_mk, module_subsys);
218 kobject_set_name(&kmod_mk.kobj, "kmod");
219 kobject_init(&kmod_mk.kobj);
220 ret = kobject_add(&kmod_mk.kobj);
221 if (ret < 0)
222 goto out;
223
224 ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
225 ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
226#ifdef CONFIG_MODULE_UNLOAD
227 ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
228#endif
229
230 kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
231out:
232 return;
233}
114#endif /* CONFIG_KMOD */ 234#endif /* CONFIG_KMOD */
115 235
116struct subprocess_info { 236struct subprocess_info {
diff --git a/kernel/module.c b/kernel/module.c
index 8a94e054230c..8c25b1a04fa6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -653,20 +653,11 @@ static void wait_for_zero_refcount(struct module *mod)
653 mutex_lock(&module_mutex); 653 mutex_lock(&module_mutex);
654} 654}
655 655
656asmlinkage long 656int delete_module(const char *name, unsigned int flags)
657sys_delete_module(const char __user *name_user, unsigned int flags)
658{ 657{
659 struct module *mod; 658 struct module *mod;
660 char name[MODULE_NAME_LEN];
661 int ret, forced = 0; 659 int ret, forced = 0;
662 660
663 if (!capable(CAP_SYS_MODULE))
664 return -EPERM;
665
666 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
667 return -EFAULT;
668 name[MODULE_NAME_LEN-1] = '\0';
669
670 if (mutex_lock_interruptible(&module_mutex) != 0) 661 if (mutex_lock_interruptible(&module_mutex) != 0)
671 return -EINTR; 662 return -EINTR;
672 663
@@ -727,6 +718,21 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
727 return ret; 718 return ret;
728} 719}
729 720
721asmlinkage long
722sys_delete_module(const char __user *name_user, unsigned int flags)
723{
724 char name[MODULE_NAME_LEN];
725
726 if (!capable(CAP_SYS_MODULE))
727 return -EPERM;
728
729 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
730 return -EFAULT;
731 name[MODULE_NAME_LEN-1] = '\0';
732
733 return delete_module(name, flags);
734}
735
730static void print_unload_info(struct seq_file *m, struct module *mod) 736static void print_unload_info(struct seq_file *m, struct module *mod)
731{ 737{
732 struct module_use *use; 738 struct module_use *use;
@@ -1068,7 +1074,8 @@ static inline void remove_sect_attrs(struct module *mod)
1068} 1074}
1069#endif /* CONFIG_KALLSYMS */ 1075#endif /* CONFIG_KALLSYMS */
1070 1076
1071static int module_add_modinfo_attrs(struct module *mod) 1077#ifdef CONFIG_SYSFS
1078int module_add_modinfo_attrs(struct module *mod)
1072{ 1079{
1073 struct module_attribute *attr; 1080 struct module_attribute *attr;
1074 struct module_attribute *temp_attr; 1081 struct module_attribute *temp_attr;
@@ -1094,7 +1101,7 @@ static int module_add_modinfo_attrs(struct module *mod)
1094 return error; 1101 return error;
1095} 1102}
1096 1103
1097static void module_remove_modinfo_attrs(struct module *mod) 1104void module_remove_modinfo_attrs(struct module *mod)
1098{ 1105{
1099 struct module_attribute *attr; 1106 struct module_attribute *attr;
1100 int i; 1107 int i;
@@ -1109,8 +1116,10 @@ static void module_remove_modinfo_attrs(struct module *mod)
1109 } 1116 }
1110 kfree(mod->modinfo_attrs); 1117 kfree(mod->modinfo_attrs);
1111} 1118}
1119#endif
1112 1120
1113static int mod_sysfs_init(struct module *mod) 1121#ifdef CONFIG_SYSFS
1122int mod_sysfs_init(struct module *mod)
1114{ 1123{
1115 int err; 1124 int err;
1116 1125
@@ -1133,7 +1142,7 @@ out:
1133 return err; 1142 return err;
1134} 1143}
1135 1144
1136static int mod_sysfs_setup(struct module *mod, 1145int mod_sysfs_setup(struct module *mod,
1137 struct kernel_param *kparam, 1146 struct kernel_param *kparam,
1138 unsigned int num_params) 1147 unsigned int num_params)
1139{ 1148{
@@ -1169,16 +1178,14 @@ out_unreg:
1169out: 1178out:
1170 return err; 1179 return err;
1171} 1180}
1181#endif
1172 1182
1173static void mod_kobject_remove(struct module *mod) 1183static void mod_kobject_remove(struct module *mod)
1174{ 1184{
1175 module_remove_modinfo_attrs(mod); 1185 module_remove_modinfo_attrs(mod);
1176 module_param_sysfs_remove(mod); 1186 module_param_sysfs_remove(mod);
1177 if (mod->mkobj.drivers_dir) 1187 kobject_unregister(mod->mkobj.drivers_dir);
1178 kobject_unregister(mod->mkobj.drivers_dir); 1188 kobject_unregister(mod->holders_dir);
1179 if (mod->holders_dir)
1180 kobject_unregister(mod->holders_dir);
1181
1182 kobject_unregister(&mod->mkobj.kobj); 1189 kobject_unregister(&mod->mkobj.kobj);
1183} 1190}
1184 1191
@@ -2345,6 +2352,7 @@ void print_modules(void)
2345 printk("\n"); 2352 printk("\n");
2346} 2353}
2347 2354
2355#ifdef CONFIG_SYSFS
2348static char *make_driver_name(struct device_driver *drv) 2356static char *make_driver_name(struct device_driver *drv)
2349{ 2357{
2350 char *driver_name; 2358 char *driver_name;
@@ -2419,6 +2427,7 @@ void module_remove_driver(struct device_driver *drv)
2419 } 2427 }
2420} 2428}
2421EXPORT_SYMBOL(module_remove_driver); 2429EXPORT_SYMBOL(module_remove_driver);
2430#endif
2422 2431
2423#ifdef CONFIG_MODVERSIONS 2432#ifdef CONFIG_MODVERSIONS
2424/* Generate the signature for struct module here, too, for modversions. */ 2433/* Generate the signature for struct module here, too, for modversions. */
diff --git a/kernel/params.c b/kernel/params.c
index 553cf7d6a4be..7a751570b56d 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -30,8 +30,6 @@
30#define DEBUGP(fmt, a...) 30#define DEBUGP(fmt, a...)
31#endif 31#endif
32 32
33static struct kobj_type module_ktype;
34
35static inline char dash2underscore(char c) 33static inline char dash2underscore(char c)
36{ 34{
37 if (c == '-') 35 if (c == '-')
@@ -391,6 +389,7 @@ struct module_param_attrs
391 struct param_attribute attrs[0]; 389 struct param_attribute attrs[0];
392}; 390};
393 391
392#ifdef CONFIG_SYSFS
394#define to_param_attr(n) container_of(n, struct param_attribute, mattr); 393#define to_param_attr(n) container_of(n, struct param_attribute, mattr);
395 394
396static ssize_t param_attr_show(struct module_attribute *mattr, 395static ssize_t param_attr_show(struct module_attribute *mattr,
@@ -426,6 +425,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
426 return len; 425 return len;
427 return err; 426 return err;
428} 427}
428#endif
429 429
430#ifdef CONFIG_MODULES 430#ifdef CONFIG_MODULES
431#define __modinit 431#define __modinit
@@ -433,6 +433,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
433#define __modinit __init 433#define __modinit __init
434#endif 434#endif
435 435
436#ifdef CONFIG_SYSFS
436/* 437/*
437 * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME 438 * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
438 * @mk: struct module_kobject (contains parent kobject) 439 * @mk: struct module_kobject (contains parent kobject)
@@ -500,9 +501,7 @@ param_sysfs_setup(struct module_kobject *mk,
500 return mp; 501 return mp;
501} 502}
502 503
503
504#ifdef CONFIG_MODULES 504#ifdef CONFIG_MODULES
505
506/* 505/*
507 * module_param_sysfs_setup - setup sysfs support for one module 506 * module_param_sysfs_setup - setup sysfs support for one module
508 * @mod: module 507 * @mod: module
@@ -625,7 +624,6 @@ static void __init param_sysfs_builtin(void)
625 624
626 625
627/* module-related sysfs stuff */ 626/* module-related sysfs stuff */
628#ifdef CONFIG_SYSFS
629 627
630#define to_module_attr(n) container_of(n, struct module_attribute, attr); 628#define to_module_attr(n) container_of(n, struct module_attribute, attr);
631#define to_module_kobject(n) container_of(n, struct module_kobject, kobj); 629#define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
@@ -673,6 +671,8 @@ static struct sysfs_ops module_sysfs_ops = {
673 .store = module_attr_store, 671 .store = module_attr_store,
674}; 672};
675 673
674static struct kobj_type module_ktype;
675
676static int uevent_filter(struct kset *kset, struct kobject *kobj) 676static int uevent_filter(struct kset *kset, struct kobject *kobj)
677{ 677{
678 struct kobj_type *ktype = get_ktype(kobj); 678 struct kobj_type *ktype = get_ktype(kobj);
@@ -686,19 +686,12 @@ static struct kset_uevent_ops module_uevent_ops = {
686 .filter = uevent_filter, 686 .filter = uevent_filter,
687}; 687};
688 688
689#else 689decl_subsys(module, &module_ktype, &module_uevent_ops);
690static struct sysfs_ops module_sysfs_ops = {
691 .show = NULL,
692 .store = NULL,
693};
694#endif
695 690
696static struct kobj_type module_ktype = { 691static struct kobj_type module_ktype = {
697 .sysfs_ops = &module_sysfs_ops, 692 .sysfs_ops = &module_sysfs_ops,
698}; 693};
699 694
700decl_subsys(module, &module_ktype, &module_uevent_ops);
701
702/* 695/*
703 * param_sysfs_init - wrapper for built-in params support 696 * param_sysfs_init - wrapper for built-in params support
704 */ 697 */
@@ -714,11 +707,21 @@ static int __init param_sysfs_init(void)
714 } 707 }
715 708
716 param_sysfs_builtin(); 709 param_sysfs_builtin();
710 kmod_sysfs_init();
717 711
718 return 0; 712 return 0;
719} 713}
720subsys_initcall(param_sysfs_init); 714subsys_initcall(param_sysfs_init);
721 715
716#else
717#if 0
718static struct sysfs_ops module_sysfs_ops = {
719 .show = NULL,
720 .store = NULL,
721};
722#endif
723#endif
724
722EXPORT_SYMBOL(param_set_byte); 725EXPORT_SYMBOL(param_set_byte);
723EXPORT_SYMBOL(param_get_byte); 726EXPORT_SYMBOL(param_get_byte);
724EXPORT_SYMBOL(param_set_short); 727EXPORT_SYMBOL(param_set_short);
diff --git a/kernel/printk.c b/kernel/printk.c
index 0c151877ff71..4b47e59248df 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -54,7 +54,7 @@ int console_printk[4] = {
54}; 54};
55 55
56/* 56/*
57 * Low lever drivers may need that to know if they can schedule in 57 * Low level drivers may need that to know if they can schedule in
58 * their unblank() callback or not. So let's export it. 58 * their unblank() callback or not. So let's export it.
59 */ 59 */
60int oops_in_progress; 60int oops_in_progress;