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