readdir.c 14 KB

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