From b0a14e593420518a3fc4c017b97e460d09a5eead Mon Sep 17 00:00:00 2001 From: yamt Date: Mon, 11 Dec 2006 15:24:27 +0000 Subject: [PATCH] - remove a static configuration, FILEASSOC_NHOOKS. do it dynamically instead. - make fileassoc_t a pointer and remove FILEASSOC_INVAL. - clean up kern_fileassoc.c. unify duplicated code. - unexport fileassoc_init using RUN_ONCE(9). - plug memory leaks in fileassoc_file_delete and fileassoc_table_delete. - always call callbacks, regardless of the value of the associated data. ok'ed by elad. --- sys/arch/amd64/conf/GENERIC | 5 +- sys/arch/i386/conf/ALL | 5 +- sys/arch/i386/conf/GENERIC | 5 +- sys/arch/i386/conf/PARALLELS | 3 +- sys/arch/i386/conf/QEMU | 5 +- sys/arch/sparc64/conf/GENERIC | 5 +- sys/conf/files | 3 +- sys/kern/init_main.c | 13 +- sys/kern/kern_fileassoc.c | 271 ++++++++++++++++++++-------------- sys/kern/kern_pax.c | 14 +- sys/kern/kern_verifiedexec.c | 14 +- sys/sys/fileassoc.h | 9 +- 12 files changed, 197 insertions(+), 155 deletions(-) diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index 91b507692625..f8caf70105b5 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.120 2006/11/30 21:01:16 bouyer Exp $ +# $NetBSD: GENERIC,v 1.121 2006/12/11 15:24:27 yamt Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.120 $" +#ident "GENERIC-$Revision: 1.121 $" maxusers 32 # estimated number of users @@ -922,7 +922,6 @@ pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont options FILEASSOC # fileassoc(9) - required for Veriexec -#options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec # diff --git a/sys/arch/i386/conf/ALL b/sys/arch/i386/conf/ALL index 18cc155f8132..85700ae79405 100644 --- a/sys/arch/i386/conf/ALL +++ b/sys/arch/i386/conf/ALL @@ -1,4 +1,4 @@ -# $NetBSD: ALL,v 1.73 2006/11/29 13:41:28 xtraeme Exp $ +# $NetBSD: ALL,v 1.74 2006/12/11 15:24:28 yamt Exp $ # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp # # ALL machine description file @@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ALL-$Revision: 1.73 $" +#ident "ALL-$Revision: 1.74 $" maxusers 32 # estimated number of users @@ -1377,7 +1377,6 @@ pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont options FILEASSOC # fileassoc(9) - required for Veriexec -options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec pseudo-device veriexec diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index f6f4c7336954..17c937c94c26 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.800 2006/12/04 01:32:37 dyoung Exp $ +# $NetBSD: GENERIC,v 1.801 2006/12/11 15:24:28 yamt Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.800 $" +#ident "GENERIC-$Revision: 1.801 $" maxusers 32 # estimated number of users @@ -1398,7 +1398,6 @@ pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont options FILEASSOC # fileassoc(9) - required for Veriexec -#options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec pseudo-device veriexec diff --git a/sys/arch/i386/conf/PARALLELS b/sys/arch/i386/conf/PARALLELS index 7073be39d3b7..400c03f4f2cd 100644 --- a/sys/arch/i386/conf/PARALLELS +++ b/sys/arch/i386/conf/PARALLELS @@ -1,4 +1,4 @@ -# $NetBSD: PARALLELS,v 1.9 2006/11/28 16:15:37 christos Exp $ +# $NetBSD: PARALLELS,v 1.10 2006/12/11 15:24:28 yamt Exp $ # # PARALLELS machine description file # @@ -383,7 +383,6 @@ pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont #options FILEASSOC # fileassoc(9) - required for Veriexec -#options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec #pseudo-device veriexec diff --git a/sys/arch/i386/conf/QEMU b/sys/arch/i386/conf/QEMU index 9479c751c0e4..66ad95fea3ed 100644 --- a/sys/arch/i386/conf/QEMU +++ b/sys/arch/i386/conf/QEMU @@ -1,4 +1,4 @@ -# $NetBSD: QEMU,v 1.8 2006/11/28 16:15:37 christos Exp $ +# $NetBSD: QEMU,v 1.9 2006/12/11 15:24:28 yamt Exp $ # # QEMU machine description file # @@ -11,7 +11,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "QEMU-$Revision: 1.8 $" +#ident "QEMU-$Revision: 1.9 $" maxusers 32 # estimated number of users @@ -462,7 +462,6 @@ pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont #options FILEASSOC # fileassoc(9) - required for Veriexec -#options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec #pseudo-device veriexec diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC index fae08fe84bcd..2c0e768f6c47 100644 --- a/sys/arch/sparc64/conf/GENERIC +++ b/sys/arch/sparc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.80 2006/12/04 23:43:35 elad Exp $ +# $NetBSD: GENERIC,v 1.81 2006/12/11 15:24:28 yamt Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/sparc64/conf/std.sparc64" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.80 $" +#ident "GENERIC-$Revision: 1.81 $" maxusers 64 @@ -884,7 +884,6 @@ pseudo-device ksyms # /dev/ksyms pseudo-device fss 4 # file system snapshot device options FILEASSOC # fileassoc(9) - required for Veriexec -#options FILEASSOC_NHOOKS=4 # Default number of storage slots # Veriexec # diff --git a/sys/conf/files b/sys/conf/files index c74eabb30276..30c7ecbce12a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.819 2006/11/24 22:04:25 wiz Exp $ +# $NetBSD: files,v 1.820 2006/12/11 15:24:28 yamt Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -93,7 +93,6 @@ defparam opt_pax.h PAX_MPROTECT PAX_SEGVGUARD defflag opt_fileassoc.h FILEASSOC -defparam opt_fileassoc.h FILEASSOC_NHOOKS defflag opt_gre.h GRE_DEBUG diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 8cebe0bd72ce..69eb0e768525 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.284 2006/12/07 20:23:38 ad Exp $ */ +/* $NetBSD: init_main.c,v 1.285 2006/12/11 15:24:28 yamt Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993 @@ -71,7 +71,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.284 2006/12/07 20:23:38 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.285 2006/12/11 15:24:28 yamt Exp $"); #include "opt_ipsec.h" #include "opt_kcont.h" @@ -81,7 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.284 2006/12/07 20:23:38 ad Exp $"); #include "opt_posix.h" #include "opt_syscall_debug.h" #include "opt_sysv.h" -#include "opt_fileassoc.h" #include "opt_pax.h" #include "rnd.h" @@ -153,10 +152,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.284 2006/12/07 20:23:38 ad Exp $"); #include #include -#ifdef FILEASSOC -#include -#endif /* FILEASSOC */ - #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) #include #endif /* PAX_MPROTECT || PAX_SEGVGUARD */ @@ -381,10 +376,6 @@ main(void) /* Initialize default security model. */ secmodel_start(); -#ifdef FILEASSOC - fileassoc_init(); -#endif /* FILEASSOC */ - #if NVERIEXEC > 0 /* * Initialise the Veriexec subsystem. diff --git a/sys/kern/kern_fileassoc.c b/sys/kern/kern_fileassoc.c index 82ef072001e2..0bf8e1c8483b 100644 --- a/sys/kern/kern_fileassoc.c +++ b/sys/kern/kern_fileassoc.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_fileassoc.c,v 1.13 2006/12/08 13:23:22 yamt Exp $ */ +/* $NetBSD: kern_fileassoc.c,v 1.14 2006/12/11 15:24:28 yamt Exp $ */ /*- * Copyright (c) 2006 Elad Efrat @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.13 2006/12/08 13:23:22 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.14 2006/12/11 15:24:28 yamt Exp $"); #include "opt_fileassoc.h" @@ -46,32 +46,36 @@ __KERNEL_RCSID(0, "$NetBSD: kern_fileassoc.c,v 1.13 2006/12/08 13:23:22 yamt Exp #include #include #include +#include #include #include - -/* Max. number of hooks. */ -#ifndef FILEASSOC_NHOOKS -#define FILEASSOC_NHOOKS 4 -#endif /* !FILEASSOC_NHOOKS */ +#include +#include static struct fileassoc_hash_entry * fileassoc_file_lookup(struct vnode *, fhandle_t *); static struct fileassoc_hash_entry * fileassoc_file_add(struct vnode *, fhandle_t *); +static specificdata_domain_t fileassoc_domain; + /* * Hook entry. * Includes the hook name for identification and private hook clear callback. */ -struct fileassoc_hook { - const char *hook_name; /* Hook name. */ - fileassoc_cleanup_cb_t hook_cleanup_cb; /* Hook clear callback. */ +struct fileassoc { + LIST_ENTRY(fileassoc) list; + const char *name; /* name. */ + fileassoc_cleanup_cb_t cleanup_cb; /* clear callback. */ + specificdata_key_t key; }; +static LIST_HEAD(, fileassoc) fileassoc_list; + /* An entry in the per-device hash table. */ struct fileassoc_hash_entry { fhandle_t *handle; /* File handle */ - void *hooks[FILEASSOC_NHOOKS]; /* Hooks. */ + specificdata_reference data; /* Hooks. */ LIST_ENTRY(fileassoc_hash_entry) entries; /* List pointer. */ }; @@ -82,13 +86,10 @@ struct fileassoc_table { size_t hash_size; /* Number of slots. */ struct mount *tbl_mntpt; u_long hash_mask; - void *tables[FILEASSOC_NHOOKS]; + specificdata_reference data; LIST_ENTRY(fileassoc_table) hash_list; /* List pointer. */ }; -struct fileassoc_hook fileassoc_hooks[FILEASSOC_NHOOKS]; -int fileassoc_nhooks; - /* Global list of hash tables, one per device. */ LIST_HEAD(, fileassoc_table) fileassoc_tables; @@ -100,54 +101,133 @@ LIST_HEAD(, fileassoc_table) fileassoc_tables; (hash32_buf((handle), FHANDLE_SIZE(handle), HASH32_BUF_INIT) \ & ((tbl)->hash_mask)) +static void * +table_getdata(struct fileassoc_table *tbl, const struct fileassoc *assoc) +{ + + return specificdata_getspecific(fileassoc_domain, &tbl->data, + assoc->key); +} + +static void +table_setdata(struct fileassoc_table *tbl, const struct fileassoc *assoc, + void *data) +{ + + specificdata_setspecific(fileassoc_domain, &tbl->data, assoc->key, + data); +} + +static void +table_cleanup(struct fileassoc_table *tbl, const struct fileassoc *assoc) +{ + fileassoc_cleanup_cb_t cb; + void *data; + + cb = assoc->cleanup_cb; + if (cb == NULL) { + return; + } + data = table_getdata(tbl, assoc); + (*cb)(data, FILEASSOC_CLEANUP_TABLE); +} + +static void * +file_getdata(struct fileassoc_hash_entry *e, const struct fileassoc *assoc) +{ + + return specificdata_getspecific(fileassoc_domain, &e->data, + assoc->key); +} + +static void +file_setdata(struct fileassoc_hash_entry *e, const struct fileassoc *assoc, + void *data) +{ + + specificdata_setspecific(fileassoc_domain, &e->data, assoc->key, + data); +} + +static void +file_cleanup(struct fileassoc_hash_entry *e, const struct fileassoc *assoc) +{ + fileassoc_cleanup_cb_t cb; + void *data; + + cb = assoc->cleanup_cb; + if (cb == NULL) { + return; + } + data = file_getdata(e, assoc); + (*cb)(data, FILEASSOC_CLEANUP_FILE); +} + +static void +file_free(struct fileassoc_hash_entry *e) +{ + struct fileassoc *assoc; + + LIST_REMOVE(e, entries); + + LIST_FOREACH(assoc, &fileassoc_list, list) { + file_cleanup(e, assoc); + } + vfs_composefh_free(e->handle); + specificdata_fini(fileassoc_domain, &e->data); + kmem_free(e, sizeof(*e)); +} + /* * Initialize the fileassoc subsystem. */ -void +static int fileassoc_init(void) { - memset(fileassoc_hooks, 0, sizeof(fileassoc_hooks)); - fileassoc_nhooks = 0; + + fileassoc_domain = specificdata_domain_create(); + + return 0; } /* * Register a new hook. */ -fileassoc_t -fileassoc_register(const char *name, fileassoc_cleanup_cb_t cleanup_cb) +int +fileassoc_register(const char *name, fileassoc_cleanup_cb_t cleanup_cb, + fileassoc_t *result) { - int i; + int error; + specificdata_key_t key; + struct fileassoc *assoc; + static ONCE_DECL(control); - if (fileassoc_nhooks >= FILEASSOC_NHOOKS) - return (-1); + RUN_ONCE(&control, fileassoc_init); + error = specificdata_key_create(fileassoc_domain, &key, NULL); + if (error) { + return error; + } + assoc = kmem_alloc(sizeof(*assoc), KM_SLEEP); + assoc->name = name; + assoc->cleanup_cb = cleanup_cb; + assoc->key = key; + LIST_INSERT_HEAD(&fileassoc_list, assoc, list); + *result = assoc; - for (i = 0; i < FILEASSOC_NHOOKS; i++) - if (fileassoc_hooks[i].hook_name == NULL) - break; - - fileassoc_hooks[i].hook_name = name; - fileassoc_hooks[i].hook_cleanup_cb = cleanup_cb; - - fileassoc_nhooks++; - - return (i); + return 0; } /* * Deregister a hook. */ int -fileassoc_deregister(fileassoc_t id) +fileassoc_deregister(fileassoc_t assoc) { - if (id < 0 || id >= FILEASSOC_NHOOKS) - return (EINVAL); - fileassoc_hooks[id].hook_name = NULL; - fileassoc_hooks[id].hook_cleanup_cb = NULL; + LIST_REMOVE(assoc, list); + kmem_free(assoc, sizeof(*assoc)); - fileassoc_nhooks--; - - return (0); + return 0; } /* @@ -222,7 +302,7 @@ fileassoc_file_lookup(struct vnode *vp, fhandle_t *hint) * Return hook data associated with a vnode. */ void * -fileassoc_lookup(struct vnode *vp, fileassoc_t id) +fileassoc_lookup(struct vnode *vp, fileassoc_t assoc) { struct fileassoc_hash_entry *mhe; @@ -230,7 +310,7 @@ fileassoc_lookup(struct vnode *vp, fileassoc_t id) if (mhe == NULL) return (NULL); - return (mhe->hooks[id]); + return file_getdata(mhe, assoc); } /* @@ -246,11 +326,12 @@ fileassoc_table_add(struct mount *mp, size_t size) return (EEXIST); /* Allocate and initialize a Veriexec hash table. */ - tbl = malloc(sizeof(*tbl), M_TEMP, M_WAITOK | M_ZERO); + tbl = kmem_zalloc(sizeof(*tbl), KM_SLEEP); tbl->hash_size = size; tbl->tbl_mntpt = mp; tbl->hash_tbl = hashinit(size, HASH_LIST, M_TEMP, M_WAITOK | M_ZERO, &tbl->hash_mask); + specificdata_init(fileassoc_domain, &tbl->data); LIST_INSERT_HEAD(&fileassoc_tables, tbl, hash_list); @@ -263,10 +344,10 @@ fileassoc_table_add(struct mount *mp, size_t size) int fileassoc_table_delete(struct mount *mp) { + const struct fileassoc *assoc; struct fileassoc_table *tbl; struct fileassoc_hashhead *hh; u_long i; - int j; tbl = fileassoc_table_lookup(mp); if (tbl == NULL) @@ -277,29 +358,20 @@ fileassoc_table_delete(struct mount *mp) for (i = 0; i < tbl->hash_size; i++) { struct fileassoc_hash_entry *mhe; - while (LIST_FIRST(&hh[i]) != NULL) { - mhe = LIST_FIRST(&hh[i]); - LIST_REMOVE(mhe, entries); - - for (j = 0; j < fileassoc_nhooks; j++) - if (fileassoc_hooks[j].hook_cleanup_cb != NULL) - (fileassoc_hooks[j].hook_cleanup_cb) - (mhe->hooks[j], - FILEASSOC_CLEANUP_FILE); - - vfs_composefh_free(mhe->handle); - free(mhe, M_TEMP); + while ((mhe = LIST_FIRST(&hh[i])) != NULL) { + file_free(mhe); } } - for (j = 0; j < fileassoc_nhooks; j++) - if (fileassoc_hooks[j].hook_cleanup_cb != NULL) - (fileassoc_hooks[j].hook_cleanup_cb)(tbl->tables[j], - FILEASSOC_CLEANUP_TABLE); + LIST_FOREACH(assoc, &fileassoc_list, list) { + table_cleanup(tbl, assoc); + } /* Remove hash table and sysctl node */ hashdone(tbl->hash_tbl, M_TEMP); LIST_REMOVE(tbl, hash_list); + specificdata_fini(fileassoc_domain, &tbl->data); + kmem_free(tbl, sizeof(*tbl)); return (0); } @@ -308,7 +380,7 @@ fileassoc_table_delete(struct mount *mp) * Run a callback for each hook entry in a table. */ int -fileassoc_table_run(struct mount *mp, fileassoc_t id, fileassoc_cb_t cb) +fileassoc_table_run(struct mount *mp, fileassoc_t assoc, fileassoc_cb_t cb) { struct fileassoc_table *tbl; struct fileassoc_hashhead *hh; @@ -323,8 +395,11 @@ fileassoc_table_run(struct mount *mp, fileassoc_t id, fileassoc_cb_t cb) struct fileassoc_hash_entry *mhe; LIST_FOREACH(mhe, &hh[i], entries) { - if (mhe->hooks[id] != NULL) - cb(mhe->hooks[id]); + void *data; + + data = file_getdata(mhe, assoc); + if (data != NULL) + cb(data); } } @@ -335,36 +410,28 @@ fileassoc_table_run(struct mount *mp, fileassoc_t id, fileassoc_cb_t cb) * Clear a table for a given hook. */ int -fileassoc_table_clear(struct mount *mp, fileassoc_t id) +fileassoc_table_clear(struct mount *mp, fileassoc_t assoc) { struct fileassoc_table *tbl; struct fileassoc_hashhead *hh; - fileassoc_cleanup_cb_t cleanup_cb; u_long i; tbl = fileassoc_table_lookup(mp); if (tbl == NULL) return (EEXIST); - cleanup_cb = fileassoc_hooks[id].hook_cleanup_cb; - hh = tbl->hash_tbl; for (i = 0; i < tbl->hash_size; i++) { struct fileassoc_hash_entry *mhe; LIST_FOREACH(mhe, &hh[i], entries) { - if ((mhe->hooks[id] != NULL) && cleanup_cb != NULL) - cleanup_cb(mhe->hooks[id], - FILEASSOC_CLEANUP_FILE); - - mhe->hooks[id] = NULL; + file_cleanup(mhe, assoc); + file_setdata(mhe, assoc, NULL); } } - if ((tbl->tables[id] != NULL) && cleanup_cb != NULL) - cleanup_cb(tbl->tables[id], FILEASSOC_CLEANUP_TABLE); - - tbl->tables[id] = NULL; + table_cleanup(tbl, assoc); + table_setdata(tbl, assoc, NULL); return (0); } @@ -373,7 +440,7 @@ fileassoc_table_clear(struct mount *mp, fileassoc_t id) * Add hook-specific data on a fileassoc table. */ int -fileassoc_tabledata_add(struct mount *mp, fileassoc_t id, void *data) +fileassoc_tabledata_add(struct mount *mp, fileassoc_t assoc, void *data) { struct fileassoc_table *tbl; @@ -381,7 +448,7 @@ fileassoc_tabledata_add(struct mount *mp, fileassoc_t id, void *data) if (tbl == NULL) return (EFAULT); - tbl->tables[id] = data; + table_setdata(tbl, assoc, data); return (0); } @@ -390,24 +457,17 @@ fileassoc_tabledata_add(struct mount *mp, fileassoc_t id, void *data) * Clear hook-specific data on a fileassoc table. */ int -fileassoc_tabledata_clear(struct mount *mp, fileassoc_t id) +fileassoc_tabledata_clear(struct mount *mp, fileassoc_t assoc) { - struct fileassoc_table *tbl; - tbl = fileassoc_table_lookup(mp); - if (tbl == NULL) - return (EFAULT); - - tbl->tables[id] = NULL; - - return (0); + return fileassoc_tabledata_add(mp, assoc, NULL); } /* * Retrieve hook-specific data from a fileassoc table. */ void * -fileassoc_tabledata_lookup(struct mount *mp, fileassoc_t id) +fileassoc_tabledata_lookup(struct mount *mp, fileassoc_t assoc) { struct fileassoc_table *tbl; @@ -415,7 +475,7 @@ fileassoc_tabledata_lookup(struct mount *mp, fileassoc_t id) if (tbl == NULL) return (NULL); - return (tbl->tables[id]); + return table_getdata(tbl, assoc); } /* @@ -457,8 +517,9 @@ fileassoc_file_add(struct vnode *vp, fhandle_t *hint) indx = FILEASSOC_HASH(tbl, th); vhh = &(tbl->hash_tbl[indx]); - e = malloc(sizeof(*e), M_TEMP, M_WAITOK | M_ZERO); + e = kmem_zalloc(sizeof(*e), KM_SLEEP); e->handle = th; + specificdata_init(fileassoc_domain, &e->data); LIST_INSERT_HEAD(vhh, e, entries); return (e); @@ -471,20 +532,12 @@ int fileassoc_file_delete(struct vnode *vp) { struct fileassoc_hash_entry *mhe; - int i; mhe = fileassoc_file_lookup(vp, NULL); if (mhe == NULL) return (ENOENT); - LIST_REMOVE(mhe, entries); - - for (i = 0; i < fileassoc_nhooks; i++) - if (fileassoc_hooks[i].hook_cleanup_cb != NULL) - (fileassoc_hooks[i].hook_cleanup_cb)(mhe->hooks[i], - FILEASSOC_CLEANUP_FILE); - - free(mhe, M_TEMP); + file_free(mhe); return (0); } @@ -493,9 +546,10 @@ fileassoc_file_delete(struct vnode *vp) * Add a hook to a vnode. */ int -fileassoc_add(struct vnode *vp, fileassoc_t id, void *data) +fileassoc_add(struct vnode *vp, fileassoc_t assoc, void *data) { struct fileassoc_hash_entry *e; + void *olddata; e = fileassoc_file_lookup(vp, NULL); if (e == NULL) { @@ -504,10 +558,11 @@ fileassoc_add(struct vnode *vp, fileassoc_t id, void *data) return (ENOTDIR); } - if (e->hooks[id] != NULL) + olddata = file_getdata(e, assoc); + if (olddata != NULL) return (EEXIST); - e->hooks[id] = data; + file_setdata(e, assoc, data); return (0); } @@ -516,20 +571,16 @@ fileassoc_add(struct vnode *vp, fileassoc_t id, void *data) * Clear a hook from a vnode. */ int -fileassoc_clear(struct vnode *vp, fileassoc_t id) +fileassoc_clear(struct vnode *vp, fileassoc_t assoc) { struct fileassoc_hash_entry *mhe; - fileassoc_cleanup_cb_t cleanup_cb; mhe = fileassoc_file_lookup(vp, NULL); if (mhe == NULL) return (ENOENT); - cleanup_cb = fileassoc_hooks[id].hook_cleanup_cb; - if ((mhe->hooks[id] != NULL) && cleanup_cb != NULL) - cleanup_cb(mhe->hooks[id], FILEASSOC_CLEANUP_FILE); - - mhe->hooks[id] = NULL; + file_cleanup(mhe, assoc); + file_setdata(mhe, assoc, NULL); return (0); } diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c index 8d55004e1006..727935caee61 100644 --- a/sys/kern/kern_pax.c +++ b/sys/kern/kern_pax.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_pax.c,v 1.8 2006/11/22 02:02:51 elad Exp $ */ +/* $NetBSD: kern_pax.c,v 1.9 2006/12/11 15:24:28 yamt Exp $ */ /*- * Copyright (c) 2006 Elad Efrat @@ -182,12 +182,20 @@ SYSCTL_SETUP(sysctl_security_pax_setup, "sysctl security.pax setup") void pax_init(void) { +#ifdef PAX_SEGVGUARD + int error; +#endif /* PAX_SEGVGUARD */ + #ifdef PAX_MPROTECT proc_specific_key_create(&pax_mprotect_key, NULL); #endif /* PAX_MPROTECT */ #ifdef PAX_SEGVGUARD - segvguard_id = fileassoc_register("segvguard", pax_segvguard_cb); + error = fileassoc_register("segvguard", pax_segvguard_cb, + &segvguard_id); + if (error) { + panic("pax_init: segvguard_id: error=%d\n", error); + } proc_specific_key_create(&pax_segvguard_key, NULL); #endif /* PAX_SEGVGUARD */ } @@ -286,7 +294,7 @@ pax_segvguard(struct lwp *l, struct vnode *vp, const char *name, (!pax_segvguard_global && t != PAX_SEGVGUARD_EXPLICIT_ENABLE)) return (0); - if (segvguard_id == FILEASSOC_INVAL || vp == NULL) + if (vp == NULL) return (EFAULT); /* Check if we already monitor the file. */ diff --git a/sys/kern/kern_verifiedexec.c b/sys/kern/kern_verifiedexec.c index 0a56f583a4a6..7db518fb33ee 100644 --- a/sys/kern/kern_verifiedexec.c +++ b/sys/kern/kern_verifiedexec.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_verifiedexec.c,v 1.78 2006/11/30 16:53:48 elad Exp $ */ +/* $NetBSD: kern_verifiedexec.c,v 1.79 2006/12/11 15:24:28 yamt Exp $ */ /*- * Copyright 2005 Elad Efrat @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.78 2006/11/30 16:53:48 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.79 2006/12/11 15:24:28 yamt Exp $"); #include "opt_veriexec.h" @@ -102,7 +102,7 @@ size_t veriexec_name_max; const struct sysctlnode *veriexec_count_node; -int veriexec_hook; +static fileassoc_t veriexec_hook; LIST_HEAD(, veriexec_fpops) veriexec_fpops_list; @@ -267,10 +267,12 @@ veriexec_fpops_add(const char *fp_type, size_t hash_len, size_t ctx_size, void veriexec_init(void) { + int error; + /* Register a fileassoc for Veriexec. */ - veriexec_hook = fileassoc_register("veriexec", veriexec_clear); - if (veriexec_hook == FILEASSOC_INVAL) - panic("Veriexec: Can't register fileassoc"); + error = fileassoc_register("veriexec", veriexec_clear, &veriexec_hook); + if (error != 0) + panic("Veriexec: Can't register fileassoc: error=%d", error); /* Register listener to handle raw disk access. */ if (kauth_listen_scope(KAUTH_SCOPE_DEVICE, veriexec_raw_cb, NULL) == diff --git a/sys/sys/fileassoc.h b/sys/sys/fileassoc.h index 9e2b7ba39f38..7c16ddf7ad88 100644 --- a/sys/sys/fileassoc.h +++ b/sys/sys/fileassoc.h @@ -1,4 +1,4 @@ -/* $NetBSD: fileassoc.h,v 1.6 2006/12/08 13:23:22 yamt Exp $ */ +/* $NetBSD: fileassoc.h,v 1.7 2006/12/11 15:24:28 yamt Exp $ */ /*- * Copyright (c) 2006 Elad Efrat @@ -36,17 +36,14 @@ #include #include -#define FILEASSOC_INVAL -1 - -typedef int fileassoc_t; +typedef struct fileassoc *fileassoc_t; typedef void (*fileassoc_cleanup_cb_t)(void *, int); typedef void (*fileassoc_cb_t)(void *); #define FILEASSOC_CLEANUP_TABLE 0 #define FILEASSOC_CLEANUP_FILE 1 -void fileassoc_init(void); -fileassoc_t fileassoc_register(const char *, fileassoc_cleanup_cb_t); +int fileassoc_register(const char *, fileassoc_cleanup_cb_t, fileassoc_t *); int fileassoc_deregister(fileassoc_t); void *fileassoc_tabledata_lookup(struct mount *, fileassoc_t); void *fileassoc_lookup(struct vnode *, fileassoc_t);