Thu Dec 18 00:56:27 2008 UTC ()
Pull up following revision(s) (requested by elad in ticket #189):
	sys/dev/verified_exec.c: revision 1.64
	sys/kern/kern_verifiedexec.c: revision 1.112
PR/39559: Juan RP: veriexec(4): too easy to cause a NULL dereference
    through it in kernel
Patch from PR applied with tiny modifications, thanks!
Discussed with blymn@ a while ago.


(snj)
diff -r1.63 -r1.63.22.1 src/sys/dev/verified_exec.c
diff -r1.111 -r1.111.4.1 src/sys/kern/kern_verifiedexec.c

cvs diff -r1.63 -r1.63.22.1 src/sys/dev/Attic/verified_exec.c (expand / switch to unified diff)

--- src/sys/dev/Attic/verified_exec.c 2007/12/11 12:16:14 1.63
+++ src/sys/dev/Attic/verified_exec.c 2008/12/18 00:56:27 1.63.22.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: verified_exec.c,v 1.63 2007/12/11 12:16:14 lukem Exp $ */ 1/* $NetBSD: verified_exec.c,v 1.63.22.1 2008/12/18 00:56:27 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org> 4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
5 * Copyright (c) 2005, 2006 Brett Lymn <blymn@NetBSD.org> 5 * Copyright (c) 2005, 2006 Brett Lymn <blymn@NetBSD.org>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.63 2007/12/11 12:16:14 lukem Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: verified_exec.c,v 1.63.22.1 2008/12/18 00:56:27 snj Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/errno.h> 35#include <sys/errno.h>
36#include <sys/conf.h> 36#include <sys/conf.h>
37#include <sys/vnode.h> 37#include <sys/vnode.h>
38#include <sys/fcntl.h> 38#include <sys/fcntl.h>
39#include <sys/namei.h> 39#include <sys/namei.h>
40#include <sys/verified_exec.h> 40#include <sys/verified_exec.h>
41#include <sys/kauth.h> 41#include <sys/kauth.h>
42#include <sys/syslog.h> 42#include <sys/syslog.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44 44
45#ifdef __FreeBSD__ 45#ifdef __FreeBSD__
@@ -118,89 +118,101 @@ veriexecopen(dev_t dev, int flags, int f @@ -118,89 +118,101 @@ veriexecopen(dev_t dev, int flags, int f
118 118
119static int 119static int
120veriexecclose(dev_t dev, int flags, int fmt, struct lwp *l) 120veriexecclose(dev_t dev, int flags, int fmt, struct lwp *l)
121{ 121{
122 if (veriexec_dev_usage > 0) 122 if (veriexec_dev_usage > 0)
123 veriexec_dev_usage--; 123 veriexec_dev_usage--;
124 return (0); 124 return (0);
125} 125}
126 126
127static int 127static int
128veriexec_delete(prop_dictionary_t dict, struct lwp *l) 128veriexec_delete(prop_dictionary_t dict, struct lwp *l)
129{ 129{
130 struct nameidata nid; 130 struct nameidata nid;
 131 const char *file;
131 int error; 132 int error;
132 133
133 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, 134 if (!prop_dictionary_get_cstring_nocopy(dict, "file", &file))
134 prop_string_cstring_nocopy(prop_dictionary_get(dict, "file"))); 135 return (EINVAL);
 136
 137 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, file);
135 error = namei(&nid); 138 error = namei(&nid);
136 if (error) 139 if (error)
137 return (error); 140 return (error);
138 141
139 /* XXX this should be done differently... */ 142 /* XXX this should be done differently... */
140 if (nid.ni_vp->v_type == VREG) 143 if (nid.ni_vp->v_type == VREG)
141 error = veriexec_file_delete(l, nid.ni_vp); 144 error = veriexec_file_delete(l, nid.ni_vp);
142 else if (nid.ni_vp->v_type == VDIR) 145 else if (nid.ni_vp->v_type == VDIR)
143 error = veriexec_table_delete(l, nid.ni_vp->v_mount); 146 error = veriexec_table_delete(l, nid.ni_vp->v_mount);
144 147
145 vrele(nid.ni_vp); 148 vrele(nid.ni_vp);
146 149
147 return (error); 150 return (error);
148} 151}
149 152
150static int 153static int
151veriexec_query(prop_dictionary_t dict, prop_dictionary_t rdict, struct lwp *l) 154veriexec_query(prop_dictionary_t dict, prop_dictionary_t rdict, struct lwp *l)
152{ 155{
153 struct nameidata nid; 156 struct nameidata nid;
 157 const char *file;
154 int error; 158 int error;
155 159
156 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, 160 if (!prop_dictionary_get_cstring_nocopy(dict, "file", &file))
157 prop_string_cstring_nocopy(prop_dictionary_get(dict, "file"))); 161 return (EINVAL);
 162
 163 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, file);
