2 * security/tomoyo/realpath.c
4 * Pathname calculation functions for TOMOYO.
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
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>
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
)
29 const unsigned char c
= *(unsigned char *) str
++;
31 if (tomoyo_is_valid(c
)) {
52 *buffer
++ = (c
>> 6) + '0';
53 *buffer
++ = ((c
>> 3) & 7) + '0';
54 *buffer
++ = (c
& 7) + '0';
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
,
77 struct dentry
*dentry
= path
->dentry
;
80 if (!dentry
|| !path
->mnt
|| !newname
|| newname_len
<= 2048)
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
);
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
)) {
99 memcpy(sp
, "/proc", 5);
101 sp
= ERR_PTR(-ENOMEM
);
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
)
111 sp
= newname
+ strlen(newname
);
112 if (*(sp
- 1) != '/') {
113 if (sp
< newname
+ newname_len
- 4) {
122 tomoyo_warn_oom(__func__
);
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);
145 if (tomoyo_realpath_from_path2(path
, buf
,
146 TOMOYO_MAX_PATHNAME_LEN
- 1) == 0)
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
)
163 if (pathname
&& kern_path(pathname
, LOOKUP_FOLLOW
, &path
) == 0) {
164 char *buf
= tomoyo_realpath_from_path(&path
);
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
)
182 if (pathname
&& kern_path(pathname
, 0, &path
) == 0) {
183 char *buf
= tomoyo_realpath_from_path(&path
);