- 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.
This commit is contained in:
parent
5a004f99ec
commit
b0a14e5934
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 <sys/cdefs.h>
|
||||
__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 <sys/sa.h>
|
||||
#include <sys/syscallargs.h>
|
||||
|
||||
#ifdef FILEASSOC
|
||||
#include <sys/fileassoc.h>
|
||||
#endif /* FILEASSOC */
|
||||
|
||||
#if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD)
|
||||
#include <sys/pax.h>
|
||||
#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.
|
||||
|
@ -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 <elad@NetBSD.org>
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__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 <sys/inttypes.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/fileassoc.h>
|
||||
#include <sys/specificdata.h>
|
||||
#include <sys/hash.h>
|
||||
#include <sys/fstypes.h>
|
||||
|
||||
/* Max. number of hooks. */
|
||||
#ifndef FILEASSOC_NHOOKS
|
||||
#define FILEASSOC_NHOOKS 4
|
||||
#endif /* !FILEASSOC_NHOOKS */
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/once.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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 <elad@NetBSD.org>
|
||||
@ -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. */
|
||||
|
@ -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 <elad@NetBSD.org>
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__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) ==
|
||||
|
@ -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 <elad@NetBSD.org>
|
||||
@ -36,17 +36,14 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user