Move all namei flags handling into kobj_load_file(). When I originally wrote this, I was going for maximum flexibility. However, after a private discussion with dholland@, I see how this will cause problems with the future world order of namei whenever that might be. At the moment, I don't need the extra flexibility, but if something comes up this may have to be revisited.diff -r1.44 -r1.45 src/sys/kern/kern_module.c
(jnemeth)
--- src/sys/kern/kern_module.c 2009/05/25 22:33:00 1.44
+++ src/sys/kern/kern_module.c 2009/05/26 08:34:23 1.45
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: kern_module.c,v 1.44 2009/05/25 22:33:00 jnemeth Exp $ */ | 1 | /* $NetBSD: kern_module.c,v 1.45 2009/05/26 08:34:23 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.44 2009/05/25 22:33:00 jnemeth Exp $"); | 37 | __KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.45 2009/05/26 08:34:23 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> | |
@@ -553,26 +553,27 @@ static int | @@ -553,26 +553,27 @@ static int | |||
553 | module_do_load(const char *name, bool isdep, int flags, | 553 | module_do_load(const char *name, bool isdep, int flags, | |
554 | prop_dictionary_t props, module_t **modp, modclass_t class, | 554 | prop_dictionary_t props, module_t **modp, modclass_t class, | |
555 | bool autoload) | 555 | bool autoload) | |
556 | { | 556 | { | |
557 | static TAILQ_HEAD(,module) pending = TAILQ_HEAD_INITIALIZER(pending); | 557 | static TAILQ_HEAD(,module) pending = TAILQ_HEAD_INITIALIZER(pending); | |
558 | static int depth; | 558 | static int depth; | |
559 | const int maxdepth = 6; | 559 | const int maxdepth = 6; | |
560 | modinfo_t *mi; | 560 | modinfo_t *mi; | |
561 | module_t *mod, *mod2; | 561 | module_t *mod, *mod2; | |
562 | char buf[MAXMODNAME], *path; | 562 | char buf[MAXMODNAME], *path; | |
563 | const char *s, *p; | 563 | const char *s, *p; | |
564 | int error; | 564 | int error; | |
565 | size_t len; | 565 | size_t len; | |
566 | bool nochroot; | |||
566 | 567 | |||
567 | KASSERT(mutex_owned(&module_lock)); | 568 | KASSERT(mutex_owned(&module_lock)); | |
568 | 569 | |||
569 | error = 0; | 570 | error = 0; | |
570 | path=NULL; | 571 | path=NULL; | |
571 | 572 | |||
572 | /* | 573 | /* | |
573 | * Avoid recursing too far. | 574 | * Avoid recursing too far. | |
574 | */ | 575 | */ | |
575 | if (++depth > maxdepth) { | 576 | if (++depth > maxdepth) { | |
576 | module_error("too many required modules"); | 577 | module_error("too many required modules"); | |
577 | depth--; | 578 | depth--; | |
578 | return EMLINK; | 579 | return EMLINK; | |
@@ -610,34 +611,35 @@ module_do_load(const char *name, bool is | @@ -610,34 +611,35 @@ module_do_load(const char *name, bool is | |||
610 | } | 611 | } | |
611 | depth--; | 612 | depth--; | |
612 | return 0; | 613 | return 0; | |
613 | } | 614 | } | |
614 | } | 615 | } | |
615 | mod = kmem_zalloc(sizeof(*mod), KM_SLEEP); | 616 | mod = kmem_zalloc(sizeof(*mod), KM_SLEEP); | |
616 | if (mod == NULL) { | 617 | if (mod == NULL) { | |
617 | module_error("out of memory for `%s'", name); | 618 | module_error("out of memory for `%s'", name); | |
618 | depth--; | 619 | depth--; | |
619 | return ENOMEM; | 620 | return ENOMEM; | |
620 | } | 621 | } | |
621 | path = PNBUF_GET(); | 622 | path = PNBUF_GET(); | |
622 | if (!autoload) { | 623 | if (!autoload) { | |
624 | nochroot = false; | |||
623 | snprintf(path, MAXPATHLEN, "%s", name); | 625 | snprintf(path, MAXPATHLEN, "%s", name); | |
624 | error = kobj_load_file(&mod->mod_kobj, path, FOLLOW); | 626 | error = kobj_load_file(&mod->mod_kobj, path, nochroot); | |
625 | } | 627 | } | |
626 | if (autoload || (error == ENOENT)) { | 628 | if (autoload || (error == ENOENT)) { | |
629 | nochroot = true; | |||
627 | snprintf(path, MAXPATHLEN, "%s/%s/%s.kmod", | 630 | snprintf(path, MAXPATHLEN, "%s/%s/%s.kmod", | |
628 | module_base, name, name); | 631 | module_base, name, name); | |
629 | error = kobj_load_file(&mod->mod_kobj, path, | 632 | error = kobj_load_file(&mod->mod_kobj, path, nochroot); | |
630 | FOLLOW | NOCHROOT); | |||
631 | } | 633 | } | |
632 | if (error != 0) { | 634 | if (error != 0) { | |
633 | kmem_free(mod, sizeof(*mod)); | 635 | kmem_free(mod, sizeof(*mod)); | |
634 | depth--; | 636 | depth--; | |
635 | PNBUF_PUT(path); | 637 | PNBUF_PUT(path); | |
636 | if (autoload) { | 638 | if (autoload) { | |
637 | module_print("Cannot load kernel object `%s'" | 639 | module_print("Cannot load kernel object `%s'" | |
638 | " error=%d", name, error); | 640 | " error=%d", name, error); | |
639 | } else { | 641 | } else { | |
640 | module_error("Cannot load kernel object `%s'" | 642 | module_error("Cannot load kernel object `%s'" | |
641 | " error=%d", name, error); | 643 | " error=%d", name, error); | |
642 | } | 644 | } | |
643 | return error; | 645 | return error; |
--- src/sys/kern/subr_kobj.c 2009/05/25 22:33:00 1.37
+++ src/sys/kern/subr_kobj.c 2009/05/26 08:34:23 1.38
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: subr_kobj.c,v 1.37 2009/05/25 22:33:00 jnemeth Exp $ */ | 1 | /* $NetBSD: subr_kobj.c,v 1.38 2009/05/26 08:34:23 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. | |
@@ -53,27 +53,27 @@ | @@ -53,27 +53,27 @@ | |||
53 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 53 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 54 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
55 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 55 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
56 | * SUCH DAMAGE. | 56 | * SUCH DAMAGE. | |
57 | */ | 57 | */ | |
58 | 58 | |||
59 | /* | 59 | /* | |
60 | * Kernel loader for ELF objects. | 60 | * Kernel loader for ELF objects. | |
61 | * | 61 | * | |
62 | * TODO: adjust kmem_alloc() calls to avoid needless fragmentation. | 62 | * TODO: adjust kmem_alloc() calls to avoid needless fragmentation. | |
63 | */ | 63 | */ | |
64 | 64 | |||
65 | #include <sys/cdefs.h> | 65 | #include <sys/cdefs.h> | |
66 | __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.37 2009/05/25 22:33:00 jnemeth Exp $"); | 66 | __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.38 2009/05/26 08:34:23 jnemeth Exp $"); | |
67 | 67 | |||
68 | #include "opt_modular.h" | 68 | #include "opt_modular.h" | |
69 | 69 | |||
70 | #include <sys/kobj_impl.h> | 70 | #include <sys/kobj_impl.h> | |
71 | 71 | |||
72 | #ifdef MODULAR | 72 | #ifdef MODULAR | |
73 | 73 | |||
74 | #include <sys/param.h> | 74 | #include <sys/param.h> | |
75 | #include <sys/kernel.h> | 75 | #include <sys/kernel.h> | |
76 | #include <sys/kmem.h> | 76 | #include <sys/kmem.h> | |
77 | #include <sys/proc.h> | 77 | #include <sys/proc.h> | |
78 | #include <sys/namei.h> | 78 | #include <sys/namei.h> | |
79 | #include <sys/vnode.h> | 79 | #include <sys/vnode.h> | |
@@ -93,41 +93,42 @@ static int kobj_read_bits(kobj_t, void * | @@ -93,41 +93,42 @@ static int kobj_read_bits(kobj_t, void * | |||
93 | static void kobj_jettison(kobj_t); | 93 | static void kobj_jettison(kobj_t); | |
94 | static void kobj_free(kobj_t, void *, size_t); | 94 | static void kobj_free(kobj_t, void *, size_t); | |
95 | static void kobj_close(kobj_t); | 95 | static void kobj_close(kobj_t); | |
96 | static int kobj_load(kobj_t); | 96 | static int kobj_load(kobj_t); | |
97 | 97 | |||
98 | extern struct vm_map *module_map; | 98 | extern struct vm_map *module_map; | |
99 | 99 | |||
100 | /* | 100 | /* | |
101 | * kobj_load_file: | 101 | * kobj_load_file: | |
102 | * | 102 | * | |
103 | * Load an object located in the file system. | 103 | * Load an object located in the file system. | |
104 | */ | 104 | */ | |
105 | int | 105 | int | |
106 | kobj_load_file(kobj_t *kop, const char *path, const uint32_t flags) | 106 | kobj_load_file(kobj_t *kop, const char *path, const bool nochroot) | |
107 | { | 107 | { | |
108 | struct nameidata nd; | 108 | struct nameidata nd; | |
109 | kauth_cred_t cred; | 109 | kauth_cred_t cred; | |
110 | int error; | 110 | int error; | |
111 | kobj_t ko; | 111 | kobj_t ko; | |
112 | 112 | |||
113 | cred = kauth_cred_get(); | 113 | cred = kauth_cred_get(); | |
114 | 114 | |||
115 | ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); | 115 | ko = kmem_zalloc(sizeof(*ko), KM_SLEEP); | |
116 | if (ko == NULL) { | 116 | if (ko == NULL) { | |
117 | return ENOMEM; | 117 | return ENOMEM; | |
118 | } | 118 | } | |
119 | 119 | |||
120 | NDINIT(&nd, LOOKUP, flags, UIO_SYSSPACE, path); | 120 | NDINIT(&nd, LOOKUP, FOLLOW | (nochroot ? NOCHROOT : 0), | |
121 | UIO_SYSSPACE, path); | |||
121 | error = vn_open(&nd, FREAD, 0); | 122 | error = vn_open(&nd, FREAD, 0); | |
122 | 123 | |||
123 | if (error != 0) { | 124 | if (error != 0) { | |
124 | kmem_free(ko, sizeof(*ko)); | 125 | kmem_free(ko, sizeof(*ko)); | |
125 | return error; | 126 | return error; | |
126 | } | 127 | } | |
127 | 128 | |||
128 | ko->ko_type = KT_VNODE; | 129 | ko->ko_type = KT_VNODE; | |
129 | ko->ko_source = nd.ni_vp; | 130 | ko->ko_source = nd.ni_vp; | |
130 | *kop = ko; | 131 | *kop = ko; | |
131 | return kobj_load(ko); | 132 | return kobj_load(ko); | |
132 | } | 133 | } | |
133 | 134 | |||
@@ -1095,27 +1096,27 @@ kobj_read_bits(kobj_t ko, void *base, si | @@ -1095,27 +1096,27 @@ kobj_read_bits(kobj_t ko, void *base, si | |||
1095 | * Utility function: free memory if it was allocated from the heap. | 1096 | * Utility function: free memory if it was allocated from the heap. | |
1096 | */ | 1097 | */ | |
1097 | static void | 1098 | static void | |
1098 | kobj_free(kobj_t ko, void *base, size_t size) | 1099 | kobj_free(kobj_t ko, void *base, size_t size) | |
1099 | { | 1100 | { | |
1100 | 1101 | |||
1101 | if (ko->ko_type != KT_MEMORY) | 1102 | if (ko->ko_type != KT_MEMORY) | |
1102 | kmem_free(base, size); | 1103 | kmem_free(base, size); | |
1103 | } | 1104 | } | |
1104 | 1105 | |||
1105 | #else /* MODULAR */ | 1106 | #else /* MODULAR */ | |
1106 | 1107 | |||
1107 | int | 1108 | int | |
1108 | kobj_load_file(kobj_t *kop, const char *name, const uint32_t flags) | 1109 | kobj_load_file(kobj_t *kop, const char *name, const bool nochroot) | |
1109 | { | 1110 | { | |
1110 | 1111 | |||
1111 | return ENOSYS; | 1112 | return ENOSYS; | |
1112 | } | 1113 | } | |
1113 | 1114 | |||
1114 | int | 1115 | int | |
1115 | kobj_load_mem(kobj_t *kop, void *base, ssize_t size) | 1116 | kobj_load_mem(kobj_t *kop, void *base, ssize_t size) | |
1116 | { | 1117 | { | |
1117 | 1118 | |||
1118 | return ENOSYS; | 1119 | return ENOSYS; | |
1119 | } | 1120 | } | |
1120 | 1121 | |||
1121 | void | 1122 | void |
--- src/sys/sys/kobj.h 2009/05/25 22:33:00 1.10
+++ src/sys/sys/kobj.h 2009/05/26 08:34:22 1.11
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: kobj.h,v 1.10 2009/05/25 22:33:00 jnemeth Exp $ */ | 1 | /* $NetBSD: kobj.h,v 1.11 2009/05/26 08:34:22 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 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -22,26 +22,26 @@ | @@ -22,26 +22,26 @@ | |||
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #ifndef _SYS_KOBJ_H_ | 29 | #ifndef _SYS_KOBJ_H_ | |
30 | #define _SYS_KOBJ_H_ | 30 | #define _SYS_KOBJ_H_ | |
31 | 31 | |||
32 | typedef struct kobj *kobj_t; | 32 | typedef struct kobj *kobj_t; | |
33 | 33 | |||
34 | /* External interface. */ | 34 | /* External interface. */ | |
35 | int kobj_load_file(kobj_t *, const char *, const uint32_t); | 35 | int kobj_load_file(kobj_t *, const char *, const bool); | |
36 | int kobj_load_mem(kobj_t *, void *, ssize_t); | 36 | int kobj_load_mem(kobj_t *, void *, ssize_t); | |
37 | int kobj_affix(kobj_t, const char *); | 37 | int kobj_affix(kobj_t, const char *); | |
38 | void kobj_unload(kobj_t); | 38 | void kobj_unload(kobj_t); | |
39 | void kobj_stat(kobj_t, vaddr_t *, size_t *); | 39 | void kobj_stat(kobj_t, vaddr_t *, size_t *); | |
40 | int kobj_find_section(kobj_t, const char *, void **, size_t *); | 40 | int kobj_find_section(kobj_t, const char *, void **, size_t *); | |
41 | 41 | |||
42 | /* MI-MD interface. */ | 42 | /* MI-MD interface. */ | |
43 | uintptr_t kobj_sym_lookup(kobj_t, uintptr_t); | 43 | uintptr_t kobj_sym_lookup(kobj_t, uintptr_t); | |
44 | int kobj_reloc(kobj_t, uintptr_t, const void *, bool, bool); | 44 | int kobj_reloc(kobj_t, uintptr_t, const void *, bool, bool); | |
45 | int kobj_machdep(kobj_t, void *, size_t, bool); | 45 | int kobj_machdep(kobj_t, void *, size_t, bool); | |
46 | 46 | |||
47 | #endif /* !_SYS_KOBJ_H_ */ | 47 | #endif /* !_SYS_KOBJ_H_ */ |