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 int iterate_dir(struct file *file, struct dir_context *ctx) 41 { 42 struct inode *inode = file_inode(file); 43 bool shared = false; 44 int res = -ENOTDIR; 45 if (file->f_op->iterate_shared) 46 shared = true; 47 else if (!file->f_op->iterate) 48 goto out; 49 50 res = security_file_permission(file, MAY_READ); 51 if (res) 52 goto out; 53 54 if (shared) 55 res = down_read_killable(&inode->i_rwsem); 56 else 57 res = down_write_killable(&inode->i_rwsem); 58 if (res) 59 goto out; 60 61 res = -ENOENT; 62 if (!IS_DEADDIR(inode)) { 63 ctx->pos = file->f_pos; 64 if (shared) 65 res = file->f_op->iterate_shared(file, ctx); 66 else 67 res = file->f_op->iterate(file, ctx); 68 file->f_pos = ctx->pos; 69 fsnotify_access(file); 70 file_accessed(file); 71 } 72 if (shared) 73 inode_unlock_shared(inode); 74 else 75 inode_unlock(inode); 76 out: 77 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 static int verify_dirent_name(const char *name, int len) 111 { 112 if (len <= 0 || len >= PATH_MAX) 113 return -EIO; 114 if (memchr(name, '/', len)) 115 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 static bool fillonedir(struct dir_context *ctx, const char *name, int namlen, 144 loff_t offset, u64 ino, unsigned int d_type) 145 { 146 struct readdir_callback *buf = 147 container_of(ctx, struct readdir_callback, ctx); 148 struct old_linux_dirent __user * dirent; 149 unsigned long d_ino; 150 151 if (buf->result) 152 return false; 153 buf->result = verify_dirent_name(name, namlen); 154 if (buf->result) 155 return false; 156 d_ino = ino; 157 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 158 buf->result = -EOVERFLOW; 159 return false; 160 } 161 buf->result++; 162 dirent = buf->dirent; 163 if (!user_write_access_begin(dirent, 164 (unsigned long)(dirent->d_name + namlen + 1) - 165 (unsigned long)dirent)) 166 goto efault; 167 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 168 unsafe_put_user(offset, &dirent->d_offset, efault_end); 169 unsafe_put_user(namlen, &dirent->d_namlen, efault_end); 170 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 171 user_write_access_end(); 172 return true; 173 efault_end: 174 user_write_access_end(); 175 efault: 176 buf->result = -EFAULT; 177 return false; 178 } 179 180 SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 181 struct old_linux_dirent __user *, dirent, unsigned int, count) 182 { 183 int error; 184 struct fd f = fdget_pos(fd); 185 struct readdir_callback buf = { 186 .ctx.actor = fillonedir, 187 .dirent = dirent 188 }; 189 190 if (!f.file) 191 return -EBADF; 192 193 error = iterate_dir(f.file, &buf.ctx); 194 if (buf.result) 195 error = buf.result; 196 197 fdput_pos(f); 198 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 static bool filldir(struct dir_context *ctx, const char *name, int namlen, 223 loff_t offset, u64 ino, unsigned int d_type) 224 { 225 struct linux_dirent __user *dirent, *prev; 226 struct getdents_callback *buf = 227 container_of(ctx, struct getdents_callback, ctx); 228 unsigned long d_ino; 229 int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2, 230 sizeof(long)); 231 int prev_reclen; 232 233 buf->error = verify_dirent_name(name, namlen); 234 if (unlikely(buf->error)) 235 return false; 236 buf->error = -EINVAL; /* only used if we fail.. */ 237 if (reclen > buf->count) 238 return false; 239 d_ino = ino; 240 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 241 buf->error = -EOVERFLOW; 242 return false; 243 } 244 prev_reclen = buf->prev_reclen; 245 if (prev_reclen && signal_pending(current)) 246 return false; 247 dirent = buf->current_dir; 248 prev = (void __user *) dirent - prev_reclen; 249 if (!user_write_access_begin(prev, reclen + prev_reclen)) 250 goto efault; 251 252 /* This might be 'dirent->d_off', but if so it will get overwritten */ 253 unsafe_put_user(offset, &prev->d_off, efault_end); 254 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 255 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 256 unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); 257 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 258 user_write_access_end(); 259 260 buf->current_dir = (void __user *)dirent + reclen; 261 buf->prev_reclen = reclen; 262 buf->count -= reclen; 263 return true; 264 efault_end: 265 user_write_access_end(); 266 efault: 267 buf->error = -EFAULT; 268 return false; 269 } 270 271 SYSCALL_DEFINE3(getdents, unsigned int, fd, 272 struct linux_dirent __user *, dirent, unsigned int, count) 273 { 274 struct fd f; 275 struct getdents_callback buf = { 276 .ctx.actor = filldir, 277 .count = count, 278 .current_dir = dirent 279 }; 280 int error; 281 282 f = fdget_pos(fd); 283 if (!f.file) 284 return -EBADF; 285 286 error = iterate_dir(f.file, &buf.ctx); 287 if (error >= 0) 288 error = buf.error; 289 if (buf.prev_reclen) { 290 struct linux_dirent __user * lastdirent; 291 lastdirent = (void __user *)buf.current_dir - buf.prev_reclen; 292 293 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 294 error = -EFAULT; 295 else 296 error = count - buf.count; 297 } 298 fdput_pos(f); 299 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 static bool filldir64(struct dir_context *ctx, const char *name, int namlen, 311 loff_t offset, u64 ino, unsigned int d_type) 312 { 313 struct linux_dirent64 __user *dirent, *prev; 314 struct getdents_callback64 *buf = 315 container_of(ctx, struct getdents_callback64, ctx); 316 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, 317 sizeof(u64)); 318 int prev_reclen; 319 320 buf->error = verify_dirent_name(name, namlen); 321 if (unlikely(buf->error)) 322 return false; 323 buf->error = -EINVAL; /* only used if we fail.. */ 324 if (reclen > buf->count) 325 return false; 326 prev_reclen = buf->prev_reclen; 327 if (prev_reclen && signal_pending(current)) 328 return false; 329 dirent = buf->current_dir; 330 prev = (void __user *)dirent - prev_reclen; 331 if (!user_write_access_begin(prev, reclen + prev_reclen)) 332 goto efault; 333 334 /* This might be 'dirent->d_off', but if so it will get overwritten */ 335 unsafe_put_user(offset, &prev->d_off, efault_end); 336 unsafe_put_user(ino, &dirent->d_ino, efault_end); 337 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 338 unsafe_put_user(d_type, &dirent->d_type, efault_end); 339 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 340 user_write_access_end(); 341 342 buf->prev_reclen = reclen; 343 buf->current_dir = (void __user *)dirent + reclen; 344 buf->count -= reclen; 345 return true; 346 347 efault_end: 348 user_write_access_end(); 349 efault: 350 buf->error = -EFAULT; 351 return false; 352 } 353 354 SYSCALL_DEFINE3(getdents64, unsigned int, fd, 355 struct linux_dirent64 __user *, dirent, unsigned int, count) 356 { 357 struct fd f; 358 struct getdents_callback64 buf = { 359 .ctx.actor = filldir64, 360 .count = count, 361 .current_dir = dirent 362 }; 363 int error; 364 365 f = fdget_pos(fd); 366 if (!f.file) 367 return -EBADF; 368 369 error = iterate_dir(f.file, &buf.ctx); 370 if (error >= 0) 371 error = buf.error; 372 if (buf.prev_reclen) { 373 struct linux_dirent64 __user * lastdirent; 374 typeof(lastdirent->d_off) d_off = buf.ctx.pos; 375 376 lastdirent = (void __user *) buf.current_dir - buf.prev_reclen; 377 if (put_user(d_off, &lastdirent->d_off)) 378 error = -EFAULT; 379 else 380 error = count - buf.count; 381 } 382 fdput_pos(f); 383 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 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 struct compat_readdir_callback *buf = 405 container_of(ctx, struct compat_readdir_callback, ctx); 406 struct compat_old_linux_dirent __user *dirent; 407 compat_ulong_t d_ino; 408 409 if (buf->result) 410 return false; 411 buf->result = verify_dirent_name(name, namlen); 412 if (buf->result) 413 return false; 414 d_ino = ino; 415 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 416 buf->result = -EOVERFLOW; 417 return false; 418 } 419 buf->result++; 420 dirent = buf->dirent; 421 if (!user_write_access_begin(dirent, 422 (unsigned long)(dirent->d_name + namlen + 1) - 423 (unsigned long)dirent)) 424 goto efault; 425 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 426 unsafe_put_user(offset, &dirent->d_offset, efault_end); 427 unsafe_put_user(namlen, &dirent->d_namlen, efault_end); 428 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 429 user_write_access_end(); 430 return true; 431 efault_end: 432 user_write_access_end(); 433 efault: 434 buf->result = -EFAULT; 435 return false; 436 } 437 438 COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 439 struct compat_old_linux_dirent __user *, dirent, unsigned int, count) 440 { 441 int error; 442 struct fd f = fdget_pos(fd); 443 struct compat_readdir_callback buf = { 444 .ctx.actor = compat_fillonedir, 445 .dirent = dirent 446 }; 447 448 if (!f.file) 449 return -EBADF; 450 451 error = iterate_dir(f.file, &buf.ctx); 452 if (buf.result) 453 error = buf.result; 454 455 fdput_pos(f); 456 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 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 struct compat_linux_dirent __user *dirent, *prev; 478 struct compat_getdents_callback *buf = 479 container_of(ctx, struct compat_getdents_callback, ctx); 480 compat_ulong_t d_ino; 481 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + 482 namlen + 2, sizeof(compat_long_t)); 483 int prev_reclen; 484 485 buf->error = verify_dirent_name(name, namlen); 486 if (unlikely(buf->error)) 487 return false; 488 buf->error = -EINVAL; /* only used if we fail.. */ 489 if (reclen > buf->count) 490 return false; 491 d_ino = ino; 492 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 493 buf->error = -EOVERFLOW; 494 return false; 495 } 496 prev_reclen = buf->prev_reclen; 497 if (prev_reclen && signal_pending(current)) 498 return false; 499 dirent = buf->current_dir; 500 prev = (void __user *) dirent - prev_reclen; 501 if (!user_write_access_begin(prev, reclen + prev_reclen)) 502 goto efault; 503 504 unsafe_put_user(offset, &prev->d_off, efault_end); 505 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 506 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 507 unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); 508 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 509 user_write_access_end(); 510 511 buf->prev_reclen = reclen; 512 buf->current_dir = (void __user *)dirent + reclen; 513 buf->count -= reclen; 514 return true; 515 efault_end: 516 user_write_access_end(); 517 efault: 518 buf->error = -EFAULT; 519 return false; 520 } 521 522 COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd, 523 struct compat_linux_dirent __user *, dirent, unsigned int, count) 524 { 525 struct fd f; 526 struct compat_getdents_callback buf = { 527 .ctx.actor = compat_filldir, 528 .current_dir = dirent, 529 .count = count 530 }; 531 int error; 532 533 f = fdget_pos(fd); 534 if (!f.file) 535 return -EBADF; 536 537 error = iterate_dir(f.file, &buf.ctx); 538 if (error >= 0) 539 error = buf.error; 540 if (buf.prev_reclen) { 541 struct compat_linux_dirent __user * lastdirent; 542 lastdirent = (void __user *)buf.current_dir - buf.prev_reclen; 543 544 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 545 error = -EFAULT; 546 else 547 error = count - buf.count; 548 } 549 fdput_pos(f); 550 return error; 551 } 552 #endif 553