Sat Jan 11 16:31:20 2014 UTC ()
Reorder code to avoid use-after-free on error. From Maxime Villard


(christos)
diff -r1.131 -r1.132 src/sys/kern/kern_verifiedexec.c

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

--- src/sys/kern/Attic/kern_verifiedexec.c 2013/11/27 17:24:44 1.131
+++ src/sys/kern/Attic/kern_verifiedexec.c 2014/01/11 16:31:20 1.132
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_verifiedexec.c,v 1.131 2013/11/27 17:24:44 christos Exp $ */ 1/* $NetBSD: kern_verifiedexec.c,v 1.132 2014/01/11 16:31:20 christos 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.131 2013/11/27 17:24:44 christos Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.132 2014/01/11 16:31:20 christos 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>
@@ -1299,59 +1299,59 @@ veriexec_file_add(struct lwp *l, prop_di @@ -1299,59 +1299,59 @@ veriexec_file_add(struct lwp *l, prop_di
1299 vfe->status = FINGERPRINT_NOTEVAL; 1299 vfe->status = FINGERPRINT_NOTEVAL;
1300 if (prop_bool_true(prop_dictionary_get(dict, "keep-filename"))) { 1300 if (prop_bool_true(prop_dictionary_get(dict, "keep-filename"))) {
1301 vfe->filename_len = strlen(file) + 1; 1301 vfe->filename_len = strlen(file) + 1;
1302 vfe->filename = kmem_alloc(vfe->filename_len, KM_SLEEP); 1302 vfe->filename = kmem_alloc(vfe->filename_len, KM_SLEEP);
1303 strlcpy(vfe->filename, file, vfe->filename_len); 1303 strlcpy(vfe->filename, file, vfe->filename_len);
1304 } else 1304 } else
1305 vfe->filename = NULL; 1305 vfe->filename = NULL;
1306 1306
1307 vfe->page_fp = NULL; 1307 vfe->page_fp = NULL;
1308 vfe->page_fp_status = PAGE_FP_NONE; 1308 vfe->page_fp_status = PAGE_FP_NONE;
1309 vfe->npages = 0; 1309 vfe->npages = 0;
1310 vfe->last_page_size = 0; 1310 vfe->last_page_size = 0;
1311 1311
1312 vte = veriexec_table_lookup(vp->v_mount); 
1313 if (vte == NULL) 
1314 vte = veriexec_table_add(l, vp->v_mount); 
1315 
1316 /* XXX if we bail below this, we might want to gc newly created vtes. */ 
1317 
1318 error = fileassoc_add(vp, veriexec_hook, vfe); 
1319 if (error) 
1320 goto unlock_out; 
1321 
1322 vte->vte_count++; 
1323 
1324 if (prop_bool_true(prop_dictionary_get(dict, "eval-on-load")) || 1312 if (prop_bool_true(prop_dictionary_get(dict, "eval-on-load")) ||
1325 (vfe->type & VERIEXEC_UNTRUSTED)) { 1313 (vfe->type & VERIEXEC_UNTRUSTED)) {
1326 u_char *digest; 1314 u_char *digest;
1327 1315
1328 digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP); 1316 digest = kmem_zalloc(vfe->ops->hash_len, KM_SLEEP);
1329 1317
1330 error = veriexec_fp_calc(l, vp, VERIEXEC_UNLOCKED, 1318 error = veriexec_fp_calc(l, vp, VERIEXEC_UNLOCKED,
1331 vfe, digest); 1319 vfe, digest);
1332 if (error) { 1320 if (error) {
1333 kmem_free(digest, vfe->ops->hash_len); 1321 kmem_free(digest, vfe->ops->hash_len);
1334 goto unlock_out; 1322 goto unlock_out;
1335 } 1323 }
1336 1324
1337 if (veriexec_fp_cmp(vfe->ops, vfe->fp, digest) == 0) 1325 if (veriexec_fp_cmp(vfe->ops, vfe->fp, digest) == 0)
1338 vfe->status = FINGERPRINT_VALID; 1326 vfe->status = FINGERPRINT_VALID;
1339 else 1327 else
1340 vfe->status = FINGERPRINT_NOMATCH; 1328 vfe->status = FINGERPRINT_NOMATCH;
1341 1329
1342 kmem_free(digest, vfe->ops->hash_len); 1330 kmem_free(digest, vfe->ops->hash_len);
1343 } 1331 }
1344 1332
 1333 vte = veriexec_table_lookup(vp->v_mount);
 1334 if (vte == NULL)
 1335 vte = veriexec_table_add(l, vp->v_mount);
 1336
 1337 /* XXX if we bail below this, we might want to gc newly created vtes. */
 1338
 1339 error = fileassoc_add(vp, veriexec_hook, vfe);
 1340 if (error)
 1341 goto unlock_out;
 1342
 1343 vte->vte_count++;
 1344
1345 veriexec_file_report(NULL, "New entry.", file, NULL, REPORT_DEBUG); 1345 veriexec_file_report(NULL, "New entry.", file, NULL, REPORT_DEBUG);
1346 veriexec_bypass = 0; 1346 veriexec_bypass = 0;
1347 1347
1348 unlock_out: 1348 unlock_out:
1349 rw_exit(&veriexec_op_lock); 1349 rw_exit(&veriexec_op_lock);
1350 1350
1351 out: 1351 out:
1352 vrele(vp); 1352 vrele(vp);
1353 if (error) 1353 if (error)
1354 veriexec_file_free(vfe); 1354 veriexec_file_free(vfe);
1355 1355
1356 return (error); 1356 return (error);
1357} 1357}