5 |
* |
* |
6 |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.5.2-pre 2007/11/19 |
* Version: 1.5.2-pre 2007/11/27 |
9 |
* |
* |
10 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
280 |
#define MAX_HASH 256 |
#define MAX_HASH 256 |
281 |
|
|
282 |
struct name_entry { |
struct name_entry { |
283 |
struct name_entry *next; /* Pointer to next record. NULL if none. */ |
struct list1_head list; |
284 |
struct path_info entry; |
struct path_info entry; |
285 |
}; |
}; |
286 |
|
|
287 |
struct free_memory_block_list { |
struct free_memory_block_list { |
288 |
struct free_memory_block_list *next; /* Pointer to next record. NULL if none. */ |
struct list_head list; |
289 |
char *ptr; /* Pointer to a free area. */ |
char *ptr; /* Pointer to a free area. */ |
290 |
int len; /* Length of the area. */ |
int len; /* Length of the area. */ |
291 |
}; |
}; |
292 |
|
|
293 |
|
static struct list1_head name_list[MAX_HASH]; /* The list of names. */ |
294 |
|
|
295 |
/* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */ |
/* Keep the given name on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned name. */ |
296 |
const struct path_info *SaveName(const char *name) |
const struct path_info *SaveName(const char *name) |
297 |
{ |
{ |
298 |
static struct free_memory_block_list fmb_list = { NULL, NULL, 0 }; |
static LIST_HEAD(fmb_list); |
|
static struct name_entry name_list[MAX_HASH]; /* The list of names. */ |
|
299 |
static DEFINE_MUTEX(lock); |
static DEFINE_MUTEX(lock); |
300 |
struct name_entry *ptr, *prev = NULL; |
struct name_entry *ptr; |
301 |
unsigned int hash; |
unsigned int hash; |
302 |
struct free_memory_block_list *fmb = &fmb_list; |
struct free_memory_block_list *fmb; |
303 |
int len; |
int len; |
304 |
static int first_call = 1; |
char *cp; |
305 |
if (!name) return NULL; |
if (!name) return NULL; |
306 |
len = strlen(name) + 1; |
len = strlen(name) + 1; |
307 |
if (len > CCS_MAX_PATHNAME_LEN) { |
if (len > CCS_MAX_PATHNAME_LEN) { |
310 |
} |
} |
311 |
hash = full_name_hash((const unsigned char *) name, len - 1); |
hash = full_name_hash((const unsigned char *) name, len - 1); |
312 |
mutex_lock(&lock); |
mutex_lock(&lock); |
313 |
if (first_call) { |
list1_for_each_entry(ptr, &name_list[hash % MAX_HASH], list) { |
|
int i; |
|
|
first_call = 0; |
|
|
memset(&name_list, 0, sizeof(name_list)); |
|
|
for (i = 0; i < MAX_HASH; i++) { |
|
|
name_list[i].entry.name = "/"; |
|
|
fill_path_info(&name_list[i].entry); |
|
|
} |
|
|
if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size."); |
|
|
} |
|
|
ptr = &name_list[hash % MAX_HASH]; |
|
|
while (ptr) { |
|
314 |
if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out; |
if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out; |
|
prev = ptr; ptr = ptr->next; |
|
315 |
} |
} |
316 |
while (len > fmb->len) { |
list_for_each_entry(fmb, &fmb_list, list) { |
317 |
if (fmb->next) { |
if (len <= fmb->len) goto ready; |
|
fmb = fmb->next; |
|
|
} else { |
|
|
char *cp; |
|
|
if ((cp = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL || (fmb->next = alloc_element(sizeof(*fmb))) == NULL) { |
|
|
kfree(cp); |
|
|
printk("ERROR: Out of memory for SaveName().\n"); |
|
|
if (!sbin_init_started) panic("MAC Initialization failed.\n"); |
|
|
goto out; /* ptr == NULL */ |
|
|
} |
|
|
memset(cp, 0, PAGE_SIZE); |
|
|
allocated_memory_for_savename += PAGE_SIZE; |
|
|
fmb = fmb->next; |
|
|
fmb->ptr = cp; |
|
|
fmb->len = PAGE_SIZE; |
|
|
} |
|
318 |
} |
} |
319 |
if ((ptr = alloc_element(sizeof(*ptr))) == NULL) goto out; |
cp = kmalloc(PAGE_SIZE, GFP_KERNEL); |
320 |
|
fmb = kmalloc(sizeof(*fmb), GFP_KERNEL); |
321 |
|
if (!cp || !fmb) { |
322 |
|
kfree(cp); |
323 |
|
kfree(fmb); |
324 |
|
printk("ERROR: Out of memory for SaveName().\n"); |
325 |
|
if (!sbin_init_started) panic("MAC Initialization failed.\n"); |
326 |
|
ptr = NULL; |
327 |
|
goto out; |
328 |
|
} |
329 |
|
memset(cp, 0, PAGE_SIZE); |
330 |
|
allocated_memory_for_savename += PAGE_SIZE; |
331 |
|
list_add(&fmb->list, &fmb_list); |
332 |
|
fmb->ptr = cp; |
333 |
|
fmb->len = PAGE_SIZE; |
334 |
|
ready: |
335 |
|
ptr = alloc_element(sizeof(*ptr)); |
336 |
|
if (!ptr) goto out; |
337 |
ptr->entry.name = fmb->ptr; |
ptr->entry.name = fmb->ptr; |
338 |
memmove(fmb->ptr, name, len); |
memmove(fmb->ptr, name, len); |
339 |
fill_path_info(&ptr->entry); |
fill_path_info(&ptr->entry); |
340 |
fmb->ptr += len; |
fmb->ptr += len; |
341 |
fmb->len -= len; |
fmb->len -= len; |
342 |
prev->next = ptr; /* prev != NULL because name_list is not empty. */ |
list1_add_tail_mb(&ptr->list, &name_list[hash % MAX_HASH]); |
343 |
if (fmb->len == 0) { |
if (fmb->len == 0) { |
344 |
struct free_memory_block_list *ptr = &fmb_list; |
list_del(&fmb->list); |
345 |
while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next; |
kfree(fmb); |
346 |
} |
} |
347 |
out: |
out: |
348 |
mutex_unlock(&lock); |
mutex_unlock(&lock); |
365 |
|
|
366 |
void __init realpath_Init(void) |
void __init realpath_Init(void) |
367 |
{ |
{ |
368 |
|
int i; |
369 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) |
370 |
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL); |
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL); |
371 |
#else |
#else |
372 |
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL); |
ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL); |
373 |
#endif |
#endif |
374 |
if (!ccs_cachep) panic("Can't create cache.\n"); |
if (!ccs_cachep) panic("Can't create cache.\n"); |
375 |
|
for (i = 0; i < MAX_HASH; i++) { |
376 |
|
INIT_LIST1_HEAD(&name_list[i]); |
377 |
|
} |
378 |
|
if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size."); |
379 |
INIT_LIST1_HEAD(&KERNEL_DOMAIN.acl_info_list); |
INIT_LIST1_HEAD(&KERNEL_DOMAIN.acl_info_list); |
380 |
KERNEL_DOMAIN.domainname = SaveName(ROOT_NAME); |
KERNEL_DOMAIN.domainname = SaveName(ROOT_NAME); |
381 |
list1_add_tail_mb(&KERNEL_DOMAIN.list, &domain_list); |
list1_add_tail_mb(&KERNEL_DOMAIN.list, &domain_list); |