linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [TOMOYO 5/9] Memory and pathname management functions.
@ 2007-06-15  7:16 Albert Cahalan
  2007-06-15 13:00 ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Albert Cahalan @ 2007-06-15  7:16 UTC (permalink / raw)
  To: linux-kernel, linux-security-module, takedakn, hch

Christoph Hellwig writes:
> On Thu, Jun 14, 2007 at 04:36:09PM +0900, Kentaro Takeda wrote:

>> We limit the maximum length of any string data (such as
>> domainname and pathnames) to TOMOYO_MAX_PATHNAME_LEN
>> (which is 4000) bytes to fit within a single page.
>>
>> Userland programs can obtain the amount of RAM currently
>> used by TOMOYO from /proc interface.
>
> Same NACK for this as for AppArmor, on exactly the same grounds.
> Please stop wasting your time on pathname-based non-solutions.

This issue is a very very small wart on an otherwise fine idea.
It's really not worth getting bothered by. Truth is, big giant
pathnames break lots of stuff already, both kernel and userspace.

Just look in /proc for some nice juicy kernel breakage:
cwd, exe, fd/*, maps, mounts, mountstats, root, smaps

So, is that a NACK for the /proc filesystem too? :-)

We even limit filenames to 255 chars; just the other day
a Russian guy was complaining that his monstrous filenames
on a vfat filesystem could not be represented in UTF-8 mode.

Both TOMOYO and AppArmor are good ideas. At minimum, one of
them ought to be accepted. My preference would be TOMOYO,
having origins untainted by Novell's Microsoft dealings.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-15  7:16 [TOMOYO 5/9] Memory and pathname management functions Albert Cahalan
@ 2007-06-15 13:00 ` Pavel Machek
  2007-06-16  9:08   ` Albert Cahalan
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2007-06-15 13:00 UTC (permalink / raw)
  To: Albert Cahalan; +Cc: linux-kernel, linux-security-module, takedakn, hch

Hi!

> >>We limit the maximum length of any string data (such as
> >>domainname and pathnames) to TOMOYO_MAX_PATHNAME_LEN
> >>(which is 4000) bytes to fit within a single page.
> >>
> >>Userland programs can obtain the amount of RAM 
> >>currently
> >>used by TOMOYO from /proc interface.
> >
> >Same NACK for this as for AppArmor, on exactly the same 
> >grounds.
> >Please stop wasting your time on pathname-based 
> >non-solutions.
> 
> This issue is a very very small wart on an otherwise 
> fine idea.
> It's really not worth getting bothered by. Truth is, big 
> giant
> pathnames break lots of stuff already, both kernel and 
> userspace.

> Just look in /proc for some nice juicy kernel breakage:
> cwd, exe, fd/*, maps, mounts, mountstats, root, smaps

Well, but we should be fixing that, not adding more. And /proc is
info-only, while this is security related code.

							Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-15 13:00 ` Pavel Machek
@ 2007-06-16  9:08   ` Albert Cahalan
  2007-06-21 18:22     ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Albert Cahalan @ 2007-06-16  9:08 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel, linux-security-module, takedakn, hch

On 6/15/07, Pavel Machek <pavel@ucw.cz> wrote:
> [Albert Cahalan]

> > It's really not worth getting bothered by. Truth is, big
> > giant
> > pathnames break lots of stuff already, both kernel and
> > userspace.
>
> > Just look in /proc for some nice juicy kernel breakage:
> > cwd, exe, fd/*, maps, mounts, mountstats, root, smaps
>
> Well, but we should be fixing that, not adding more. And /proc is
> info-only, while this is security related code.

Security tools read from /proc, so /proc is security-related.

The limit imposed by TOMOYO (or AppArmor) is fine,
despite being security-related. It just needs to fail in
the safe direction: access denied.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-16  9:08   ` Albert Cahalan
@ 2007-06-21 18:22     ` Pavel Machek
  2007-06-22 14:45       ` Albert Cahalan
  0 siblings, 1 reply; 8+ messages in thread
From: Pavel Machek @ 2007-06-21 18:22 UTC (permalink / raw)
  To: Albert Cahalan; +Cc: linux-kernel, linux-security-module, takedakn, hch

Hi!

> >> It's really not worth getting bothered by. Truth is, big
> >> giant
> >> pathnames break lots of stuff already, both kernel and
> >> userspace.
> >
> >> Just look in /proc for some nice juicy kernel breakage:
> >> cwd, exe, fd/*, maps, mounts, mountstats, root, smaps
> >
> >Well, but we should be fixing that, not adding more. And /proc is
> >info-only, while this is security related code.
> 
> Security tools read from /proc, so /proc is security-related.

If some tool relies on pathnames in /proc, that tool is broken... as
is /proc. We should be fixing that.

> The limit imposed by TOMOYO (or AppArmor) is fine,
> despite being security-related. It just needs to fail in

It is not "fine", but maybe it will not get us a bugtraq posting.
								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-21 18:22     ` Pavel Machek
@ 2007-06-22 14:45       ` Albert Cahalan
  0 siblings, 0 replies; 8+ messages in thread
From: Albert Cahalan @ 2007-06-22 14:45 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel, linux-security-module, takedakn, hch

On 6/21/07, Pavel Machek <pavel@ucw.cz> wrote:

> > >> It's really not worth getting bothered by. Truth is, big
> > >> giant
> > >> pathnames break lots of stuff already, both kernel and
> > >> userspace.
> > >
> > >> Just look in /proc for some nice juicy kernel breakage:
> > >> cwd, exe, fd/*, maps, mounts, mountstats, root, smaps
> > >
> > >Well, but we should be fixing that, not adding more. And /proc is
> > >info-only, while this is security related code.
> >
> > Security tools read from /proc, so /proc is security-related.
>
> If some tool relies on pathnames in /proc, that tool is broken... as
> is /proc. We should be fixing that.

Running TOMOYO or AppArmor fixes the bug. :-)
You can't get long paths that break /proc if you are
running either. Therefore, one of those is required.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-14 17:34   ` Christoph Hellwig
@ 2007-06-15  1:19     ` Toshiharu Harada
  0 siblings, 0 replies; 8+ messages in thread
From: Toshiharu Harada @ 2007-06-15  1:19 UTC (permalink / raw)
  To: Christoph Hellwig, Kentaro Takeda, linux-kernel, linux-security-module

Christoph Hellwig wrote:
> On Thu, Jun 14, 2007 at 04:36:09PM +0900, Kentaro Takeda wrote:
>> We limit the maximum length of any string data (such as domainname and 
>> pathnames)
>> to TOMOYO_MAX_PATHNAME_LEN (which is 4000) bytes to fit within a single 
>> page.
>>
>> Userland programs can obtain the amount of RAM currently used by TOMOYO 
>> from /proc interface.
> 
> Same NACK for this as for AppArmor, on exactly the same grounds.  Please
> stop wasting your time on pathname-based non-solutions.

TOMOYO Linux is a pathname-based MAC, that is true.
But what that patch aimed for was sharing the idea of having
Linux kernel to keep "process invocation history" information
for each process. In that sense, TOMOYO Linux is just
a sample implementation.

Please take a look at the following message:
http://lkml.org/lkml/2007/6/13/58

Best regards,
Toshiharu Harada


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-14  7:36 ` [TOMOYO 5/9] Memory and pathname management functions Kentaro Takeda
@ 2007-06-14 17:34   ` Christoph Hellwig
  2007-06-15  1:19     ` Toshiharu Harada
  0 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2007-06-14 17:34 UTC (permalink / raw)
  To: Kentaro Takeda; +Cc: linux-kernel, linux-security-module

On Thu, Jun 14, 2007 at 04:36:09PM +0900, Kentaro Takeda wrote:
> We limit the maximum length of any string data (such as domainname and 
> pathnames)
> to TOMOYO_MAX_PATHNAME_LEN (which is 4000) bytes to fit within a single 
> page.
> 
> Userland programs can obtain the amount of RAM currently used by TOMOYO 
> from /proc interface.


Same NACK for this as for AppArmor, on exactly the same grounds.  Please
stop wasting your time on pathname-based non-solutions.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [TOMOYO 5/9] Memory and pathname management functions.
  2007-06-14  7:30 [TOMOYO 0/9] TOMOYO Linux security module Kentaro Takeda
@ 2007-06-14  7:36 ` Kentaro Takeda
  2007-06-14 17:34   ` Christoph Hellwig
  0 siblings, 1 reply; 8+ messages in thread
From: Kentaro Takeda @ 2007-06-14  7:36 UTC (permalink / raw)
  To: linux-kernel, linux-security-module

We limit the maximum length of any string data (such as domainname and pathnames)
to TOMOYO_MAX_PATHNAME_LEN (which is 4000) bytes to fit within a single page.

Userland programs can obtain the amount of RAM currently used by TOMOYO from /proc interface.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

---------------
 security/tomoyo/include/realpath.h |   46 +++++
 security/tomoyo/realpath.c         |  445 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 491 insertions(+)

diff -ubBpErN linux-2.6.21.5/security/tomoyo/include/realpath.h linux-2.6.21.5-tomoyo/security/tomoyo/include/realpath.h
--- linux-2.6.21.5/security/tomoyo/include/realpath.h	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/include/realpath.h	2007-06-05 00:00:00.000000000 +0900
@@ -0,0 +1,46 @@
+/*
+ * security/tomoyo/include/realpath.h
+ *
+ * Get the canonicalized absolute pathnames. The basis for TOMOYO.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ *
+ */
+
+#ifndef _TOMOYO_REALPATH_H
+#define _TOMOYO_REALPATH_H
+
+struct path_info;
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+int tomoyo_realpath_from_dentry2(struct dentry *dentry,
+                                 struct vfsmount *mnt,
+                                 char *newname,
+                                 int newname_len);
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+/* These functions use tomoyo_alloc(), so caller must tomoyo_free() */
+/* if these functions didn't return NULL. */
+char *tomoyo_realpath(const char *pathname);
+char *tomoyo_realpath_nofollow(const char *pathname);
+char *tomoyo_realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt);
+
+/* Allocate memory for structures. */
+/* The RAM is chunked, so NEVER try to kfree() the returned pointer. */
+void *tomoyo_alloc_element(const unsigned int size);
+
+/* Get used RAM size for tomoyo_alloc_elements(). */
+unsigned int tomoyo_get_memory_used_for_elements(void);
+
+/* Keep the given name on the RAM. */
+/* The RAM is shared, so NEVER try to modify or kfree() the returned name. */
+const struct path_info *tomoyo_save_name(const char *name);
+
+/* Get used RAM size for tomoyo_save_name(). */
+unsigned int tomoyo_get_memory_used_for_save_name(void);
+
+unsigned int tomoyo_get_memory_used_for_dynamic(void);
+
+#endif
diff -ubBpErN linux-2.6.21.5/security/tomoyo/realpath.c linux-2.6.21.5-tomoyo/security/tomoyo/realpath.c
--- linux-2.6.21.5/security/tomoyo/realpath.c	1970-01-01 09:00:00.000000000 +0900
+++ linux-2.6.21.5-tomoyo/security/tomoyo/realpath.c	2007-06-14 15:06:37.000000000 +0900
@@ -0,0 +1,445 @@
+/*
+ * security/tomoyo/realpath.c
+ *
+ * Get the canonicalized absolute pathnames.
+ * The basis for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2007  NTT DATA CORPORATION
+ *
+ * Version: 2.0   2007/06/05
+ */
+
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/utime.h>
+#include <linux/file.h>
+#include <linux/smp_lock.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/proc_fs.h>
+#include "realpath.h"
+#include "tomoyo.h"
+
+extern int sbin_init_started;
+
+/***** realpath handler *****/
+
+/*
+ * tomoyo_get_absolute_path - return the path of a dentry but ignores chroot'ed root.
+ * @dentry: dentry to report
+ * @vfsmnt: vfsmnt to which the dentry belongs
+ * @buffer: buffer to return value in
+ * @buflen: buffer length
+ *
+ * Caller holds the dcache_lock.
+ * Based on __d_path() in fs/dcache.c
+ *
+ * If dentry is a directory, trailing '/' is appended.
+ * Characters other than ' ' < c < 127 are converted to \ooo style octal string.
+ * Character \ is converted to \\ string.
+ */
+static int tomoyo_get_absolute_path(struct dentry *dentry,
+                                    struct vfsmount *vfsmnt,
+                                    char *buffer,
+                                    int buflen)
+{
+	char *start = buffer;
+	char *end = buffer + buflen;
+	int is_dir = (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode));
+
+	if (buflen < 256) goto out;
+
+	*--end = '\0';
+	buflen--;
+
+	for (;;) {
+		struct dentry *parent;
+
+		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+			/* Global root? */
+			spin_lock(&vfsmount_lock);
+			if (vfsmnt->mnt_parent == vfsmnt) {
+				spin_unlock(&vfsmount_lock);
+				break;
+			}
+			dentry = vfsmnt->mnt_mountpoint;
+			vfsmnt = vfsmnt->mnt_parent;
+			spin_unlock(&vfsmount_lock);
+			continue;
+		}
+		if (is_dir) {
+			is_dir = 0;
+			*--end = '/';
+			buflen--;
+		}
+		parent = dentry->d_parent;
+		{
+			const char *sp = dentry->d_name.name;
+			const char *cp = sp + dentry->d_name.len - 1;
+			unsigned char c;
+
+			/* Exception: Use /proc/self/ rather than /proc/\$/ for current process. */
+			if (IS_ROOT(parent) && *sp > '0' && *sp <= '9' && parent->d_sb
+			    && parent->d_sb->s_magic == PROC_SUPER_MAGIC) {
+				char *ep;
+				const pid_t pid = (pid_t) simple_strtoul(sp, &ep, 10);
+				if (!*ep && pid == current->tgid) {
+					sp = "self";
+					cp = sp + 3;
+				}
+				if (!*ep && pid == current->pid) {
+					sp = "self";
+					cp = sp + 3;
+				}
+			}
+
+			while (sp <= cp) {
+				c = * (unsigned char *) cp;
+				if (c == '\\') {
+					buflen -= 2;
+					if (buflen < 0) goto out;
+					*--end = '\\';
+					*--end = '\\';
+				} else if (c > ' ' && c < 127) {
+					if (--buflen < 0) goto out;
+					*--end = (char) c;
+				} else {
+					buflen -= 4;
+					if (buflen < 0) goto out;
+					*--end = (c & 7) + '0';
+					*--end = ((c >> 3) & 7) + '0';
+					*--end = (c >> 6) + '0';
+					*--end = '\\';
+				}
+				cp--;
+			}
+			if (--buflen < 0) goto out;
+			*--end = '/';
+		}
+		dentry = parent;
+	}
+	if (*end == '/') {
+		buflen++;
+		end++;
+	}
+	{
+		const char *sp = dentry->d_name.name;
+		const char *cp = sp + dentry->d_name.len - 1;
+		unsigned char c;
+		while (sp <= cp) {
+			c = * (unsigned char *) cp;
+			if (c == '\\') {
+				buflen -= 2;
+				if (buflen < 0) goto out;
+				*--end = '\\';
+				*--end = '\\';
+			} else if (c > ' ' && c < 127) {
+				if (--buflen < 0) goto out;
+				*--end = (char) c;
+			} else {
+				buflen -= 4;
+				if (buflen < 0) goto out;
+				*--end = (c & 7) + '0';
+				*--end = ((c >> 3) & 7) + '0';
+				*--end = (c >> 6) + '0';
+				*--end = '\\';
+			}
+			cp--;
+		}
+	}
+	/* Move the pathname to the top of the buffer. */
+	memmove(start, end, strlen(end) + 1);
+	return 0;
+ out:
+	return -ENOMEM;
+}
+
+/* Returns realpath(3) of the given dentry but ignores chroot'ed root. */
+int tomoyo_realpath_from_dentry2(struct dentry *dentry,
+                                 struct vfsmount *mnt,
+                                 char *newname,
+                                 int newname_len)
+{
+	int error;
+	struct dentry *d_dentry;
+	struct vfsmount *d_mnt;
+	if (!dentry || !mnt || !newname || newname_len <= 0) return -EINVAL;
+	if (!current->fs) {
+		printk("%s: current->fs == NULL for pid=%d\n", __FUNCTION__, current->pid);
+		return -ENOENT;
+	}
+	d_dentry = dget(dentry);
+	d_mnt = mntget(mnt);
+	/***** CRITICAL SECTION START *****/
+	spin_lock(&dcache_lock);
+	error = tomoyo_get_absolute_path(d_dentry, d_mnt, newname, newname_len);
+	spin_unlock(&dcache_lock);
+	/***** CRITICAL SECTION END *****/
+	dput(d_dentry);
+	mntput(d_mnt);
+	return error;
+}
+
+/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
+/* These functions use tomoyo_alloc(), so caller must tomoyo_free() */
+/* if these functions didn't return NULL. */
+char *tomoyo_realpath_from_dentry(struct dentry *dentry, struct vfsmount *mnt)
+{
+	char *buf = tomoyo_alloc(TOMOYO_MAX_PATHNAME_LEN);
+	if (buf && tomoyo_realpath_from_dentry2(dentry, mnt, buf, TOMOYO_MAX_PATHNAME_LEN - 1) == 0)
+		return buf;
+	tomoyo_free(buf);
+	return NULL;
+}
+
+char *tomoyo_realpath(const char *pathname)
+{
+	struct nameidata nd;
+	if (pathname && path_lookup(pathname, LOOKUP_FOLLOW, &nd) == 0) {
+		char *buf = tomoyo_realpath_from_dentry(nd.dentry, nd.mnt);
+		path_release(&nd);
+		return buf;
+	}
+	return NULL;
+}
+
+char *tomoyo_realpath_nofollow(const char *pathname)
+{
+	struct nameidata nd;
+	if (pathname && path_lookup(pathname, 0, &nd) == 0) {
+		char *buf = tomoyo_realpath_from_dentry(nd.dentry, nd.mnt);
+		path_release(&nd);
+		return buf;
+	}
+	return NULL;
+}
+
+/***** Private memory allocator. *****/
+
+/*
+ * Round up an integer so that the returned pointers are appropriately aligned.
+ * FIXME: Are there more requirements that is needed for assigning value atomically?
+ */
+static inline unsigned int tomoyo_roundup(const unsigned int size) {
+	if (sizeof(void *) >= sizeof(long)) {
+		return ((size + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *);
+	} else {
+		return ((size + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+	}
+}
+
+static unsigned int allocated_memory_for_elements = 0;
+
+unsigned int tomoyo_get_memory_used_for_elements(void)
+{
+	return allocated_memory_for_elements;
+}
+
+/* Allocate memory for structures. */
+/* The RAM is chunked, so NEVER try to kfree() the returned pointer. */
+void *tomoyo_alloc_element(const unsigned int size)
+{
+	static DECLARE_MUTEX(lock);
+	static char *buf = NULL;
+	static unsigned int buf_used_len = PAGE_SIZE;
+	char *ptr = NULL;
+	const unsigned int word_aligned_size = tomoyo_roundup(size);
+	if (word_aligned_size > PAGE_SIZE) return NULL;
+	down(&lock);
+	if (buf_used_len + word_aligned_size > PAGE_SIZE) {
+		if ((ptr = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL) {
+			printk("ERROR: Out of memory for tomoyo_alloc_element().\n");
+			if (!sbin_init_started) panic("MAC Initialization failed.\n");
+		} else {
+			memset(ptr, 0, PAGE_SIZE);
+			buf = ptr;
+			allocated_memory_for_elements += PAGE_SIZE;
+			buf_used_len = word_aligned_size;
+			ptr = buf;
+		}
+	} else if (word_aligned_size) {
+		int i;
+		ptr = buf + buf_used_len;
+		buf_used_len += word_aligned_size;
+		for (i = 0; i < word_aligned_size; i++) {
+			if (ptr[i]) {
+				printk(KERN_ERR "WARNING: Reserved memory was tainted! "
+				                "The system might go wrong.\n");
+				ptr[i] = '\0';
+			}
+		}
+	}
+	up(&lock);
+	return ptr;
+}
+
+/***** Shared memory allocator. *****/
+
+static unsigned int allocated_memory_for_savename = 0;
+
+unsigned int tomoyo_get_memory_used_for_save_name(void)
+{
+	return allocated_memory_for_savename;
+}
+
+#define MAX_HASH 256
+
+struct name_entry {
+	struct name_entry *next; /* Pointer to next record. NULL if none.             */
+	struct path_info entry;
+};
+
+struct free_memory_block_list {
+	struct free_memory_block_list *next; /* Pointer to next record. NULL if none. */
+	char *ptr;                           /* Pointer to a free area.               */
+	int len;                             /* Length of the area.                   */
+};
+
+/* Keep the given name on the RAM. */
+/* The RAM is shared, so NEVER try to modify or kfree() the returned name. */
+const struct path_info *tomoyo_save_name(const char *name)
+{
+	static struct free_memory_block_list fmb_list = { NULL, NULL, 0 };
+	static struct name_entry name_list[MAX_HASH]; /* The list of names. */
+	static DECLARE_MUTEX(lock);
+	struct name_entry *ptr, *prev = NULL;
+	unsigned int hash;
+	struct free_memory_block_list *fmb = &fmb_list;
+	int len;
+	static int first_call = 1;
+	if (!name) return NULL;
+	len = strlen(name) + 1;
+	if (len > TOMOYO_MAX_PATHNAME_LEN) {
+		printk("ERROR: Name too long for tomoyo_save_name().\n");
+		return NULL;
+	}
+	hash = full_name_hash((const unsigned char *) name, len - 1);
+	down(&lock);
+	if (first_call) {
+		int i;
+		first_call = 0;
+		memset(&name_list, 0, sizeof(name_list));
+		for (i = 0; i < MAX_HASH; i++) {
+			name_list[i].entry.name = "/";
+			tomoyo_fill_path_info(&name_list[i].entry);
+		}
+		if (TOMOYO_MAX_PATHNAME_LEN > PAGE_SIZE) panic("Bad size.");
+	}
+	ptr = &name_list[hash % MAX_HASH];
+	while (ptr) {
+		if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out;
+		prev = ptr;
+		ptr = ptr->next;
+	}
+	while (len > fmb->len) {
+		if (fmb->next) {
+			fmb = fmb->next;
+		} else {
+			char *cp;
+			if ((cp = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL ||
+			    (fmb->next = tomoyo_alloc_element(sizeof(*fmb))) == NULL) {
+				kfree(cp);
+				printk("ERROR: Out of memory for tomoyo_save_name().\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;
+		}
+	}
+	if ((ptr = tomoyo_alloc_element(sizeof(*ptr))) == NULL) goto out;
+	ptr->entry.name = fmb->ptr;
+	memmove(fmb->ptr, name, len);
+	tomoyo_fill_path_info(&ptr->entry);
+	fmb->ptr += len;
+	fmb->len -= len;
+	prev->next = ptr; /* prev != NULL because name_list is not empty. */
+	if (fmb->len == 0) {
+		struct free_memory_block_list *ptr = &fmb_list;
+		while (ptr->next != fmb)
+			ptr = ptr->next;
+		ptr->next = fmb->next;
+	}
+ out:
+	up(&lock);
+	return ptr ? &ptr->entry : NULL;
+}
+
+/***** Dynamic memory allocator. *****/
+
+struct cache_entry {
+	struct list_head list;
+	void *ptr;
+	int size;
+};
+
+static struct kmem_cache *ccs_cachep = NULL;
+
+void tomoyo_realpath_init(void)
+{
+	ccs_cachep = kmem_cache_create("ccs_cache", sizeof(struct cache_entry), 0, 0, NULL, NULL);
+	if (!ccs_cachep) panic("Can't create cache.\n");
+}
+
+static LIST_HEAD(cache_list);
+static spinlock_t cache_list_lock = SPIN_LOCK_UNLOCKED;
+static unsigned int dynamic_memory_size = 0;
+
+unsigned int tomoyo_get_memory_used_for_dynamic(void)
+{
+	return dynamic_memory_size;
+}
+
+void *tomoyo_alloc(const size_t size)
+{
+	void *ret = kmalloc(size, GFP_KERNEL);
+	if (ret) {
+		struct cache_entry *new_entry = kmem_cache_alloc(ccs_cachep, GFP_KERNEL);
+		if (!new_entry) {
+			kfree(ret);
+			ret = NULL;
+		} else {
+			INIT_LIST_HEAD(&new_entry->list);
+			new_entry->ptr = ret;
+			new_entry->size = size;
+			spin_lock(&cache_list_lock);
+			list_add_tail(&new_entry->list, &cache_list);
+			dynamic_memory_size += size;
+			spin_unlock(&cache_list_lock);
+			memset(ret, 0, size);
+		}
+	}
+	return ret;
+}
+
+void tomoyo_free(const void *p)
+{
+	struct list_head *v;
+	struct cache_entry *entry = NULL;
+	if (!p) return;
+	spin_lock(&cache_list_lock);
+	list_for_each(v, &cache_list) {
+		entry = list_entry(v, struct cache_entry, list);
+		if (entry->ptr != p) {
+			entry = NULL;
+			continue;
+		}
+		list_del(&entry->list);
+		dynamic_memory_size -= entry->size;
+		break;
+	}
+	spin_unlock(&cache_list_lock);
+	if (entry) {
+		kfree(p);
+		kmem_cache_free(ccs_cachep, entry);
+	} else {
+		printk("BUG: tomoyo_free() with invalid pointer.\n");
+	}
+}
---------------



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-06-22 14:45 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-15  7:16 [TOMOYO 5/9] Memory and pathname management functions Albert Cahalan
2007-06-15 13:00 ` Pavel Machek
2007-06-16  9:08   ` Albert Cahalan
2007-06-21 18:22     ` Pavel Machek
2007-06-22 14:45       ` Albert Cahalan
  -- strict thread matches above, loose matches on Subject: below --
2007-06-14  7:30 [TOMOYO 0/9] TOMOYO Linux security module Kentaro Takeda
2007-06-14  7:36 ` [TOMOYO 5/9] Memory and pathname management functions Kentaro Takeda
2007-06-14 17:34   ` Christoph Hellwig
2007-06-15  1:19     ` Toshiharu Harada

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).