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