TOMOYO: Split files into some pieces.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / security / tomoyo / realpath.c
blob1fd685a94ad1243c0c162df511cb5d61e010e789
1 /*
2 * security/tomoyo/realpath.c
4 * Pathname calculation functions for TOMOYO.
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */
9 #include <linux/types.h>
10 #include <linux/mount.h>
11 #include <linux/mnt_namespace.h>
12 #include <linux/fs_struct.h>
13 #include <linux/magic.h>
14 #include <linux/slab.h>
15 #include "common.h"
17 /**
18 * tomoyo_encode: Convert binary string to ascii string.
20 * @buffer: Buffer for ASCII string.
21 * @buflen: Size of @buffer.
22 * @str: Binary string.
24 * Returns 0 on success, -ENOMEM otherwise.
26 int tomoyo_encode(char *buffer, int buflen, const char *str)
28 while (1) {
29 const unsigned char c = *(unsigned char *) str++;
31 if (tomoyo_is_valid(c)) {
32 if (--buflen <= 0)
33 break;
34 *buffer++ = (char) c;
35 if (c != '\\')
36 continue;
37 if (--buflen <= 0)
38 break;
39 *buffer++ = (char) c;
40 continue;
42 if (!c) {
43 if (--buflen <= 0)
44 break;
45 *buffer = '\0';
46 return 0;
48 buflen -= 4;
49 if (buflen <= 0)
50 break;
51 *buffer++ = '\\';
52 *buffer++ = (c >> 6) + '0';
53 *buffer++ = ((c >> 3) & 7) + '0';
54 *buffer++ = (c & 7) + '0';
56 return -ENOMEM;
59 /**
60 * tomoyo_realpath_from_path2 - Returns realpath(3) of the given dentry but ignores chroot'ed root.
62 * @path: Pointer to "struct path".
63 * @newname: Pointer to buffer to return value in.
64 * @newname_len: Size of @newname.
66 * Returns 0 on success, negative value otherwise.
68 * If dentry is a directory, trailing '/' is appended.
69 * Characters out of 0x20 < c < 0x7F range are converted to
70 * \ooo style octal string.
71 * Character \ is converted to \\ string.
73 int tomoyo_realpath_from_path2(struct path *path, char *newname,
74 int newname_len)
76 int error = -ENOMEM;
77 struct dentry *dentry = path->dentry;
78 char *sp;
80 if (!dentry || !path->mnt || !newname || newname_len <= 2048)
81 return -EINVAL;
82 if (dentry->d_op && dentry->d_op->d_dname) {
83 /* For "socket:[\$]" and "pipe:[\$]". */
84 static const int offset = 1536;
85 sp = dentry->d_op->d_dname(dentry, newname + offset,
86 newname_len - offset);
87 } else {
88 struct path ns_root = {.mnt = NULL, .dentry = NULL};
90 spin_lock(&dcache_lock);
91 /* go to whatever namespace root we are under */
92 sp = __d_path(path, &ns_root, newname, newname_len);
93 spin_unlock(&dcache_lock);
94 /* Prepend "/proc" prefix if using internal proc vfs mount. */
95 if (!IS_ERR(sp) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
96 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
97 sp -= 5;
98 if (sp >= newname)
99 memcpy(sp, "/proc", 5);
100 else
101 sp = ERR_PTR(-ENOMEM);
104 if (IS_ERR(sp))
105 error = PTR_ERR(sp);
106 else
107 error = tomoyo_encode(newname, sp - newname, sp);
108 /* Append trailing '/' if dentry is a directory. */
109 if (!error && dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)
110 && *newname) {
111 sp = newname + strlen(newname);
112 if (*(sp - 1) != '/') {
113 if (sp < newname + newname_len - 4) {
114 *sp++ = '/';
115 *sp = '\0';
116 } else {
117 error = -ENOMEM;
121 if (error)
122 tomoyo_warn_oom(__func__);
123 return error;
127 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
129 * @path: Pointer to "struct path".
131 * Returns the realpath of the given @path on success, NULL otherwise.
133 * These functions use kzalloc(), so the caller must call kfree()
134 * if these functions didn't return NULL.
136 char *tomoyo_realpath_from_path(struct path *path)
138 char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_NOFS);
140 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX);
141 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer)
142 <= TOMOYO_MAX_PATHNAME_LEN - 1);
143 if (!buf)
144 return NULL;
145 if (tomoyo_realpath_from_path2(path, buf,
146 TOMOYO_MAX_PATHNAME_LEN - 1) == 0)
147 return buf;
148 kfree(buf);
149 return NULL;
153 * tomoyo_realpath - Get realpath of a pathname.
155 * @pathname: The pathname to solve.
157 * Returns the realpath of @pathname on success, NULL otherwise.
159 char *tomoyo_realpath(const char *pathname)
161 struct path path;
163 if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) {
164 char *buf = tomoyo_realpath_from_path(&path);
165 path_put(&path);
166 return buf;
168 return NULL;
172 * tomoyo_realpath_nofollow - Get realpath of a pathname.
174 * @pathname: The pathname to solve.
176 * Returns the realpath of @pathname on success, NULL otherwise.
178 char *tomoyo_realpath_nofollow(const char *pathname)
180 struct path path;
182 if (pathname && kern_path(pathname, 0, &path) == 0) {
183 char *buf = tomoyo_realpath_from_path(&path);
184 path_put(&path);
185 return buf;
187 return NULL;