2 * security/tomoyo/realpath.c
4 * Get the canonicalized absolute pathnames. The basis for TOMOYO.
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
8 * Version: 2.2.0 2009/04/01
12 #include <linux/types.h>
13 #include <linux/mount.h>
14 #include <linux/mnt_namespace.h>
15 #include <linux/fs_struct.h>
16 #include <linux/hash.h>
17 #include <linux/magic.h>
21 * tomoyo_encode: Convert binary string to ascii string.
23 * @buffer: Buffer for ASCII string.
24 * @buflen: Size of @buffer.
25 * @str: Binary string.
27 * Returns 0 on success, -ENOMEM otherwise.
29 int tomoyo_encode(char *buffer
, int buflen
, const char *str
)
32 const unsigned char c
= *(unsigned char *) str
++;
34 if (tomoyo_is_valid(c
)) {
55 *buffer
++ = (c
>> 6) + '0';
56 *buffer
++ = ((c
>> 3) & 7) + '0';
57 *buffer
++ = (c
& 7) + '0';
63 * tomoyo_realpath_from_path2 - Returns realpath(3) of the given dentry but ignores chroot'ed root.
65 * @path: Pointer to "struct path".
66 * @newname: Pointer to buffer to return value in.
67 * @newname_len: Size of @newname.
69 * Returns 0 on success, negative value otherwise.
71 * If dentry is a directory, trailing '/' is appended.
72 * Characters out of 0x20 < c < 0x7F range are converted to
73 * \ooo style octal string.
74 * Character \ is converted to \\ string.
76 int tomoyo_realpath_from_path2(struct path
*path
, char *newname
,
80 struct dentry
*dentry
= path
->dentry
;
83 if (!dentry
|| !path
->mnt
|| !newname
|| newname_len
<= 2048)
85 if (dentry
->d_op
&& dentry
->d_op
->d_dname
) {
86 /* For "socket:[\$]" and "pipe:[\$]". */
87 static const int offset
= 1536;
88 sp
= dentry
->d_op
->d_dname(dentry
, newname
+ offset
,
89 newname_len
- offset
);
91 /* Taken from d_namespace_path(). */
93 struct path ns_root
= { };
96 read_lock(¤t
->fs
->lock
);
97 root
= current
->fs
->root
;
99 read_unlock(¤t
->fs
->lock
);
100 spin_lock(&vfsmount_lock
);
101 if (root
.mnt
&& root
.mnt
->mnt_ns
)
102 ns_root
.mnt
= mntget(root
.mnt
->mnt_ns
->root
);
104 ns_root
.dentry
= dget(ns_root
.mnt
->mnt_root
);
105 spin_unlock(&vfsmount_lock
);
106 spin_lock(&dcache_lock
);
108 sp
= __d_path(path
, &tmp
, newname
, newname_len
);
109 spin_unlock(&dcache_lock
);
112 /* Prepend "/proc" prefix if using internal proc vfs mount. */
113 if (!IS_ERR(sp
) && (path
->mnt
->mnt_parent
== path
->mnt
) &&
114 (path
->mnt
->mnt_sb
->s_magic
== PROC_SUPER_MAGIC
)) {
117 memcpy(sp
, "/proc", 5);
119 sp
= ERR_PTR(-ENOMEM
);
125 error
= tomoyo_encode(newname
, sp
- newname
, sp
);
126 /* Append trailing '/' if dentry is a directory. */
127 if (!error
&& dentry
->d_inode
&& S_ISDIR(dentry
->d_inode
->i_mode
)
129 sp
= newname
+ strlen(newname
);
130 if (*(sp
- 1) != '/') {
131 if (sp
< newname
+ newname_len
- 4) {
140 printk(KERN_WARNING
"tomoyo_realpath: Pathname too long.\n");
145 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
147 * @path: Pointer to "struct path".
149 * Returns the realpath of the given @path on success, NULL otherwise.
151 * These functions use kzalloc(), so the caller must call kfree()
152 * if these functions didn't return NULL.
154 char *tomoyo_realpath_from_path(struct path
*path
)
156 char *buf
= kzalloc(sizeof(struct tomoyo_page_buffer
), GFP_KERNEL
);
158 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer
)
159 <= TOMOYO_MAX_PATHNAME_LEN
- 1);
162 if (tomoyo_realpath_from_path2(path
, buf
,
163 TOMOYO_MAX_PATHNAME_LEN
- 1) == 0)
170 * tomoyo_realpath - Get realpath of a pathname.
172 * @pathname: The pathname to solve.
174 * Returns the realpath of @pathname on success, NULL otherwise.
176 char *tomoyo_realpath(const char *pathname
)
180 if (pathname
&& kern_path(pathname
, LOOKUP_FOLLOW
, &path
) == 0) {
181 char *buf
= tomoyo_realpath_from_path(&path
);
189 * tomoyo_realpath_nofollow - Get realpath of a pathname.
191 * @pathname: The pathname to solve.
193 * Returns the realpath of @pathname on success, NULL otherwise.
195 char *tomoyo_realpath_nofollow(const char *pathname
)
199 if (pathname
&& kern_path(pathname
, 0, &path
) == 0) {
200 char *buf
= tomoyo_realpath_from_path(&path
);
207 /* Memory allocated for non-string data. */
208 static atomic_t tomoyo_policy_memory_size
;
209 /* Quota for holding policy. */
210 static unsigned int tomoyo_quota_for_policy
;
213 * tomoyo_memory_ok - Check memory quota.
215 * @ptr: Pointer to allocated memory.
217 * Returns true on success, false otherwise.
219 * Caller holds tomoyo_policy_lock.
220 * Memory pointed by @ptr will be zeroed on success.
222 bool tomoyo_memory_ok(void *ptr
)
224 int allocated_len
= ptr
? ksize(ptr
) : 0;
225 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
226 if (ptr
&& (!tomoyo_quota_for_policy
||
227 atomic_read(&tomoyo_policy_memory_size
)
228 <= tomoyo_quota_for_policy
)) {
229 memset(ptr
, 0, allocated_len
);
232 printk(KERN_WARNING
"ERROR: Out of memory "
233 "for tomoyo_alloc_element().\n");
234 if (!tomoyo_policy_loaded
)
235 panic("MAC Initialization failed.\n");
240 * tomoyo_memory_free - Free memory for elements.
242 * @ptr: Pointer to allocated memory.
244 void tomoyo_memory_free(void *ptr
)
246 atomic_sub(ksize(ptr
), &tomoyo_policy_memory_size
);
251 * tomoyo_name_list is used for holding string data used by TOMOYO.
252 * Since same string data is likely used for multiple times (e.g.
253 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
254 * "const struct tomoyo_path_info *".
256 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
257 /* Lock for protecting tomoyo_name_list . */
258 DEFINE_MUTEX(tomoyo_name_list_lock
);
261 * tomoyo_get_name - Allocate permanent memory for string data.
263 * @name: The string to store into the permernent memory.
265 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
267 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
269 struct tomoyo_name_entry
*ptr
;
273 struct list_head
*head
;
277 len
= strlen(name
) + 1;
278 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
279 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
280 mutex_lock(&tomoyo_name_list_lock
);
281 list_for_each_entry(ptr
, head
, list
) {
282 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
284 atomic_inc(&ptr
->users
);
287 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_KERNEL
);
288 allocated_len
= ptr
? ksize(ptr
) : 0;
289 if (!ptr
|| (tomoyo_quota_for_policy
&&
290 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
291 > tomoyo_quota_for_policy
)) {
293 printk(KERN_WARNING
"ERROR: Out of memory "
294 "for tomoyo_get_name().\n");
295 if (!tomoyo_policy_loaded
)
296 panic("MAC Initialization failed.\n");
300 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
301 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
302 memmove((char *) ptr
->entry
.name
, name
, len
);
303 atomic_set(&ptr
->users
, 1);
304 tomoyo_fill_path_info(&ptr
->entry
);
305 list_add_tail(&ptr
->list
, head
);
307 mutex_unlock(&tomoyo_name_list_lock
);
308 return ptr
? &ptr
->entry
: NULL
;
312 * tomoyo_realpath_init - Initialize realpath related code.
314 void __init
tomoyo_realpath_init(void)
318 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN
> PATH_MAX
);
319 for (i
= 0; i
< TOMOYO_MAX_HASH
; i
++)
320 INIT_LIST_HEAD(&tomoyo_name_list
[i
]);
321 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
322 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
324 * tomoyo_read_lock() is not needed because this function is
325 * called before the first "delete" request.
327 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
328 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
329 panic("Can't register tomoyo_kernel_domain");
333 * tomoyo_read_memory_counter - Check for memory usage in bytes.
335 * @head: Pointer to "struct tomoyo_io_buffer".
337 * Returns memory usage.
339 int tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
341 if (!head
->read_eof
) {
342 const unsigned int policy
343 = atomic_read(&tomoyo_policy_memory_size
);
346 memset(buffer
, 0, sizeof(buffer
));
347 if (tomoyo_quota_for_policy
)
348 snprintf(buffer
, sizeof(buffer
) - 1,
350 tomoyo_quota_for_policy
);
353 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
, buffer
);
354 tomoyo_io_printf(head
, "Total: %10u\n", policy
);
355 head
->read_eof
= true;
361 * tomoyo_write_memory_quota - Set memory quota.
363 * @head: Pointer to "struct tomoyo_io_buffer".
367 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
369 char *data
= head
->write_buf
;
372 if (sscanf(data
, "Policy: %u", &size
) == 1)
373 tomoyo_quota_for_policy
= size
;