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[1]; 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 int 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 -EINVAL; 153 d_ino = ino; 154 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 155 buf->result = -EOVERFLOW; 156 return -EOVERFLOW; 157 } 158 buf->result++; 159 dirent = buf->dirent; 160 if (!access_ok(dirent, 161 (unsigned long)(dirent->d_name + namlen + 1) - 162 (unsigned long)dirent)) 163 goto efault; 164 if ( __put_user(d_ino, &dirent->d_ino) || 165 __put_user(offset, &dirent->d_offset) || 166 __put_user(namlen, &dirent->d_namlen) || 167 __copy_to_user(dirent->d_name, name, namlen) || 168 __put_user(0, dirent->d_name + namlen)) 169 goto efault; 170 return 0; 171 efault: 172 buf->result = -EFAULT; 173 return -EFAULT; 174 } 175 176 SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 177 struct old_linux_dirent __user *, dirent, unsigned int, count) 178 { 179 int error; 180 struct fd f = fdget_pos(fd); 181 struct readdir_callback buf = { 182 .ctx.actor = fillonedir, 183 .dirent = dirent 184 }; 185 186 if (!f.file) 187 return -EBADF; 188 189 error = iterate_dir(f.file, &buf.ctx); 190 if (buf.result) 191 error = buf.result; 192 193 fdput_pos(f); 194 return error; 195 } 196 197 #endif /* __ARCH_WANT_OLD_READDIR */ 198 199 /* 200 * New, all-improved, singing, dancing, iBCS2-compliant getdents() 201 * interface. 202 */ 203 struct linux_dirent { 204 unsigned long d_ino; 205 unsigned long d_off; 206 unsigned short d_reclen; 207 char d_name[1]; 208 }; 209 210 struct getdents_callback { 211 struct dir_context ctx; 212 struct linux_dirent __user * current_dir; 213 int prev_reclen; 214 int count; 215 int error; 216 }; 217 218 static int filldir(struct dir_context *ctx, const char *name, int namlen, 219 loff_t offset, u64 ino, unsigned int d_type) 220 { 221 struct linux_dirent __user *dirent, *prev; 222 struct getdents_callback *buf = 223 container_of(ctx, struct getdents_callback, ctx); 224 unsigned long d_ino; 225 int reclen = ALIGN(offsetof(struct linux_dirent, d_name) + namlen + 2, 226 sizeof(long)); 227 int prev_reclen; 228 229 buf->error = verify_dirent_name(name, namlen); 230 if (unlikely(buf->error)) 231 return buf->error; 232 buf->error = -EINVAL; /* only used if we fail.. */ 233 if (reclen > buf->count) 234 return -EINVAL; 235 d_ino = ino; 236 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 237 buf->error = -EOVERFLOW; 238 return -EOVERFLOW; 239 } 240 prev_reclen = buf->prev_reclen; 241 if (prev_reclen && signal_pending(current)) 242 return -EINTR; 243 dirent = buf->current_dir; 244 prev = (void __user *) dirent - prev_reclen; 245 if (!user_access_begin(prev, reclen + prev_reclen)) 246 goto efault; 247 248 /* This might be 'dirent->d_off', but if so it will get overwritten */ 249 unsafe_put_user(offset, &prev->d_off, efault_end); 250 unsafe_put_user(d_ino, &dirent->d_ino, efault_end); 251 unsafe_put_user(reclen, &dirent->d_reclen, efault_end); 252 unsafe_put_user(d_type, (char __user *) dirent + reclen - 1, efault_end); 253 unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end); 254 user_access_end(); 255 256 buf->current_dir = (void __user *)dirent + reclen; 257 buf->prev_reclen = reclen; 258 buf->count -= reclen; 259 return 0; 260 efault_end: 261 user_access_end(); 262 efault: 263 buf->error = -EFAULT; 264 return -EFAULT; 265 } 266 267 SYSCALL_DEFINE3(getdents, unsigned int, fd, 268 struct linux_dirent __user *, dirent, unsigned int, count) 269 { 270 struct fd f; 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 if (buf.prev_reclen) { 289 struct linux_dirent __user * lastdirent; 290 lastdirent = (void __user *)buf.current_dir - buf.prev_reclen; 291 292 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 293 error = -EFAULT; 294 else 295 error = count - buf.count; 296 } 297 fdput_pos(f); 298 return error; 299 } 300 301 struct getdents_callback64 { 302 struct dir_context ctx; 303 struct linux_dirent64 __user * current_dir; 304 int prev_reclen; 305 int count; 306 int error; 307 }; 308 309 static int filldir64(struct dir_context *ctx, const char *name, int namlen, 310 loff_t offset, u64 ino, unsigned int d_type) 311 { 312 struct linux_dirent64 __user *dirent, *prev; 313 struct getdents_callback64 *buf = 314 container_of(ctx, struct getdents_callback64, ctx); 315 int reclen = ALIGN(offsetof(struct linux_dirent64, d_name) + namlen + 1, 316 sizeof(u64)); 317 int prev_reclen; 318 319 buf->error = verify_dirent_name(name, namlen); 320 if (unlikely(buf->error)) 321 return buf->error; 322 buf->error = -EINVAL; /* only used if we fail.. */ 323 if (reclen > buf->count) 324 return -EINVAL; 325 prev_reclen = buf->prev_reclen; 326 if (prev_reclen && signal_pending(current)) 327 return -EINTR; 328 dirent = buf->current_dir; 329 prev = (void __user *)dirent - prev_reclen; 330 if (!user_access_begin(prev, reclen + prev_reclen)) 331 goto efault; 332 333 /* This might be 'dirent->d_off', but if so it will get overwritten */ 334 unsafe_put_user(offset, &prev->d_off, efault_end); 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->prev_reclen = reclen; 342 buf->current_dir = (void __user *)dirent + reclen; 343 buf->count -= reclen; 344 return 0; 345 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 getdents_callback64 buf = { 358 .ctx.actor = filldir64, 359 .count = count, 360 .current_dir = dirent 361 }; 362 int error; 363 364 if (!access_ok(dirent, count)) 365 return -EFAULT; 366 367 f = fdget_pos(fd); 368 if (!f.file) 369 return -EBADF; 370 371 error = iterate_dir(f.file, &buf.ctx); 372 if (error >= 0) 373 error = buf.error; 374 if (buf.prev_reclen) { 375 struct linux_dirent64 __user * lastdirent; 376 typeof(lastdirent->d_off) d_off = buf.ctx.pos; 377 378 lastdirent = (void __user *) buf.current_dir - buf.prev_reclen; 379 if (__put_user(d_off, &lastdirent->d_off)) 380 error = -EFAULT; 381 else 382 error = count - buf.count; 383 } 384 fdput_pos(f); 385 return error; 386 } 387 388 389 SYSCALL_DEFINE3(getdents64, unsigned int, fd, 390 struct linux_dirent64 __user *, dirent, unsigned int, count) 391 { 392 return ksys_getdents64(fd, dirent, count); 393 } 394 395 #ifdef CONFIG_COMPAT 396 struct compat_old_linux_dirent { 397 compat_ulong_t d_ino; 398 compat_ulong_t d_offset; 399 unsigned short d_namlen; 400 char d_name[1]; 401 }; 402 403 struct compat_readdir_callback { 404 struct dir_context ctx; 405 struct compat_old_linux_dirent __user *dirent; 406 int result; 407 }; 408 409 static int compat_fillonedir(struct dir_context *ctx, const char *name, 410 int namlen, loff_t offset, u64 ino, 411 unsigned int d_type) 412 { 413 struct compat_readdir_callback *buf = 414 container_of(ctx, struct compat_readdir_callback, ctx); 415 struct compat_old_linux_dirent __user *dirent; 416 compat_ulong_t d_ino; 417 418 if (buf->result) 419 return -EINVAL; 420 d_ino = ino; 421 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 422 buf->result = -EOVERFLOW; 423 return -EOVERFLOW; 424 } 425 buf->result++; 426 dirent = buf->dirent; 427 if (!access_ok(dirent, 428 (unsigned long)(dirent->d_name + namlen + 1) - 429 (unsigned long)dirent)) 430 goto efault; 431 if ( __put_user(d_ino, &dirent->d_ino) || 432 __put_user(offset, &dirent->d_offset) || 433 __put_user(namlen, &dirent->d_namlen) || 434 __copy_to_user(dirent->d_name, name, namlen) || 435 __put_user(0, dirent->d_name + namlen)) 436 goto efault; 437 return 0; 438 efault: 439 buf->result = -EFAULT; 440 return -EFAULT; 441 } 442 443 COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd, 444 struct compat_old_linux_dirent __user *, dirent, unsigned int, count) 445 { 446 int error; 447 struct fd f = fdget_pos(fd); 448 struct compat_readdir_callback buf = { 449 .ctx.actor = compat_fillonedir, 450 .dirent = dirent 451 }; 452 453 if (!f.file) 454 return -EBADF; 455 456 error = iterate_dir(f.file, &buf.ctx); 457 if (buf.result) 458 error = buf.result; 459 460 fdput_pos(f); 461 return error; 462 } 463 464 struct compat_linux_dirent { 465 compat_ulong_t d_ino; 466 compat_ulong_t d_off; 467 unsigned short d_reclen; 468 char d_name[1]; 469 }; 470 471 struct compat_getdents_callback { 472 struct dir_context ctx; 473 struct compat_linux_dirent __user *current_dir; 474 struct compat_linux_dirent __user *previous; 475 int count; 476 int error; 477 }; 478 479 static int compat_filldir(struct dir_context *ctx, const char *name, int namlen, 480 loff_t offset, u64 ino, unsigned int d_type) 481 { 482 struct compat_linux_dirent __user * dirent; 483 struct compat_getdents_callback *buf = 484 container_of(ctx, struct compat_getdents_callback, ctx); 485 compat_ulong_t d_ino; 486 int reclen = ALIGN(offsetof(struct compat_linux_dirent, d_name) + 487 namlen + 2, sizeof(compat_long_t)); 488 489 buf->error = -EINVAL; /* only used if we fail.. */ 490 if (reclen > buf->count) 491 return -EINVAL; 492 d_ino = ino; 493 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { 494 buf->error = -EOVERFLOW; 495 return -EOVERFLOW; 496 } 497 dirent = buf->previous; 498 if (dirent) { 499 if (signal_pending(current)) 500 return -EINTR; 501 if (__put_user(offset, &dirent->d_off)) 502 goto efault; 503 } 504 dirent = buf->current_dir; 505 if (__put_user(d_ino, &dirent->d_ino)) 506 goto efault; 507 if (__put_user(reclen, &dirent->d_reclen)) 508 goto efault; 509 if (copy_to_user(dirent->d_name, name, namlen)) 510 goto efault; 511 if (__put_user(0, dirent->d_name + namlen)) 512 goto efault; 513 if (__put_user(d_type, (char __user *) dirent + reclen - 1)) 514 goto efault; 515 buf->previous = dirent; 516 dirent = (void __user *)dirent + reclen; 517 buf->current_dir = dirent; 518 buf->count -= reclen; 519 return 0; 520 efault: 521 buf->error = -EFAULT; 522 return -EFAULT; 523 } 524 525 COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd, 526 struct compat_linux_dirent __user *, dirent, unsigned int, count) 527 { 528 struct fd f; 529 struct compat_linux_dirent __user * lastdirent; 530 struct compat_getdents_callback buf = { 531 .ctx.actor = compat_filldir, 532 .current_dir = dirent, 533 .count = count 534 }; 535 int error; 536 537 if (!access_ok(dirent, count)) 538 return -EFAULT; 539 540 f = fdget_pos(fd); 541 if (!f.file) 542 return -EBADF; 543 544 error = iterate_dir(f.file, &buf.ctx); 545 if (error >= 0) 546 error = buf.error; 547 lastdirent = buf.previous; 548 if (lastdirent) { 549 if (put_user(buf.ctx.pos, &lastdirent->d_off)) 550 error = -EFAULT; 551 else 552 error = count - buf.count; 553 } 554 fdput_pos(f); 555 return error; 556 } 557 #endif 558