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 struct path ns_root
= {.mnt
= NULL
, .dentry
= NULL
};
93 spin_lock(&dcache_lock
);
94 /* go to whatever namespace root we are under */
95 sp
= __d_path(path
, &ns_root
, newname
, newname_len
);
96 spin_unlock(&dcache_lock
);
97 /* Prepend "/proc" prefix if using internal proc vfs mount. */
98 if (!IS_ERR(sp
) && (path
->mnt
->mnt_flags
& MNT_INTERNAL
) &&
99 (path
->mnt
->mnt_sb
->s_magic
== PROC_SUPER_MAGIC
)) {
102 memcpy(sp
, "/proc", 5);
104 sp
= ERR_PTR(-ENOMEM
);
110 error
= tomoyo_encode(newname
, sp
- newname
, sp
);
111 /* Append trailing '/' if dentry is a directory. */
112 if (!error
&& dentry
->d_inode
&& S_ISDIR(dentry
->d_inode
->i_mode
)
114 sp
= newname
+ strlen(newname
);
115 if (*(sp
- 1) != '/') {
116 if (sp
< newname
+ newname_len
- 4) {
125 printk(KERN_WARNING
"tomoyo_realpath: Pathname too long.\n");
130 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
132 * @path: Pointer to "struct path".
134 * Returns the realpath of the given @path on success, NULL otherwise.
136 * These functions use kzalloc(), so the caller must call kfree()
137 * if these functions didn't return NULL.
139 char *tomoyo_realpath_from_path(struct path
*path
)
141 char *buf
= kzalloc(sizeof(struct tomoyo_page_buffer
), GFP_KERNEL
);
143 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer
)
144 <= TOMOYO_MAX_PATHNAME_LEN
- 1);
147 if (tomoyo_realpath_from_path2(path
, buf
,
148 TOMOYO_MAX_PATHNAME_LEN
- 1) == 0)
155 * tomoyo_realpath - Get realpath of a pathname.
157 * @pathname: The pathname to solve.
159 * Returns the realpath of @pathname on success, NULL otherwise.
161 char *tomoyo_realpath(const char *pathname
)
165 if (pathname
&& kern_path(pathname
, LOOKUP_FOLLOW
, &path
) == 0) {
166 char *buf
= tomoyo_realpath_from_path(&path
);
174 * tomoyo_realpath_nofollow - Get realpath of a pathname.
176 * @pathname: The pathname to solve.
178 * Returns the realpath of @pathname on success, NULL otherwise.
180 char *tomoyo_realpath_nofollow(const char *pathname
)
184 if (pathname
&& kern_path(pathname
, 0, &path
) == 0) {
185 char *buf
= tomoyo_realpath_from_path(&path
);
192 /* Memory allocated for non-string data. */
193 static atomic_t tomoyo_policy_memory_size
;
194 /* Quota for holding policy. */
195 static unsigned int tomoyo_quota_for_policy
;
198 * tomoyo_memory_ok - Check memory quota.
200 * @ptr: Pointer to allocated memory.
202 * Returns true on success, false otherwise.
204 * Caller holds tomoyo_policy_lock.
205 * Memory pointed by @ptr will be zeroed on success.
207 bool tomoyo_memory_ok(void *ptr
)
209 int allocated_len
= ptr
? ksize(ptr
) : 0;
210 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
211 if (ptr
&& (!tomoyo_quota_for_policy
||
212 atomic_read(&tomoyo_policy_memory_size
)
213 <= tomoyo_quota_for_policy
)) {
214 memset(ptr
, 0, allocated_len
);
217 printk(KERN_WARNING
"ERROR: Out of memory "
218 "for tomoyo_alloc_element().\n");
219 if (!tomoyo_policy_loaded
)
220 panic("MAC Initialization failed.\n");
225 * tomoyo_memory_free - Free memory for elements.
227 * @ptr: Pointer to allocated memory.
229 void tomoyo_memory_free(void *ptr
)
231 atomic_sub(ksize(ptr
), &tomoyo_policy_memory_size
);
236 * tomoyo_name_list is used for holding string data used by TOMOYO.
237 * Since same string data is likely used for multiple times (e.g.
238 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
239 * "const struct tomoyo_path_info *".
241 struct list_head tomoyo_name_list
[TOMOYO_MAX_HASH
];
242 /* Lock for protecting tomoyo_name_list . */
243 DEFINE_MUTEX(tomoyo_name_list_lock
);
246 * tomoyo_get_name - Allocate permanent memory for string data.
248 * @name: The string to store into the permernent memory.
250 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
252 const struct tomoyo_path_info
*tomoyo_get_name(const char *name
)
254 struct tomoyo_name_entry
*ptr
;
258 struct list_head
*head
;
262 len
= strlen(name
) + 1;
263 hash
= full_name_hash((const unsigned char *) name
, len
- 1);
264 head
= &tomoyo_name_list
[hash_long(hash
, TOMOYO_HASH_BITS
)];
265 mutex_lock(&tomoyo_name_list_lock
);
266 list_for_each_entry(ptr
, head
, list
) {
267 if (hash
!= ptr
->entry
.hash
|| strcmp(name
, ptr
->entry
.name
))
269 atomic_inc(&ptr
->users
);
272 ptr
= kzalloc(sizeof(*ptr
) + len
, GFP_KERNEL
);
273 allocated_len
= ptr
? ksize(ptr
) : 0;
274 if (!ptr
|| (tomoyo_quota_for_policy
&&
275 atomic_read(&tomoyo_policy_memory_size
) + allocated_len
276 > tomoyo_quota_for_policy
)) {
278 printk(KERN_WARNING
"ERROR: Out of memory "
279 "for tomoyo_get_name().\n");
280 if (!tomoyo_policy_loaded
)
281 panic("MAC Initialization failed.\n");
285 atomic_add(allocated_len
, &tomoyo_policy_memory_size
);
286 ptr
->entry
.name
= ((char *) ptr
) + sizeof(*ptr
);
287 memmove((char *) ptr
->entry
.name
, name
, len
);
288 atomic_set(&ptr
->users
, 1);
289 tomoyo_fill_path_info(&ptr
->entry
);
290 list_add_tail(&ptr
->list
, head
);
292 mutex_unlock(&tomoyo_name_list_lock
);
293 return ptr
? &ptr
->entry
: NULL
;
297 * tomoyo_realpath_init - Initialize realpath related code.
299 void __init
tomoyo_realpath_init(void)
303 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN
> PATH_MAX
);
304 for (i
= 0; i
< TOMOYO_MAX_HASH
; i
++)
305 INIT_LIST_HEAD(&tomoyo_name_list
[i
]);
306 INIT_LIST_HEAD(&tomoyo_kernel_domain
.acl_info_list
);
307 tomoyo_kernel_domain
.domainname
= tomoyo_get_name(TOMOYO_ROOT_NAME
);
309 * tomoyo_read_lock() is not needed because this function is
310 * called before the first "delete" request.
312 list_add_tail_rcu(&tomoyo_kernel_domain
.list
, &tomoyo_domain_list
);
313 if (tomoyo_find_domain(TOMOYO_ROOT_NAME
) != &tomoyo_kernel_domain
)
314 panic("Can't register tomoyo_kernel_domain");
318 * tomoyo_read_memory_counter - Check for memory usage in bytes.
320 * @head: Pointer to "struct tomoyo_io_buffer".
322 * Returns memory usage.
324 int tomoyo_read_memory_counter(struct tomoyo_io_buffer
*head
)
326 if (!head
->read_eof
) {
327 const unsigned int policy
328 = atomic_read(&tomoyo_policy_memory_size
);
331 memset(buffer
, 0, sizeof(buffer
));
332 if (tomoyo_quota_for_policy
)
333 snprintf(buffer
, sizeof(buffer
) - 1,
335 tomoyo_quota_for_policy
);
338 tomoyo_io_printf(head
, "Policy: %10u%s\n", policy
, buffer
);
339 tomoyo_io_printf(head
, "Total: %10u\n", policy
);
340 head
->read_eof
= true;
346 * tomoyo_write_memory_quota - Set memory quota.
348 * @head: Pointer to "struct tomoyo_io_buffer".
352 int tomoyo_write_memory_quota(struct tomoyo_io_buffer
*head
)
354 char *data
= head
->write_buf
;
357 if (sscanf(data
, "Policy: %u", &size
) == 1)
358 tomoyo_quota_for_policy
= size
;