158 error = namei(&nid); 164 error = namei(&nid);
159 if (error) 165 if (error)
160 return (error); 166 return (error);
161 167
162 error = veriexec_convert(nid.ni_vp, rdict); 168 error = veriexec_convert(nid.ni_vp, rdict);
163 169
164 vrele(nid.ni_vp); 170 vrele(nid.ni_vp);
165 171
166 return (error); 172 return (error);
167} 173}
168 174
169int 175int
170veriexecioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 176veriexecioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
171{ 177{
172 extern int veriexec_strict; 178 extern int veriexec_strict;
173 struct plistref *plistref; 179 struct plistref *plistref;
174 prop_dictionary_t dict; 180 prop_dictionary_t dict;
175 int error = 0; 181 int error = 0;
176 182
177 /* XXX This should be replaced with a kauth(9) request. */ 183 /* XXX This should be replaced with a kauth(9) request. */
178 switch (cmd) { 184 switch (cmd) {
179 case VERIEXEC_TABLESIZE: 185 case VERIEXEC_TABLESIZE:
180 case VERIEXEC_LOAD: 186 case VERIEXEC_LOAD:
181 case VERIEXEC_DELETE: 187 case VERIEXEC_DELETE:
182 case VERIEXEC_FLUSH: 188 case VERIEXEC_FLUSH:
 189 if (!(flags & FWRITE))
 190 return (EPERM);
 191
183 if (veriexec_strict > VERIEXEC_LEARNING) { 192 if (veriexec_strict > VERIEXEC_LEARNING) {
184 log(LOG_WARNING, "Veriexec: Strict mode, modifying " 193 log(LOG_WARNING, "Veriexec: Strict mode, modifying "
185 "tables not permitted.\n"); 194 "tables not permitted.\n");
186 195
187 return (EPERM); 196 return (EPERM);
188 } 197 }
189 198
190 break; 199 break;
191 200
192 case VERIEXEC_QUERY: 201 case VERIEXEC_QUERY:
193 case VERIEXEC_DUMP: 202 case VERIEXEC_DUMP:
 203 if (!(flags & FREAD))
 204 return (EPERM);
 205
194 break; 206 break;
195 207
196 default: 208 default:
197 /* Invalid operation. */ 209 /* Invalid operation. */
198 return (ENODEV); 210 return (ENODEV);
199 } 211 }
200 212
201 plistref = (struct plistref *)data; 213 plistref = (struct plistref *)data;
202 214
203 switch (cmd) { 215 switch (cmd) {
204 case VERIEXEC_TABLESIZE: 216 case VERIEXEC_TABLESIZE:
205 /* Do nothing. Kept for binary compatibility. */ 217 /* Do nothing. Kept for binary compatibility. */
206 break; 218 break;

cvs diff -r1.111 -r1.111.4.1 src/sys/kern/Attic/kern_verifiedexec.c (expand / switch to unified diff)

--- src/sys/kern/Attic/kern_verifiedexec.c 2008/10/23 13:18:14 1.111
+++ src/sys/kern/Attic/kern_verifiedexec.c 2008/12/18 00:56:27 1.111.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_verifiedexec.c,v 1.111 2008/10/23 13:18:14 blymn Exp $ */ 1/* $NetBSD: kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org> 4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
5 * Copyright (c) 2005, 2006 Brett Lymn <blymn@NetBSD.org> 5 * Copyright (c) 2005, 2006 Brett Lymn <blymn@NetBSD.org>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.111 2008/10/23 13:18:14 blymn Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp $");
33 33
34#include "opt_veriexec.h" 34#include "opt_veriexec.h"
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/mount.h> 37#include <sys/mount.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/vnode.h> 39#include <sys/vnode.h>
40#include <sys/namei.h> 40#include <sys/namei.h>
41#include <sys/exec.h> 41#include <sys/exec.h>
42#include <sys/once.h> 42#include <sys/once.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/rwlock.h> 44#include <sys/rwlock.h>
45#include <sys/syslog.h> 45#include <sys/syslog.h>
@@ -1175,27 +1175,28 @@ veriexec_table_add(struct lwp *l, struct @@ -1175,27 +1175,28 @@ veriexec_table_add(struct lwp *l, struct
1175 * Add a file to be monitored by Veriexec. 1175 * Add a file to be monitored by Veriexec.
1176 * 1176 *
1177 * Expected elements in dict: file, fp, fp-type, entry-type. 1177 * Expected elements in dict: file, fp, fp-type, entry-type.
1178 */ 1178 */
1179int 1179int
1180veriexec_file_add(struct lwp *l, prop_dictionary_t dict) 1180veriexec_file_add(struct lwp *l, prop_dictionary_t dict)
1181{ 1181{
1182 struct veriexec_table_entry *vte; 1182 struct veriexec_table_entry *vte;
1183 struct veriexec_file_entry *vfe = NULL, *hh; 1183 struct veriexec_file_entry *vfe = NULL, *hh;
1184 struct nameidata nid; 1184 struct nameidata nid;
1185 const char *file, *fp_type; 1185 const char *file, *fp_type;
1186 int error; 1186 int error;
1187 1187
1188 file = prop_string_cstring_nocopy(prop_dictionary_get(dict, "file")); 1188 if (!prop_dictionary_get_cstring_nocopy(dict, "file", &file))
 1189 return (EINVAL);
1189 1190
1190 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, file); 1191 NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, file);
1191 error = namei(&nid); 1192 error = namei(&nid);
1192 if (error) 1193 if (error)
1193 return (error); 1194 return (error);
1194 1195
1195 /* Add only regular files. */ 1196 /* Add only regular files. */
1196 if (nid.ni_vp->v_type != VREG) { 1197 if (nid.ni_vp->v_type != VREG) {
1197 log(LOG_ERR, "Veriexec: Not adding `%s': Not a regular file.\n", 1198 log(LOG_ERR, "Veriexec: Not adding `%s': Not a regular file.\n",
1198 file); 1199 file);
1199 1200
1200 error = EBADF; 1201 error = EBADF;
1201 1202