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 static int verify_dirent_name(const char *name, int len) 107 { 108 if (!len) 109 return -EIO; 110 if (memchr(name, '/', len)) 111 return -EIO; 112 return 0; 113 } 114 115 /* 116 * Traditional linux readdir() handling.. 117 * 118 * "count=1" is a special case, meaning that the buffer is one 119 * dirent-structure in size and that the code can't handle more 120 * anyway. Thus the special "fillonedir()" function for that 121 * case (the low-level handlers don't need to care about this). 122 */ 123 124 #ifdef __ARCH_WANT_OLD_READDIR 125 126 struct old_linux_dirent { 127 unsigned long d_ino; 128 unsigned long d_offset; 129 unsigned short d_namlen; 130 char d_name[1]; 131 }; 132 133 struct readdir_callback { 134 struct dir_context ctx; 135 struct old_linux_dirent __user * dirent; 136 int result; 137 }; 138 139 static int fillonedir(struct dir_context *ctx, const char *name, int namlen, 140 loff_t offset, u64 ino, unsigned int d_type) 141 { 142 struct readdir_callback *buf = 143 container_of(ctx, struct readdir_callback, ctx); 144 struct old_linux_dirent __user * dirent; 145 unsigned long d_ino; 146 147 if (buf->result) 148 return -EINVAL; 149 d_ino = ino; 150 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 151 buf->result = -EOVERFLOW; 152 return -EOVERFLOW; 153 } 154 buf->result++; 155 dirent = buf->dirent; 156 if (!access_ok(dirent, 157 (unsigned long)(dirent->d_name + namlen + 1) - 158 (unsigned long)dirent)) 159 goto efault; 160 if ( __put_user(d_ino, &dirent->d_ino) || 161 __put_user(offset, &dirent->d_offset) || 162 __put_user(namlen, &dirent->d_namlen) || 163 __copy_to_user(dirent->d_name, name, namlen) || 164 __put_user(0, dirent->d_name + namlen)) 165 goto efault; 166 return 0; 167 efault: 168 buf->result = -EFAULT; 169 return -EFAULT; 170 } 171 172 SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 173 struct old_linux_dirent __user *, dirent, unsigned int, count) 174 { 175 int error; 176 struct fd f = fdget_pos(fd); 177 struct readdir_callback buf = { 178 .ctx.actor = fillonedir, 179 .dirent = dirent 180 }; 181 182 if (!f.file) 183 return -EBADF; 184 185 error = iterate_dir(f.file, &buf.ctx); 186 if (buf.result) 187 error = buf.result; 188 189 fdput_pos(f); 190 return error; 191 } 192 193 #endif /* __ARCH_WANT_OLD_READDIR */ 194 195 /* 196 * New, all-improved, singing, dancing, iBCS2-compliant getdents() 197 * interface. 198 */ 199 struct linux_dirent { 200 unsigned long d_ino; 201 unsigned long d_off; 202 unsigned short d_reclen; 203 char d_name[1]; 204 }; 205 206 struct getdents_callback { 207 struct dir_context ctx; 208 struct linux_dirent __user * current_dir; 209 struct linux_dirent __user * previous; 210 int count; 211 int error; 212 }; 213 214 static int filldir(struct dir_context *ctx, const char *name, int namlen, 215 loff_t offset, u64 ino, unsigned int d_type) 216 { 217 struct linux_dirent __user * dirent; 218 struct getdents_callback *buf = 219 container_of(ctx, struct getdents_callback, ctx); 220 unsigned long d_ino; 221 int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2, 222 sizeof(long)); 223 224 buf->error = verify_dirent_name(name, namlen); 225 if (unlikely(buf->error)) 226 return buf->error; 227 buf->error = -EINVAL; /* only used if we fail.. */ 228 if (reclen > buf->count) 229 return -EINVAL; 230 d_ino = ino; 231 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 232 buf->error = -EOVERFLOW; 233 return -EOVERFLOW; 234 } 235 dirent = buf->previous; 236 if (dirent && signal_pending(current)) 237 return -EINTR; 238 239 /* 240 * Note! This range-checks 'previous' (which may be NULL). 241 * The real range was checked in getdents 242 */ 243 if (!user_access_begin(dirent, sizeof(*dirent))) 244 goto efault; 245 if (dirent) 246 unsafe_put_user(offset, &dirent->d_off, efault_end); 247 dirent = buf->current_dir; 248 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 249 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 250 unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); 251 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 252 user_access_end(); 253 254 buf->previous = dirent; 255 dirent = (void __user *)dirent + reclen; 256 buf->current_dir = dirent; 257 buf->count -= reclen; 258 return 0; 259 efault_end: 260 user_access_end(); 261 efault: 262 buf->error = -EFAULT; 263 return -EFAULT; 264 } 265 266 SYSCALL_DEFINE3(getdents, unsigned int, fd, 267 struct linux_dirent __user *, dirent, unsigned int, count) 268 { 269 struct fd f; 270 struct linux_dirent __user * lastdirent; 271 struct getdents_callback buf = { 272 .ctx.actor = filldir, 273 .count = count, 274 .current_dir = dirent 275 }; 276 int error; 277 278 if (!access_ok(dirent, count)) 279 return -EFAULT; 280 281 f = fdget_pos(fd); 282 if (!f.file) 283 return -EBADF; 284 285 error = iterate_dir(f.file, &buf.ctx); 286 if (error >= 0) 287 error = buf.error; 288 lastdirent = buf.previous; 289 if (lastdirent) { 290 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 291 error = -EFAULT; 292 else 293 error = count - buf.count; 294 } 295 fdput_pos(f); 296 return error; 297 } 298 299 struct getdents_callback64 { 300 struct dir_context ctx; 301 struct linux_dirent64 __user * current_dir; 302 struct linux_dirent64 __user * previous; 303 int count; 304 int error; 305 }; 306 307 static int filldir64(struct dir_context *ctx, const char *name, int namlen, 308 loff_t offset, u64 ino, unsigned int d_type) 309 { 310 struct linux_dirent64 __user *dirent; 311 struct getdents_callback64 *buf = 312 container_of(ctx, struct getdents_callback64, ctx); 313 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, 314 sizeof(u64)); 315 316 buf->error = verify_dirent_name(name, namlen); 317 if (unlikely(buf->error)) 318 return buf->error; 319 buf->error = -EINVAL; /* only used if we fail.. */ 320 if (reclen > buf->count) 321 return -EINVAL; 322 dirent = buf->previous; 323 if (dirent && signal_pending(current)) 324 return -EINTR; 325 326 /* 327 * Note! This range-checks 'previous' (which may be NULL). 328 * The real range was checked in getdents 329 */ 330 if (!user_access_begin(dirent, sizeof(*dirent))) 331 goto efault; 332 if (dirent) 333 unsafe_put_user(offset, &dirent->d_off, efault_end); 334 dirent = buf->current_dir; 335 unsafe_put_user(ino, &dirent->d_ino, efault_end); 336 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 337 unsafe_put_user(d_type, &dirent->d_type, efault_end); 338 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 339 user_access_end(); 340 341 buf->previous = dirent; 342 dirent = (void __user *)dirent + reclen; 343 buf->current_dir = dirent; 344 buf->count -= reclen; 345 return 0; 346 efault_end: 347 user_access_end(); 348 efault: 349 buf->error = -EFAULT; 350 return -EFAULT; 351 } 352 353 int ksys_getdents64(unsigned int fd, struct linux_dirent64 __user *dirent, 354 unsigned int count) 355 { 356 struct fd f; 357 struct linux_dirent64 __user * lastdirent; 358 struct getdents_callback64 buf = { 359 .ctx.actor = filldir64, 360 .count = count, 361 .current_dir = dirent 362 }; 363 int error; 364 365 if (!access_ok(dirent, count)) 366 return -EFAULT; 367 368 f = fdget_pos(fd); 369 if (!f.file) 370 return -EBADF; 371 372 error = iterate_dir(f.file, &buf.ctx); 373 if (error >= 0) 374 error = buf.error; 375 lastdirent = buf.previous; 376 if (lastdirent) { 377 typeof(lastdirent->d_off) d_off = buf.ctx.pos; 378 if (__put_user(d_off, &lastdirent->d_off)) 379 error = -EFAULT; 380 else 381 error = count - buf.count; 382 } 383 fdput_pos(f); 384 return error; 385 } 386 387 388 SYSCALL_DEFINE3(getdents64, unsigned int, fd, 389 struct linux_dirent64 __user *, dirent, unsigned int, count) 390 { 391 return ksys_getdents64(fd, dirent, count); 392 } 393 394 #ifdef CONFIG_COMPAT 395 struct compat_old_linux_dirent { 396 compat_ulong_t d_ino; 397 compat_ulong_t d_offset; 398 unsigned short d_namlen; 399 char d_name[1]; 400 }; 401 402 struct compat_readdir_callback { 403 struct dir_context ctx; 404 struct compat_old_linux_dirent __user *dirent; 405 int result; 406 }; 407 408 static int compat_fillonedir(struct dir_context *ctx, const char *name, 409 int namlen, loff_t offset, u64 ino, 410 unsigned int d_type) 411 { 412 struct compat_readdir_callback *buf = 413 container_of(ctx, struct compat_readdir_callback, ctx); 414 struct compat_old_linux_dirent __user *dirent; 415 compat_ulong_t d_ino; 416 417 if (buf->result) 418 return -EINVAL; 419 d_ino = ino; 420 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 421 buf->result = -EOVERFLOW; 422 return -EOVERFLOW; 423 } 424 buf->result++; 425 dirent = buf->dirent; 426 if (!access_ok(dirent, 427 (unsigned long)(dirent->d_name + namlen + 1) - 428 (unsigned long)dirent)) 429 goto efault; 430 if ( __put_user(d_ino, &dirent->d_ino) || 431 __put_user(offset, &dirent->d_offset) || 432 __put_user(namlen, &dirent->d_namlen) || 433 __copy_to_user(dirent->d_name, name, namlen) || 434 __put_user(0, dirent->d_name + namlen)) 435 goto efault; 436 return 0; 437 efault: 438 buf->result = -EFAULT; 439 return -EFAULT; 440 } 441 442 COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 443 struct compat_old_linux_dirent __user *, dirent, unsigned int, count) 444 { 445 int error; 446 struct fd f = fdget_pos(fd); 447 struct compat_readdir_callback buf = { 448 .ctx.actor = compat_fillonedir, 449 .dirent = dirent 450 }; 451 452 if (!f.file) 453 return -EBADF; 454 455 error = iterate_dir(f.file, &buf.ctx); 456 if (buf.result) 457 error = buf.result; 458 459 fdput_pos(f); 460 return error; 461 } 462 463 struct compat_linux_dirent { 464 compat_ulong_t d_ino; 465 compat_ulong_t d_off; 466 unsigned short d_reclen; 467 char d_name[1]; 468 }; 469 470 struct compat_getdents_callback { 471 struct dir_context ctx; 472 struct compat_linux_dirent __user *current_dir; 473 struct compat_linux_dirent __user *previous; 474 int count; 475 int error; 476 }; 477 478 static int compat_filldir(struct dir_context *ctx, const char *name, int namlen, 479 loff_t offset, u64 ino, unsigned int d_type) 480 { 481 struct compat_linux_dirent __user * dirent; 482 struct compat_getdents_callback *buf = 483 container_of(ctx, struct compat_getdents_callback, ctx); 484 compat_ulong_t d_ino; 485 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + 486 namlen + 2, sizeof(compat_long_t)); 487 488 buf->error = -EINVAL; /* only used if we fail.. */ 489 if (reclen > buf->count) 490 return -EINVAL; 491 d_ino = ino; 492 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 493 buf->error = -EOVERFLOW; 494 return -EOVERFLOW; 495 } 496 dirent = buf->previous; 497 if (dirent) { 498 if (signal_pending(current)) 499 return -EINTR; 500 if (__put_user(offset, &dirent->d_off)) 501 goto efault; 502 } 503 dirent = buf->current_dir; 504 if (__put_user(d_ino, &dirent->d_ino)) 505 goto efault; 506 if (__put_user(reclen, &dirent->d_reclen)) 507 goto efault; 508 if (copy_to_user(dirent->d_name, name, namlen)) 509 goto efault; 510 if (__put_user(0, dirent->d_name + namlen)) 511 goto efault; 512 if (__put_user(d_type, (char __user *) dirent + reclen - 1)) 513 goto efault; 514 buf->previous = dirent; 515 dirent = (void __user *)dirent + reclen; 516 buf->current_dir = dirent; 517 buf->count -= reclen; 518 return 0; 519 efault: 520 buf->error = -EFAULT; 521 return -EFAULT; 522 } 523 524 COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd, 525 struct compat_linux_dirent __user *, dirent, unsigned int, count) 526 { 527 struct fd f; 528 struct compat_linux_dirent __user * lastdirent; 529 struct compat_getdents_callback buf = { 530 .ctx.actor = compat_filldir, 531 .current_dir = dirent, 532 .count = count 533 }; 534 int error; 535 536 if (!access_ok(dirent, count)) 537 return -EFAULT; 538 539 f = fdget_pos(fd); 540 if (!f.file) 541 return -EBADF; 542 543 error = iterate_dir(f.file, &buf.ctx); 544 if (error >= 0) 545 error = buf.error; 546 lastdirent = buf.previous; 547 if (lastdirent) { 548 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 549 error = -EFAULT; 550 else 551 error = count - buf.count; 552 } 553 fdput_pos(f); 554 return error; 555 } 556 #endif 557