| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: kern_module.c,v 1.46 2009/06/07 09:47:31 jnemeth Exp $ */ | | 1 | /* $NetBSD: kern_module.c,v 1.47 2009/06/09 19:09:03 jnemeth Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software developed for The NetBSD Foundation | | 7 | * This code is derived from software developed for The NetBSD Foundation |
8 | * by Andrew Doran. | | 8 | * by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -24,27 +24,27 @@ | | | @@ -24,27 +24,27 @@ |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Kernel module support. | | 33 | * Kernel module support. |
34 | */ | | 34 | */ |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | __KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.46 2009/06/07 09:47:31 jnemeth Exp $"); | | 37 | __KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.47 2009/06/09 19:09:03 jnemeth Exp $"); |
38 | | | 38 | |
39 | #ifdef _KERNEL_OPT | | 39 | #ifdef _KERNEL_OPT |
40 | #include "opt_ddb.h" | | 40 | #include "opt_ddb.h" |
41 | #include "opt_modular.h" | | 41 | #include "opt_modular.h" |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <sys/param.h> | | 44 | #include <sys/param.h> |
45 | #include <sys/systm.h> | | 45 | #include <sys/systm.h> |
46 | #include <sys/kernel.h> | | 46 | #include <sys/kernel.h> |
47 | #include <sys/fcntl.h> | | 47 | #include <sys/fcntl.h> |
48 | #include <sys/proc.h> | | 48 | #include <sys/proc.h> |
49 | #include <sys/kauth.h> | | 49 | #include <sys/kauth.h> |
50 | #include <sys/kobj.h> | | 50 | #include <sys/kobj.h> |
| @@ -85,26 +85,27 @@ __link_set_add_rodata(modules, module_du | | | @@ -85,26 +85,27 @@ __link_set_add_rodata(modules, module_du |
85 | static module_t *module_lookup(const char *); | | 85 | static module_t *module_lookup(const char *); |
86 | static int module_do_load(const char *, bool, int, prop_dictionary_t, | | 86 | static int module_do_load(const char *, bool, int, prop_dictionary_t, |
87 | module_t **, modclass_t class, bool); | | 87 | module_t **, modclass_t class, bool); |
88 | static int module_do_unload(const char *); | | 88 | static int module_do_unload(const char *); |
89 | static void module_error(const char *, ...) | | 89 | static void module_error(const char *, ...) |
90 | __attribute__((__format__(__printf__,1,2))); | | 90 | __attribute__((__format__(__printf__,1,2))); |
91 | static void module_print(const char *, ...) | | 91 | static void module_print(const char *, ...) |
92 | __attribute__((__format__(__printf__,1,2))); | | 92 | __attribute__((__format__(__printf__,1,2))); |
93 | static int module_do_builtin(const char *, module_t **); | | 93 | static int module_do_builtin(const char *, module_t **); |
94 | static int module_fetch_info(module_t *); | | 94 | static int module_fetch_info(module_t *); |
95 | static void module_thread(void *); | | 95 | static void module_thread(void *); |
96 | static int module_load_plist_file(const char *, const bool, void **, | | 96 | static int module_load_plist_file(const char *, const bool, void **, |
97 | size_t *); | | 97 | size_t *); |
| | | 98 | static bool module_merge_dicts(prop_dictionary_t, const prop_dictionary_t); |
98 | | | 99 | |
99 | /* | | 100 | /* |
100 | * module_error: | | 101 | * module_error: |
101 | * | | 102 | * |
102 | * Utility function: log an error. | | 103 | * Utility function: log an error. |
103 | */ | | 104 | */ |
104 | static void | | 105 | static void |
105 | module_error(const char *fmt, ...) | | 106 | module_error(const char *fmt, ...) |
106 | { | | 107 | { |
107 | va_list ap; | | 108 | va_list ap; |
108 | | | 109 | |
109 | va_start(ap, fmt); | | 110 | va_start(ap, fmt); |
110 | printf("WARNING: module error: "); | | 111 | printf("WARNING: module error: "); |
| @@ -787,40 +788,44 @@ module_do_load(const char *name, bool is | | | @@ -787,40 +788,44 @@ module_do_load(const char *name, bool is |
787 | /* | | 788 | /* |
788 | * Load and process <module>.prop if it exists. | | 789 | * Load and process <module>.prop if it exists. |
789 | */ | | 790 | */ |
790 | if (mod->mod_source == MODULE_SOURCE_FILESYS) { | | 791 | if (mod->mod_source == MODULE_SOURCE_FILESYS) { |
791 | error = module_load_plist_file(path, nochroot, &plist, | | 792 | error = module_load_plist_file(path, nochroot, &plist, |
792 | &plistlen); | | 793 | &plistlen); |
793 | if (error != 0) { | | 794 | if (error != 0) { |
794 | module_print("plist load returned error %d for `%s'", | | 795 | module_print("plist load returned error %d for `%s'", |
795 | error, path); | | 796 | error, path); |
796 | } else { | | 797 | } else { |
797 | filedict = prop_dictionary_internalize(plist); | | 798 | filedict = prop_dictionary_internalize(plist); |
798 | if (filedict == NULL) { | | 799 | if (filedict == NULL) { |
799 | error = EINVAL; | | 800 | error = EINVAL; |
| | | 801 | } else if (!module_merge_dicts(filedict, props)) { |
| | | 802 | error = EINVAL; |
| | | 803 | prop_object_release(filedict); |
| | | 804 | filedict = NULL; |
800 | } | | 805 | } |
801 | } | | 806 | } |
802 | if (plist != NULL) { | | 807 | if (plist != NULL) { |
803 | kmem_free(plist, PAGE_SIZE); | | 808 | kmem_free(plist, PAGE_SIZE); |
804 | } | | 809 | } |
805 | if ((error != 0) && (error != ENOENT)) { | | 810 | if ((error != 0) && (error != ENOENT)) { |
806 | goto fail; | | 811 | goto fail; |
807 | } | | 812 | } |
808 | } | | 813 | } |
809 | | | 814 | |
810 | KASSERT(module_active == NULL); | | 815 | KASSERT(module_active == NULL); |
811 | module_active = mod; | | 816 | module_active = mod; |
812 | error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ? | | 817 | error = (*mi->mi_modcmd)(MODULE_CMD_INIT, (filedict != NULL) ? |
813 | filedict : props); | | 818 | filedict : props); /* props will have been merged with filedict */ |
814 | module_active = NULL; | | 819 | module_active = NULL; |
815 | if (filedict != NULL) { | | 820 | if (filedict != NULL) { |
816 | prop_object_release(filedict); | | 821 | prop_object_release(filedict); |
817 | } | | 822 | } |
818 | if (error != 0) { | | 823 | if (error != 0) { |
819 | module_error("modcmd function returned error %d for `%s'", | | 824 | module_error("modcmd function returned error %d for `%s'", |
820 | error, mi->mi_name); | | 825 | error, mi->mi_name); |
821 | goto fail; | | 826 | goto fail; |
822 | } | | 827 | } |
823 | | | 828 | |
824 | /* | | 829 | /* |
825 | * Good, the module loaded successfully. Put it onto the | | 830 | * Good, the module loaded successfully. Put it onto the |
826 | * list and add references to its requisite modules. | | 831 | * list and add references to its requisite modules. |
| @@ -1187,13 +1192,47 @@ module_load_plist_file(const char *modpa | | | @@ -1187,13 +1192,47 @@ module_load_plist_file(const char *modpa |
1187 | base = NULL; | | 1192 | base = NULL; |
1188 | } | | 1193 | } |
1189 | *length = sb.st_size; | | 1194 | *length = sb.st_size; |
1190 | | | 1195 | |
1191 | out: | | 1196 | out: |
1192 | VOP_UNLOCK(nd.ni_vp, 0); | | 1197 | VOP_UNLOCK(nd.ni_vp, 0); |
1193 | vn_close(nd.ni_vp, FREAD, kauth_cred_get()); | | 1198 | vn_close(nd.ni_vp, FREAD, kauth_cred_get()); |
1194 | | | 1199 | |
1195 | out1: | | 1200 | out1: |
1196 | PNBUF_PUT(proppath); | | 1201 | PNBUF_PUT(proppath); |
1197 | *basep = base; | | 1202 | *basep = base; |
1198 | return error; | | 1203 | return error; |
1199 | } | | 1204 | } |
| | | 1205 | |
| | | 1206 | static bool |
| | | 1207 | module_merge_dicts(prop_dictionary_t existing_dict, |
| | | 1208 | const prop_dictionary_t new_dict) |
| | | 1209 | { |
| | | 1210 | prop_dictionary_keysym_t props_keysym; |
| | | 1211 | prop_object_iterator_t props_iter; |
| | | 1212 | prop_object_t props_obj; |
| | | 1213 | const char *props_key; |
| | | 1214 | bool error; |
| | | 1215 | |
| | | 1216 | error = false; |
| | | 1217 | props_iter = prop_dictionary_iterator(new_dict); |
| | | 1218 | if (props_iter == NULL) { |
| | | 1219 | return false; |
| | | 1220 | } |
| | | 1221 | |
| | | 1222 | while ((props_obj = prop_object_iterator_next(props_iter)) != NULL) { |
| | | 1223 | props_keysym = (prop_dictionary_keysym_t)props_obj; |
| | | 1224 | props_key = prop_dictionary_keysym_cstring_nocopy(props_keysym); |
| | | 1225 | props_obj = prop_dictionary_get_keysym(new_dict, props_keysym); |
| | | 1226 | if ((props_obj == NULL) || !prop_dictionary_set(existing_dict, |
| | | 1227 | props_key, props_obj)) { |
| | | 1228 | error = true; |
| | | 1229 | goto out; |
| | | 1230 | } |
| | | 1231 | } |
| | | 1232 | error = false; |
| | | 1233 | |
| | | 1234 | out: |
| | | 1235 | prop_object_iterator_release(props_iter); |
| | | 1236 | |
| | | 1237 | return !error; |
| | | 1238 | } |