/* * dcookies.c * * Copyright 2002 John Levon <levon@movementarian.org> * * Persistent cookie-path mappings. These are used by * profilers to convert a per-task EIP value into something * non-transitory that can be processed at a later date. * This is done by locking the dentry/vfsmnt pair in the * kernel until released by the tasks needing the persistent * objects. The tag is simply an unsigned long that refers * to the pair and can be looked up from userspace. */#include <linux/syscalls.h>

{unsignedlongcookie=(unsignedlong)cookie64;interr=-EINVAL;char*kbuf;char*path;size_tpathlen;structdcookie_struct*dcs;/* we could leak path information to users * without dir read permission without this */if(!capable(CAP_SYS_ADMIN))return-EPERM;

if(!dcookie_cache)gotoout;dcookie_hashtable=kmalloc(PAGE_SIZE,GFP_KERNEL);if(!dcookie_hashtable)gotoout_kmem;err=0;/* * Find the power-of-two list-heads that can fit into the allocation.. * We don't guarantee that "sizeof(struct list_head)" is necessarily * a power-of-two. */hash_size=PAGE_SIZE/sizeof(structlist_head);hash_bits=0;do{hash_bits++;}while((hash_size>>hash_bits)!=0);hash_bits--;/* * Re-calculate the actual number of entries and the mask * from the number of bits we can fit. */hash_size=1UL<<hash_bits;/* And initialize the newly allocated array */d=dcookie_hashtable;i=hash_size;do{INIT_LIST_HEAD(d);d++;i--;}while(i);out:returnerr;out_kmem:kmem_cache_destroy(dcookie_cache);gotoout;}staticvoidfree_dcookie(structdcookie_struct*dcs){