Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * linux/fs/readdir.c
4 : *
5 : * Copyright (C) 1995 Linus Torvalds
6 : */
7 :
8 : #include <linux/stddef.h>
9 : #include <linux/kernel.h>
10 : #include <linux/export.h>
11 : #include <linux/time.h>
12 : #include <linux/mm.h>
13 : #include <linux/errno.h>
14 : #include <linux/stat.h>
15 : #include <linux/file.h>
16 : #include <linux/fs.h>
17 : #include <linux/fsnotify.h>
18 : #include <linux/dirent.h>
19 : #include <linux/security.h>
20 : #include <linux/syscalls.h>
21 : #include <linux/unistd.h>
22 : #include <linux/compat.h>
23 : #include <linux/uaccess.h>
24 :
25 : #include <asm/unaligned.h>
26 :
27 : /*
28 : * Note the "unsafe_put_user() semantics: we goto a
29 : * label for errors.
30 : */
31 : #define unsafe_copy_dirent_name(_dst, _src, _len, label) do { \
32 : char __user *dst = (_dst); \
33 : const char *src = (_src); \
34 : size_t len = (_len); \
35 : unsafe_put_user(0, dst+len, label); \
36 : unsafe_copy_to_user(dst, src, len, label); \
37 : } while (0)
38 :
39 :
40 113012147 : int iterate_dir(struct file *file, struct dir_context *ctx)
41 : {
42 113012147 : struct inode *inode = file_inode(file);
43 113012147 : bool shared = false;
44 113012147 : int res = -ENOTDIR;
45 113012147 : if (file->f_op->iterate_shared)
46 : shared = true;
47 623334 : else if (!file->f_op->iterate)
48 0 : goto out;
49 :
50 113012147 : res = security_file_permission(file, MAY_READ);
51 113012147 : if (res)
52 : goto out;
53 :
54 113012147 : if (shared)
55 112388813 : res = down_read_killable(&inode->i_rwsem);
56 : else
57 623334 : res = down_write_killable(&inode->i_rwsem);
58 112919592 : if (res)
59 5 : goto out;
60 :
61 112919587 : res = -ENOENT;
62 112919587 : if (!IS_DEADDIR(inode)) {
63 112941778 : ctx->pos = file->f_pos;
64 112941778 : if (shared)
65 112318442 : res = file->f_op->iterate_shared(file, ctx);
66 : else
67 623336 : res = file->f_op->iterate(file, ctx);
68 113121746 : file->f_pos = ctx->pos;
69 113121746 : fsnotify_access(file);
70 113102120 : file_accessed(file);
71 : }
72 113099832 : if (shared)
73 112476496 : inode_unlock_shared(inode);
74 : else
75 623336 : inode_unlock(inode);
76 113124847 : out:
77 113124847 : return res;
78 : }
79 : EXPORT_SYMBOL(iterate_dir);
80 :
81 : /*
82 : * POSIX says that a dirent name cannot contain NULL or a '/'.
83 : *
84 : * It's not 100% clear what we should really do in this case.
85 : * The filesystem is clearly corrupted, but returning a hard
86 : * error means that you now don't see any of the other names
87 : * either, so that isn't a perfect alternative.
88 : *
89 : * And if you return an error, what error do you use? Several
90 : * filesystems seem to have decided on EUCLEAN being the error
91 : * code for EFSCORRUPTED, and that may be the error to use. Or
92 : * just EIO, which is perhaps more obvious to users.
93 : *
94 : * In order to see the other file names in the directory, the
95 : * caller might want to make this a "soft" error: skip the
96 : * entry, and return the error at the end instead.
97 : *
98 : * Note that this should likely do a "memchr(name, 0, len)"
99 : * check too, since that would be filesystem corruption as
100 : * well. However, that case can't actually confuse user space,
101 : * which has to do a strlen() on the name anyway to find the
102 : * filename length, and the above "soft error" worry means
103 : * that it's probably better left alone until we have that
104 : * issue clarified.
105 : *
106 : * Note the PATH_MAX check - it's arbitrary but the real
107 : * kernel limit on a possible path component, not NAME_MAX,
108 : * which is the technical standard limit.
109 : */
110 26553251144 : static int verify_dirent_name(const char *name, int len)
111 : {
112 26553251144 : if (len <= 0 || len >= PATH_MAX)
113 : return -EIO;
114 53106502288 : if (memchr(name, '/', len))
115 0 : return -EIO;
116 : return 0;
117 : }
118 :
119 : /*
120 : * Traditional linux readdir() handling..
121 : *
122 : * "count=1" is a special case, meaning that the buffer is one
123 : * dirent-structure in size and that the code can't handle more
124 : * anyway. Thus the special "fillonedir()" function for that
125 : * case (the low-level handlers don't need to care about this).
126 : */
127 :
128 : #ifdef __ARCH_WANT_OLD_READDIR
129 :
130 : struct old_linux_dirent {
131 : unsigned long d_ino;
132 : unsigned long d_offset;
133 : unsigned short d_namlen;
134 : char d_name[];
135 : };
136 :
137 : struct readdir_callback {
138 : struct dir_context ctx;
139 : struct old_linux_dirent __user * dirent;
140 : int result;
141 : };
142 :
143 0 : static bool fillonedir(struct dir_context *ctx, const char *name, int namlen,
144 : loff_t offset, u64 ino, unsigned int d_type)
145 : {
146 0 : struct readdir_callback *buf =
147 0 : container_of(ctx, struct readdir_callback, ctx);
148 0 : struct old_linux_dirent __user * dirent;
149 0 : unsigned long d_ino;
150 :
151 0 : if (buf->result)
152 : return false;
153 0 : buf->result = verify_dirent_name(name, namlen);
154 0 : if (buf->result)
155 : return false;
156 0 : d_ino = ino;
157 0 : if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
158 : buf->result = -EOVERFLOW;
159 : return false;
160 : }
161 0 : buf->result++;
162 0 : dirent = buf->dirent;
163 0 : if (!user_write_access_begin(dirent,
164 : (unsigned long)(dirent->d_name + namlen + 1) -
165 : (unsigned long)dirent))
166 0 : goto efault;
167 0 : unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
168 0 : unsafe_put_user(offset, &dirent->d_offset, efault_end);
169 0 : unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
170 0 : unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
171 0 : user_write_access_end();
172 0 : return true;
173 0 : efault_end:
174 0 : user_write_access_end();
175 0 : efault:
176 0 : buf->result = -EFAULT;
177 0 : return false;
178 : }
179 :
180 0 : SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
181 : struct old_linux_dirent __user *, dirent, unsigned int, count)
182 : {
183 0 : int error;
184 0 : struct fd f = fdget_pos(fd);
185 0 : struct readdir_callback buf = {
186 : .ctx.actor = fillonedir,
187 : .dirent = dirent
188 : };
189 :
190 0 : if (!f.file)
191 : return -EBADF;
192 :
193 0 : error = iterate_dir(f.file, &buf.ctx);
194 0 : if (buf.result)
195 0 : error = buf.result;
196 :
197 0 : fdput_pos(f);
198 0 : return error;
199 : }
200 :
201 : #endif /* __ARCH_WANT_OLD_READDIR */
202 :
203 : /*
204 : * New, all-improved, singing, dancing, iBCS2-compliant getdents()
205 : * interface.
206 : */
207 : struct linux_dirent {
208 : unsigned long d_ino;
209 : unsigned long d_off;
210 : unsigned short d_reclen;
211 : char d_name[];
212 : };
213 :
214 : struct getdents_callback {
215 : struct dir_context ctx;
216 : struct linux_dirent __user * current_dir;
217 : int prev_reclen;
218 : int count;
219 : int error;
220 : };
221 :
222 0 : static bool filldir(struct dir_context *ctx, const char *name, int namlen,
223 : loff_t offset, u64 ino, unsigned int d_type)
224 : {
225 0 : struct linux_dirent __user *dirent, *prev;
226 0 : struct getdents_callback *buf =
227 0 : container_of(ctx, struct getdents_callback, ctx);
228 0 : unsigned long d_ino;
229 0 : int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2,
230 : sizeof(long));
231 0 : int prev_reclen;
232 :
233 0 : buf->error = verify_dirent_name(name, namlen);
234 0 : if (unlikely(buf->error))
235 : return false;
236 0 : buf->error = -EINVAL; /* only used if we fail.. */
237 0 : if (reclen > buf->count)
238 : return false;
239 0 : d_ino = ino;
240 0 : if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
241 : buf->error = -EOVERFLOW;
242 : return false;
243 : }
244 0 : prev_reclen = buf->prev_reclen;
245 0 : if (prev_reclen && signal_pending(current))
246 : return false;
247 0 : dirent = buf->current_dir;
248 0 : prev = (void __user *) dirent - prev_reclen;
249 0 : if (!user_write_access_begin(prev, reclen + prev_reclen))
250 0 : goto efault;
251 :
252 : /* This might be 'dirent->d_off', but if so it will get overwritten */
253 0 : unsafe_put_user(offset, &prev->d_off, efault_end);
254 0 : unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
255 0 : unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
256 0 : unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
257 0 : unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
258 0 : user_write_access_end();
259 :
260 0 : buf->current_dir = (void __user *)dirent + reclen;
261 0 : buf->prev_reclen = reclen;
262 0 : buf->count -= reclen;
263 0 : return true;
264 0 : efault_end:
265 0 : user_write_access_end();
266 0 : efault:
267 0 : buf->error = -EFAULT;
268 0 : return false;
269 : }
270 :
271 0 : SYSCALL_DEFINE3(getdents, unsigned int, fd,
272 : struct linux_dirent __user *, dirent, unsigned int, count)
273 : {
274 0 : struct fd f;
275 0 : struct getdents_callback buf = {
276 : .ctx.actor = filldir,
277 : .count = count,
278 : .current_dir = dirent
279 : };
280 0 : int error;
281 :
282 0 : f = fdget_pos(fd);
283 0 : if (!f.file)
284 : return -EBADF;
285 :
286 0 : error = iterate_dir(f.file, &buf.ctx);
287 0 : if (error >= 0)
288 0 : error = buf.error;
289 0 : if (buf.prev_reclen) {
290 0 : struct linux_dirent __user * lastdirent;
291 0 : lastdirent = (void __user *)buf.current_dir - buf.prev_reclen;
292 :
293 0 : if (put_user(buf.ctx.pos, &lastdirent->d_off))
294 : error = -EFAULT;
295 : else
296 0 : error = count - buf.count;
297 : }
298 0 : fdput_pos(f);
299 0 : return error;
300 : }
301 :
302 : struct getdents_callback64 {
303 : struct dir_context ctx;
304 : struct linux_dirent64 __user * current_dir;
305 : int prev_reclen;
306 : int count;
307 : int error;
308 : };
309 :
310 26912936313 : static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
311 : loff_t offset, u64 ino, unsigned int d_type)
312 : {
313 26912936313 : struct linux_dirent64 __user *dirent, *prev;
314 26912936313 : struct getdents_callback64 *buf =
315 26912936313 : container_of(ctx, struct getdents_callback64, ctx);
316 26912936313 : int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1,
317 : sizeof(u64));
318 26912936313 : int prev_reclen;
319 :
320 26912936313 : buf->error = verify_dirent_name(name, namlen);
321 26350672739 : if (unlikely(buf->error))
322 : return false;
323 26350672739 : buf->error = -EINVAL; /* only used if we fail.. */
324 26350672739 : if (reclen > buf->count)
325 : return false;
326 26331226674 : prev_reclen = buf->prev_reclen;
327 26331226674 : if (prev_reclen && signal_pending(current))
328 : return false;
329 25744691902 : dirent = buf->current_dir;
330 25744691902 : prev = (void __user *)dirent - prev_reclen;
331 25744691902 : if (!user_write_access_begin(prev, reclen + prev_reclen))
332 0 : goto efault;
333 :
334 : /* This might be 'dirent->d_off', but if so it will get overwritten */
335 26736036758 : unsafe_put_user(offset, &prev->d_off, efault_end);
336 26559755853 : unsafe_put_user(ino, &dirent->d_ino, efault_end);
337 26365655256 : unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
338 26646968182 : unsafe_put_user(d_type, &dirent->d_type, efault_end);
339 66348434591 : unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
340 25702375799 : user_write_access_end();
341 :
342 26661015299 : buf->prev_reclen = reclen;
343 26661015299 : buf->current_dir = (void __user *)dirent + reclen;
344 26661015299 : buf->count -= reclen;
345 26661015299 : return true;
346 :
347 0 : efault_end:
348 0 : user_write_access_end();
349 0 : efault:
350 0 : buf->error = -EFAULT;
351 0 : return false;
352 : }
353 :
354 219395054 : SYSCALL_DEFINE3(getdents64, unsigned int, fd,
355 : struct linux_dirent64 __user *, dirent, unsigned int, count)
356 : {
357 109648696 : struct fd f;
358 109648696 : struct getdents_callback64 buf = {
359 : .ctx.actor = filldir64,
360 : .count = count,
361 : .current_dir = dirent
362 : };
363 109648696 : int error;
364 :
365 109648696 : f = fdget_pos(fd);
366 109776152 : if (!f.file)
367 : return -EBADF;
368 :
369 109776152 : error = iterate_dir(f.file, &buf.ctx);
370 109832105 : if (error >= 0)
371 109829439 : error = buf.error;
372 109832105 : if (buf.prev_reclen) {
373 64424845 : struct linux_dirent64 __user * lastdirent;
374 64424845 : typeof(lastdirent->d_off) d_off = buf.ctx.pos;
375 :
376 64424845 : lastdirent = (void __user *) buf.current_dir - buf.prev_reclen;
377 64424845 : if (put_user(d_off, &lastdirent->d_off))
378 : error = -EFAULT;
379 : else
380 64416786 : error = count - buf.count;
381 : }
382 109824046 : fdput_pos(f);
383 109854829 : return error;
384 : }
385 :
386 : #ifdef CONFIG_COMPAT
387 : struct compat_old_linux_dirent {
388 : compat_ulong_t d_ino;
389 : compat_ulong_t d_offset;
390 : unsigned short d_namlen;
391 : char d_name[];
392 : };
393 :
394 : struct compat_readdir_callback {
395 : struct dir_context ctx;
396 : struct compat_old_linux_dirent __user *dirent;
397 : int result;
398 : };
399 :
400 0 : static bool compat_fillonedir(struct dir_context *ctx, const char *name,
401 : int namlen, loff_t offset, u64 ino,
402 : unsigned int d_type)
403 : {
404 0 : struct compat_readdir_callback *buf =
405 0 : container_of(ctx, struct compat_readdir_callback, ctx);
406 0 : struct compat_old_linux_dirent __user *dirent;
407 0 : compat_ulong_t d_ino;
408 :
409 0 : if (buf->result)
410 : return false;
411 0 : buf->result = verify_dirent_name(name, namlen);
412 0 : if (buf->result)
413 : return false;
414 0 : d_ino = ino;
415 0 : if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
416 0 : buf->result = -EOVERFLOW;
417 0 : return false;
418 : }
419 0 : buf->result++;
420 0 : dirent = buf->dirent;
421 0 : if (!user_write_access_begin(dirent,
422 : (unsigned long)(dirent->d_name + namlen + 1) -
423 : (unsigned long)dirent))
424 0 : goto efault;
425 0 : unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
426 0 : unsafe_put_user(offset, &dirent->d_offset, efault_end);
427 0 : unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
428 0 : unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
429 0 : user_write_access_end();
430 0 : return true;
431 0 : efault_end:
432 0 : user_write_access_end();
433 0 : efault:
434 0 : buf->result = -EFAULT;
435 0 : return false;
436 : }
437 :
438 0 : COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
439 : struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
440 : {
441 0 : int error;
442 0 : struct fd f = fdget_pos(fd);
443 0 : struct compat_readdir_callback buf = {
444 : .ctx.actor = compat_fillonedir,
445 : .dirent = dirent
446 : };
447 :
448 0 : if (!f.file)
449 : return -EBADF;
450 :
451 0 : error = iterate_dir(f.file, &buf.ctx);
452 0 : if (buf.result)
453 0 : error = buf.result;
454 :
455 0 : fdput_pos(f);
456 0 : return error;
457 : }
458 :
459 : struct compat_linux_dirent {
460 : compat_ulong_t d_ino;
461 : compat_ulong_t d_off;
462 : unsigned short d_reclen;
463 : char d_name[];
464 : };
465 :
466 : struct compat_getdents_callback {
467 : struct dir_context ctx;
468 : struct compat_linux_dirent __user *current_dir;
469 : int prev_reclen;
470 : int count;
471 : int error;
472 : };
473 :
474 0 : static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen,
475 : loff_t offset, u64 ino, unsigned int d_type)
476 : {
477 0 : struct compat_linux_dirent __user *dirent, *prev;
478 0 : struct compat_getdents_callback *buf =
479 0 : container_of(ctx, struct compat_getdents_callback, ctx);
480 0 : compat_ulong_t d_ino;
481 0 : int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) +
482 : namlen + 2, sizeof(compat_long_t));
483 0 : int prev_reclen;
484 :
485 0 : buf->error = verify_dirent_name(name, namlen);
486 0 : if (unlikely(buf->error))
487 : return false;
488 0 : buf->error = -EINVAL; /* only used if we fail.. */
489 0 : if (reclen > buf->count)
490 : return false;
491 0 : d_ino = ino;
492 0 : if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
493 0 : buf->error = -EOVERFLOW;
494 0 : return false;
495 : }
496 0 : prev_reclen = buf->prev_reclen;
497 0 : if (prev_reclen && signal_pending(current))
498 : return false;
499 0 : dirent = buf->current_dir;
500 0 : prev = (void __user *) dirent - prev_reclen;
501 0 : if (!user_write_access_begin(prev, reclen + prev_reclen))
502 0 : goto efault;
503 :
504 0 : unsafe_put_user(offset, &prev->d_off, efault_end);
505 0 : unsafe_put_user(d_ino, &dirent->d_ino, efault_end);
506 0 : unsafe_put_user(reclen, &dirent->d_reclen, efault_end);
507 0 : unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end);
508 0 : unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
509 0 : user_write_access_end();
510 :
511 0 : buf->prev_reclen = reclen;
512 0 : buf->current_dir = (void __user *)dirent + reclen;
513 0 : buf->count -= reclen;
514 0 : return true;
515 0 : efault_end:
516 0 : user_write_access_end();
517 0 : efault:
518 0 : buf->error = -EFAULT;
519 0 : return false;
520 : }
521 :
522 0 : COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
523 : struct compat_linux_dirent __user *, dirent, unsigned int, count)
524 : {
525 0 : struct fd f;
526 0 : struct compat_getdents_callback buf = {
527 : .ctx.actor = compat_filldir,
528 : .current_dir = dirent,
529 : .count = count
530 : };
531 0 : int error;
532 :
533 0 : f = fdget_pos(fd);
534 0 : if (!f.file)
535 : return -EBADF;
536 :
537 0 : error = iterate_dir(f.file, &buf.ctx);
538 0 : if (error >= 0)
539 0 : error = buf.error;
540 0 : if (buf.prev_reclen) {
541 0 : struct compat_linux_dirent __user * lastdirent;
542 0 : lastdirent = (void __user *)buf.current_dir - buf.prev_reclen;
543 :
544 0 : if (put_user(buf.ctx.pos, &lastdirent->d_off))
545 : error = -EFAULT;
546 : else
547 0 : error = count - buf.count;
548 : }
549 0 : fdput_pos(f);
550 0 : return error;
551 : }
552 : #endif
|