| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: kern_core.c,v 1.24 2016/07/07 06:55:43 msaitoh Exp $ */ | | 1 | /* $NetBSD: kern_core.c,v 1.24.10.1 2022/09/09 18:24:20 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 | | 4 | * Copyright (c) 1982, 1986, 1989, 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * (c) UNIX System Laboratories, Inc. | | 6 | * (c) UNIX System Laboratories, Inc. |
7 | * All or some portions of this file are derived from material licensed | | 7 | * All or some portions of this file are derived from material licensed |
8 | * to the University of California by American Telephone and Telegraph | | 8 | * to the University of California by American Telephone and Telegraph |
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | | 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with |
10 | * the permission of UNIX System Laboratories, Inc. | | 10 | * the permission of UNIX System Laboratories, Inc. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 | * SUCH DAMAGE. | | 34 | * SUCH DAMAGE. |
35 | * | | 35 | * |
36 | * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95 | | 36 | * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95 |
37 | */ | | 37 | */ |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | __KERNEL_RCSID(0, "$NetBSD: kern_core.c,v 1.24 2016/07/07 06:55:43 msaitoh Exp $"); | | 40 | __KERNEL_RCSID(0, "$NetBSD: kern_core.c,v 1.24.10.1 2022/09/09 18:24:20 martin Exp $"); |
41 | | | 41 | |
42 | #include <sys/param.h> | | 42 | #include <sys/param.h> |
43 | #include <sys/vnode.h> | | 43 | #include <sys/vnode.h> |
44 | #include <sys/namei.h> | | 44 | #include <sys/namei.h> |
45 | #include <sys/acct.h> | | 45 | #include <sys/acct.h> |
46 | #include <sys/file.h> | | 46 | #include <sys/file.h> |
47 | #include <sys/stat.h> | | 47 | #include <sys/stat.h> |
48 | #include <sys/proc.h> | | 48 | #include <sys/proc.h> |
49 | #include <sys/exec.h> | | 49 | #include <sys/exec.h> |
50 | #include <sys/filedesc.h> | | 50 | #include <sys/filedesc.h> |
51 | #include <sys/kauth.h> | | 51 | #include <sys/kauth.h> |
52 | #include <sys/module.h> | | 52 | #include <sys/module.h> |
53 | | | 53 | |
| @@ -85,104 +85,98 @@ coredump_modcmd(modcmd_t cmd, void *arg) | | | @@ -85,104 +85,98 @@ coredump_modcmd(modcmd_t cmd, void *arg) |
85 | } | | 85 | } |
86 | } | | 86 | } |
87 | | | 87 | |
88 | /* | | 88 | /* |
89 | * Dump core, into a file named "progname.core" or "core" (depending on the | | 89 | * Dump core, into a file named "progname.core" or "core" (depending on the |
90 | * value of shortcorename), unless the process was setuid/setgid. | | 90 | * value of shortcorename), unless the process was setuid/setgid. |
91 | */ | | 91 | */ |
92 | static int | | 92 | static int |
93 | coredump(struct lwp *l, const char *pattern) | | 93 | coredump(struct lwp *l, const char *pattern) |
94 | { | | 94 | { |
95 | struct vnode *vp; | | 95 | struct vnode *vp; |
96 | struct proc *p; | | 96 | struct proc *p; |
97 | struct vmspace *vm; | | 97 | struct vmspace *vm; |
98 | kauth_cred_t cred; | | 98 | kauth_cred_t cred = NULL; |
99 | struct pathbuf *pb; | | 99 | struct pathbuf *pb; |
100 | struct nameidata nd; | | 100 | struct nameidata nd; |
101 | struct vattr vattr; | | 101 | struct vattr vattr; |
102 | struct coredump_iostate io; | | 102 | struct coredump_iostate io; |
103 | struct plimit *lim; | | 103 | struct plimit *lim; |
104 | int error, error1; | | 104 | int error, error1; |
105 | char *name, *lastslash; | | 105 | char *name, *lastslash; |
106 | | | 106 | |
107 | name = PNBUF_GET(); | | 107 | name = PNBUF_GET(); |
108 | | | 108 | |
109 | p = l->l_proc; | | 109 | p = l->l_proc; |
110 | vm = p->p_vmspace; | | 110 | vm = p->p_vmspace; |
111 | | | 111 | |
112 | mutex_enter(proc_lock); /* p_session */ | | 112 | mutex_enter(proc_lock); /* p_session */ |
113 | mutex_enter(p->p_lock); | | 113 | mutex_enter(p->p_lock); |
114 | | | 114 | |
115 | /* | | 115 | /* |
116 | * Refuse to core if the data + stack + user size is larger than | | 116 | * Refuse to core if the data + stack + user size is larger than |
117 | * the core dump limit. XXX THIS IS WRONG, because of mapped | | 117 | * the core dump limit. XXX THIS IS WRONG, because of mapped |
118 | * data. | | 118 | * data. |
119 | */ | | 119 | */ |
120 | if (USPACE + ctob(vm->vm_dsize + vm->vm_ssize) >= | | 120 | if (USPACE + ctob(vm->vm_dsize + vm->vm_ssize) >= |
121 | p->p_rlimit[RLIMIT_CORE].rlim_cur) { | | 121 | p->p_rlimit[RLIMIT_CORE].rlim_cur) { |
122 | error = EFBIG; /* better error code? */ | | 122 | error = EFBIG; /* better error code? */ |
123 | mutex_exit(p->p_lock); | | 123 | goto release; |
124 | mutex_exit(proc_lock); | | | |
125 | goto done; | | | |
126 | } | | 124 | } |
127 | | | 125 | |
128 | /* | | 126 | /* |
129 | * It may well not be curproc, so grab a reference to its current | | 127 | * It may well not be curproc, so grab a reference to its current |
130 | * credentials. | | 128 | * credentials. |
131 | */ | | 129 | */ |
132 | kauth_cred_hold(p->p_cred); | | 130 | kauth_cred_hold(p->p_cred); |
133 | cred = p->p_cred; | | 131 | cred = p->p_cred; |
134 | | | 132 | |
135 | /* | | 133 | /* |
136 | * Make sure the process has not set-id, to prevent data leaks, | | 134 | * Make sure the process has not set-id, to prevent data leaks, |
137 | * unless it was specifically requested to allow set-id coredumps. | | 135 | * unless it was specifically requested to allow set-id coredumps. |
138 | */ | | 136 | */ |
139 | if (p->p_flag & PK_SUGID) { | | 137 | if (p->p_flag & PK_SUGID) { |
140 | if (!security_setidcore_dump) { | | 138 | if (!security_setidcore_dump) { |
141 | error = EPERM; | | 139 | error = EPERM; |
142 | mutex_exit(p->p_lock); | | 140 | goto release; |
143 | mutex_exit(proc_lock); | | | |
144 | goto done; | | | |
145 | } | | 141 | } |
146 | pattern = security_setidcore_path; | | 142 | pattern = security_setidcore_path; |
147 | } | | 143 | } |
148 | | | 144 | |
149 | /* Lock, as p_limit and pl_corename might change. */ | | 145 | /* Lock, as p_limit and pl_corename might change. */ |
150 | lim = p->p_limit; | | 146 | lim = p->p_limit; |
151 | mutex_enter(&lim->pl_lock); | | 147 | mutex_enter(&lim->pl_lock); |
152 | if (pattern == NULL) { | | 148 | if (pattern == NULL) { |
153 | pattern = lim->pl_corename; | | 149 | pattern = lim->pl_corename; |
154 | } | | 150 | } |
155 | error = coredump_buildname(p, name, pattern, MAXPATHLEN); | | 151 | error = coredump_buildname(p, name, pattern, MAXPATHLEN); |
156 | mutex_exit(&lim->pl_lock); | | 152 | mutex_exit(&lim->pl_lock); |
157 | | | 153 | |
158 | if (error) { | | 154 | if (error) |
159 | mutex_exit(p->p_lock); | | 155 | goto release; |
160 | mutex_exit(proc_lock); | | | |
161 | goto done; | | | |
162 | } | | | |
163 | | | 156 | |
164 | /* | | 157 | /* |
165 | * On a simple filename, see if the filesystem allow us to write | | 158 | * On a simple filename, see if the filesystem allow us to write |
166 | * core dumps there. | | 159 | * core dumps there. |
167 | */ | | 160 | */ |
168 | lastslash = strrchr(name, '/'); | | 161 | lastslash = strrchr(name, '/'); |
169 | if (!lastslash) { | | 162 | if (!lastslash) { |
170 | vp = p->p_cwdi->cwdi_cdir; | | 163 | vp = p->p_cwdi->cwdi_cdir; |
171 | if (vp->v_mount == NULL || | | 164 | if (vp->v_mount == NULL || |
172 | (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0) | | 165 | (vp->v_mount->mnt_flag & MNT_NOCOREDUMP) != 0) |
173 | error = EPERM; | | 166 | error = EPERM; |
174 | } | | 167 | } |
175 | | | 168 | |
| | | 169 | release: |
176 | mutex_exit(p->p_lock); | | 170 | mutex_exit(p->p_lock); |
177 | mutex_exit(proc_lock); | | 171 | mutex_exit(proc_lock); |
178 | if (error) | | 172 | if (error) |
179 | goto done; | | 173 | goto done; |
180 | | | 174 | |
181 | /* | | 175 | /* |
182 | * On a complex filename, see if the filesystem allow us to write | | 176 | * On a complex filename, see if the filesystem allow us to write |
183 | * core dumps there. | | 177 | * core dumps there. |
184 | * | | 178 | * |
185 | * XXX: We should have an API that avoids double lookups | | 179 | * XXX: We should have an API that avoids double lookups |
186 | */ | | 180 | */ |
187 | if (lastslash) { | | 181 | if (lastslash) { |
188 | char c[2]; | | 182 | char c[2]; |
| @@ -250,26 +244,28 @@ coredump(struct lwp *l, const char *patt | | | @@ -250,26 +244,28 @@ coredump(struct lwp *l, const char *patt |
250 | io.io_lwp = l; | | 244 | io.io_lwp = l; |
251 | io.io_vp = vp; | | 245 | io.io_vp = vp; |
252 | io.io_cred = cred; | | 246 | io.io_cred = cred; |
253 | io.io_offset = 0; | | 247 | io.io_offset = 0; |
254 | | | 248 | |
255 | /* Now dump the actual core file. */ | | 249 | /* Now dump the actual core file. */ |
256 | error = (*p->p_execsw->es_coredump)(l, &io); | | 250 | error = (*p->p_execsw->es_coredump)(l, &io); |
257 | out: | | 251 | out: |
258 | VOP_UNLOCK(vp); | | 252 | VOP_UNLOCK(vp); |
259 | error1 = vn_close(vp, FWRITE, cred); | | 253 | error1 = vn_close(vp, FWRITE, cred); |
260 | if (error == 0) | | 254 | if (error == 0) |
261 | error = error1; | | 255 | error = error1; |
262 | done: | | 256 | done: |
| | | 257 | if (cred != NULL) |
| | | 258 | kauth_cred_free(cred); |
263 | if (name != NULL) | | 259 | if (name != NULL) |
264 | PNBUF_PUT(name); | | 260 | PNBUF_PUT(name); |
265 | return error; | | 261 | return error; |
266 | } | | 262 | } |
267 | | | 263 | |
268 | static int | | 264 | static int |
269 | coredump_buildname(struct proc *p, char *dst, const char *src, size_t len) | | 265 | coredump_buildname(struct proc *p, char *dst, const char *src, size_t len) |
270 | { | | 266 | { |
271 | const char *s; | | 267 | const char *s; |
272 | char *d, *end; | | 268 | char *d, *end; |
273 | int i; | | 269 | int i; |
274 | | | 270 | |
275 | KASSERT(mutex_owned(proc_lock)); | | 271 | KASSERT(mutex_owned(proc_lock)); |