.. | .. |
---|
7 | 7 | |
---|
8 | 8 | #include "common.h" |
---|
9 | 9 | #include <linux/magic.h> |
---|
| 10 | +#include <linux/proc_fs.h> |
---|
10 | 11 | |
---|
11 | 12 | /** |
---|
12 | 13 | * tomoyo_encode2 - Encode binary string to ascii string. |
---|
.. | .. |
---|
94 | 95 | const int buflen) |
---|
95 | 96 | { |
---|
96 | 97 | char *pos = ERR_PTR(-ENOMEM); |
---|
| 98 | + |
---|
97 | 99 | if (buflen >= 256) { |
---|
98 | 100 | /* go to whatever namespace root we are under */ |
---|
99 | 101 | pos = d_absolute_path(path, buffer, buflen - 1); |
---|
100 | 102 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
---|
101 | 103 | struct inode *inode = d_backing_inode(path->dentry); |
---|
| 104 | + |
---|
102 | 105 | if (inode && S_ISDIR(inode->i_mode)) { |
---|
103 | 106 | buffer[buflen - 2] = '/'; |
---|
104 | 107 | buffer[buflen - 1] = '\0'; |
---|
.. | .. |
---|
123 | 126 | const int buflen) |
---|
124 | 127 | { |
---|
125 | 128 | char *pos = ERR_PTR(-ENOMEM); |
---|
| 129 | + |
---|
126 | 130 | if (buflen >= 256) { |
---|
127 | 131 | pos = dentry_path_raw(dentry, buffer, buflen - 1); |
---|
128 | 132 | if (!IS_ERR(pos) && *pos == '/' && pos[1]) { |
---|
129 | 133 | struct inode *inode = d_backing_inode(dentry); |
---|
| 134 | + |
---|
130 | 135 | if (inode && S_ISDIR(inode->i_mode)) { |
---|
131 | 136 | buffer[buflen - 2] = '/'; |
---|
132 | 137 | buffer[buflen - 1] = '\0'; |
---|
.. | .. |
---|
150 | 155 | { |
---|
151 | 156 | struct super_block *sb = dentry->d_sb; |
---|
152 | 157 | char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen); |
---|
| 158 | + |
---|
153 | 159 | if (IS_ERR(pos)) |
---|
154 | 160 | return pos; |
---|
155 | 161 | /* Convert from $PID to self if $PID is current thread. */ |
---|
156 | 162 | if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') { |
---|
157 | 163 | char *ep; |
---|
158 | 164 | const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10); |
---|
| 165 | + struct pid_namespace *proc_pidns = proc_pid_ns(sb); |
---|
| 166 | + |
---|
159 | 167 | if (*ep == '/' && pid && pid == |
---|
160 | | - task_tgid_nr_ns(current, sb->s_fs_info)) { |
---|
| 168 | + task_tgid_nr_ns(current, proc_pidns)) { |
---|
161 | 169 | pos = ep - 5; |
---|
162 | 170 | if (pos < buffer) |
---|
163 | 171 | goto out; |
---|
.. | .. |
---|
170 | 178 | goto prepend_filesystem_name; |
---|
171 | 179 | { |
---|
172 | 180 | struct inode *inode = d_backing_inode(sb->s_root); |
---|
| 181 | + |
---|
173 | 182 | /* |
---|
174 | 183 | * Use filesystem name if filesystem does not support rename() |
---|
175 | 184 | * operation. |
---|
.. | .. |
---|
182 | 191 | char name[64]; |
---|
183 | 192 | int name_len; |
---|
184 | 193 | const dev_t dev = sb->s_dev; |
---|
| 194 | + |
---|
185 | 195 | name[sizeof(name) - 1] = '\0'; |
---|
186 | 196 | snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev), |
---|
187 | 197 | MINOR(dev)); |
---|
.. | .. |
---|
197 | 207 | { |
---|
198 | 208 | const char *name = sb->s_type->name; |
---|
199 | 209 | const int name_len = strlen(name); |
---|
| 210 | + |
---|
200 | 211 | pos -= name_len + 1; |
---|
201 | 212 | if (pos < buffer) |
---|
202 | 213 | goto out; |
---|
.. | .. |
---|
206 | 217 | return pos; |
---|
207 | 218 | out: |
---|
208 | 219 | return ERR_PTR(-ENOMEM); |
---|
209 | | -} |
---|
210 | | - |
---|
211 | | -/** |
---|
212 | | - * tomoyo_get_socket_name - Get the name of a socket. |
---|
213 | | - * |
---|
214 | | - * @path: Pointer to "struct path". |
---|
215 | | - * @buffer: Pointer to buffer to return value in. |
---|
216 | | - * @buflen: Sizeof @buffer. |
---|
217 | | - * |
---|
218 | | - * Returns the buffer. |
---|
219 | | - */ |
---|
220 | | -static char *tomoyo_get_socket_name(const struct path *path, char * const buffer, |
---|
221 | | - const int buflen) |
---|
222 | | -{ |
---|
223 | | - struct inode *inode = d_backing_inode(path->dentry); |
---|
224 | | - struct socket *sock = inode ? SOCKET_I(inode) : NULL; |
---|
225 | | - struct sock *sk = sock ? sock->sk : NULL; |
---|
226 | | - if (sk) { |
---|
227 | | - snprintf(buffer, buflen, "socket:[family=%u:type=%u:" |
---|
228 | | - "protocol=%u]", sk->sk_family, sk->sk_type, |
---|
229 | | - sk->sk_protocol); |
---|
230 | | - } else { |
---|
231 | | - snprintf(buffer, buflen, "socket:[unknown]"); |
---|
232 | | - } |
---|
233 | | - return buffer; |
---|
234 | 220 | } |
---|
235 | 221 | |
---|
236 | 222 | /** |
---|
.. | .. |
---|
255 | 241 | unsigned int buf_len = PAGE_SIZE / 2; |
---|
256 | 242 | struct dentry *dentry = path->dentry; |
---|
257 | 243 | struct super_block *sb; |
---|
| 244 | + |
---|
258 | 245 | if (!dentry) |
---|
259 | 246 | return NULL; |
---|
260 | 247 | sb = dentry->d_sb; |
---|
261 | 248 | while (1) { |
---|
262 | 249 | char *pos; |
---|
263 | 250 | struct inode *inode; |
---|
| 251 | + |
---|
264 | 252 | buf_len <<= 1; |
---|
265 | 253 | kfree(buf); |
---|
266 | 254 | buf = kmalloc(buf_len, GFP_NOFS); |
---|
.. | .. |
---|
268 | 256 | break; |
---|
269 | 257 | /* To make sure that pos is '\0' terminated. */ |
---|
270 | 258 | buf[buf_len - 1] = '\0'; |
---|
271 | | - /* Get better name for socket. */ |
---|
272 | | - if (sb->s_magic == SOCKFS_MAGIC) { |
---|
273 | | - pos = tomoyo_get_socket_name(path, buf, buf_len - 1); |
---|
274 | | - goto encode; |
---|
275 | | - } |
---|
276 | | - /* For "pipe:[\$]". */ |
---|
| 259 | + /* For "pipe:[\$]" and "socket:[\$]". */ |
---|
277 | 260 | if (dentry->d_op && dentry->d_op->d_dname) { |
---|
278 | 261 | pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); |
---|
279 | 262 | goto encode; |
---|
.. | .. |
---|
284 | 267 | * or dentry without vfsmount. |
---|
285 | 268 | */ |
---|
286 | 269 | if (!path->mnt || |
---|
287 | | - (!inode->i_op->rename)) |
---|
| 270 | + (!inode->i_op->rename && |
---|
| 271 | + !(sb->s_type->fs_flags & FS_REQUIRES_DEV))) |
---|
288 | 272 | pos = tomoyo_get_local_path(path->dentry, buf, |
---|
289 | 273 | buf_len - 1); |
---|
290 | 274 | /* Get absolute name for the rest. */ |
---|
.. | .. |
---|
323 | 307 | |
---|
324 | 308 | if (pathname && kern_path(pathname, 0, &path) == 0) { |
---|
325 | 309 | char *buf = tomoyo_realpath_from_path(&path); |
---|
| 310 | + |
---|
326 | 311 | path_put(&path); |
---|
327 | 312 | return buf; |
---|
328 | 313 | } |
---|