1 // SPDX-License-Identifier: MIT 2 /* 3 * VirtualBox Guest Shared Folders support: Utility functions. 4 * Mainly conversion from/to VirtualBox/Linux data structures. 5 * 6 * Copyright (C) 2006-2018 Oracle Corporation 7 */ 8 9 #include <linux/namei.h> 10 #include <linux/nls.h> 11 #include <linux/sizes.h> 12 #include <linux/vfs.h> 13 #include "vfsmod.h" 14 15 struct inode *vboxsf_new_inode(struct super_block *sb) 16 { 17 struct vboxsf_sbi *sbi = VBOXSF_SBI(sb); 18 struct inode *inode; 19 unsigned long flags; 20 int cursor, ret; 21 u32 gen; 22 23 inode = new_inode(sb); 24 if (!inode) 25 return ERR_PTR(-ENOMEM); 26 27 idr_preload(GFP_KERNEL); 28 spin_lock_irqsave(&sbi->ino_idr_lock, flags); 29 cursor = idr_get_cursor(&sbi->ino_idr); 30 ret = idr_alloc_cyclic(&sbi->ino_idr, inode, 1, 0, GFP_ATOMIC); 31 if (ret >= 0 && ret < cursor) 32 sbi->next_generation++; 33 gen = sbi->next_generation; 34 spin_unlock_irqrestore(&sbi->ino_idr_lock, flags); 35 idr_preload_end(); 36 37 if (ret < 0) { 38 iput(inode); 39 return ERR_PTR(ret); 40 } 41 42 inode->i_ino = ret; 43 inode->i_generation = gen; 44 return inode; 45 } 46 47 /* set [inode] attributes based on [info], uid/gid based on [sbi] */ 48 int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode, 49 const struct shfl_fsobjinfo *info, bool reinit) 50 { 51 const struct shfl_fsobjattr *attr; 52 s64 allocated; 53 umode_t mode; 54 55 attr = &info->attr; 56 57 #define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0) 58 59 mode = mode_set(IRUSR); 60 mode |= mode_set(IWUSR); 61 mode |= mode_set(IXUSR); 62 63 mode |= mode_set(IRGRP); 64 mode |= mode_set(IWGRP); 65 mode |= mode_set(IXGRP); 66 67 mode |= mode_set(IROTH); 68 mode |= mode_set(IWOTH); 69 mode |= mode_set(IXOTH); 70 71 #undef mode_set 72 73 /* We use the host-side values for these */ 74 inode->i_flags |= S_NOATIME | S_NOCMTIME; 75 inode->i_mapping->a_ops = &vboxsf_reg_aops; 76 77 if (SHFL_IS_DIRECTORY(attr->mode)) { 78 if (sbi->o.dmode_set) 79 mode = sbi->o.dmode; 80 mode &= ~sbi->o.dmask; 81 mode |= S_IFDIR; 82 if (!reinit) { 83 inode->i_op = &vboxsf_dir_iops; 84 inode->i_fop = &vboxsf_dir_fops; 85 /* 86 * XXX: this probably should be set to the number of entries 87 * in the directory plus two (. ..) 88 */ 89 set_nlink(inode, 1); 90 } else if (!S_ISDIR(inode->i_mode)) 91 return -ESTALE; 92 inode->i_mode = mode; 93 } else if (SHFL_IS_SYMLINK(attr->mode)) { 94 if (sbi->o.fmode_set) 95 mode = sbi->o.fmode; 96 mode &= ~sbi->o.fmask; 97 mode |= S_IFLNK; 98 if (!reinit) { 99 inode->i_op = &vboxsf_lnk_iops; 100 set_nlink(inode, 1); 101 } else if (!S_ISLNK(inode->i_mode)) 102 return -ESTALE; 103 inode->i_mode = mode; 104 } else { 105 if (sbi->o.fmode_set) 106 mode = sbi->o.fmode; 107 mode &= ~sbi->o.fmask; 108 mode |= S_IFREG; 109 if (!reinit) { 110 inode->i_op = &vboxsf_reg_iops; 111 inode->i_fop = &vboxsf_reg_fops; 112 set_nlink(inode, 1); 113 } else if (!S_ISREG(inode->i_mode)) 114 return -ESTALE; 115 inode->i_mode = mode; 116 } 117 118 inode->i_uid = sbi->o.uid; 119 inode->i_gid = sbi->o.gid; 120 121 inode->i_size = info->size; 122 inode->i_blkbits = 12; 123 /* i_blocks always in units of 512 bytes! */ 124 allocated = info->allocated + 511; 125 do_div(allocated, 512); 126 inode->i_blocks = allocated; 127 128 inode->i_atime = ns_to_timespec64( 129 info->access_time.ns_relative_to_unix_epoch); 130 inode->i_ctime = ns_to_timespec64( 131 info->change_time.ns_relative_to_unix_epoch); 132 inode->i_mtime = ns_to_timespec64( 133 info->modification_time.ns_relative_to_unix_epoch); 134 return 0; 135 } 136 137 int vboxsf_create_at_dentry(struct dentry *dentry, 138 struct shfl_createparms *params) 139 { 140 struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb); 141 struct shfl_string *path; 142 int err; 143 144 path = vboxsf_path_from_dentry(sbi, dentry); 145 if (IS_ERR(path)) 146 return PTR_ERR(path); 147 148 err = vboxsf_create(sbi->root, path, params); 149 __putname(path); 150 151 return err; 152 } 153 154 int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path, 155 struct shfl_fsobjinfo *info) 156 { 157 struct shfl_createparms params = {}; 158 int err; 159 160 params.handle = SHFL_HANDLE_NIL; 161 params.create_flags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW; 162 163 err = vboxsf_create(sbi->root, path, ¶ms); 164 if (err) 165 return err; 166 167 if (params.result != SHFL_FILE_EXISTS) 168 return -ENOENT; 169 170 if (info) 171 *info = params.info; 172 173 return 0; 174 } 175 176 int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info) 177 { 178 struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb); 179 struct shfl_string *path; 180 int err; 181 182 path = vboxsf_path_from_dentry(sbi, dentry); 183 if (IS_ERR(path)) 184 return PTR_ERR(path); 185 186 err = vboxsf_stat(sbi, path, info); 187 __putname(path); 188 return err; 189 } 190 191 int vboxsf_inode_revalidate(struct dentry *dentry) 192 { 193 struct vboxsf_sbi *sbi; 194 struct vboxsf_inode *sf_i; 195 struct shfl_fsobjinfo info; 196 struct timespec64 prev_mtime; 197 struct inode *inode; 198 int err; 199 200 if (!dentry || !d_really_is_positive(dentry)) 201 return -EINVAL; 202 203 inode = d_inode(dentry); 204 prev_mtime = inode->i_mtime; 205 sf_i = VBOXSF_I(inode); 206 sbi = VBOXSF_SBI(dentry->d_sb); 207 if (!sf_i->force_restat) { 208 if (time_before(jiffies, dentry->d_time + sbi->o.ttl)) 209 return 0; 210 } 211 212 err = vboxsf_stat_dentry(dentry, &info); 213 if (err) 214 return err; 215 216 dentry->d_time = jiffies; 217 sf_i->force_restat = 0; 218 err = vboxsf_init_inode(sbi, inode, &info, true); 219 if (err) 220 return err; 221 222 /* 223 * If the file was changed on the host side we need to invalidate the 224 * page-cache for it. Note this also gets triggered by our own writes, 225 * this is unavoidable. 226 */ 227 if (timespec64_compare(&inode->i_mtime, &prev_mtime) > 0) 228 invalidate_inode_pages2(inode->i_mapping); 229 230 return 0; 231 } 232 233 int vboxsf_getattr(struct user_namespace *mnt_userns, const struct path *path, 234 struct kstat *kstat, u32 request_mask, unsigned int flags) 235 { 236 int err; 237 struct dentry *dentry = path->dentry; 238 struct inode *inode = d_inode(dentry); 239 struct vboxsf_inode *sf_i = VBOXSF_I(inode); 240 241 switch (flags & AT_STATX_SYNC_TYPE) { 242 case AT_STATX_DONT_SYNC: 243 err = 0; 244 break; 245 case AT_STATX_FORCE_SYNC: 246 sf_i->force_restat = 1; 247 fallthrough; 248 default: 249 err = vboxsf_inode_revalidate(dentry); 250 } 251 if (err) 252 return err; 253 254 generic_fillattr(&init_user_ns, d_inode(dentry), kstat); 255 return 0; 256 } 257 258 int vboxsf_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, 259 struct iattr *iattr) 260 { 261 struct vboxsf_inode *sf_i = VBOXSF_I(d_inode(dentry)); 262 struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb); 263 struct shfl_createparms params = {}; 264 struct shfl_fsobjinfo info = {}; 265 u32 buf_len; 266 int err; 267 268 params.handle = SHFL_HANDLE_NIL; 269 params.create_flags = SHFL_CF_ACT_OPEN_IF_EXISTS | 270 SHFL_CF_ACT_FAIL_IF_NEW | 271 SHFL_CF_ACCESS_ATTR_WRITE; 272 273 /* this is at least required for Posix hosts */ 274 if (iattr->ia_valid & ATTR_SIZE) 275 params.create_flags |= SHFL_CF_ACCESS_WRITE; 276 277 err = vboxsf_create_at_dentry(dentry, ¶ms); 278 if (err || params.result != SHFL_FILE_EXISTS) 279 return err ? err : -ENOENT; 280 281 #define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0) 282 283 /* 284 * Setting the file size and setting the other attributes has to 285 * be handled separately. 286 */ 287 if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) { 288 if (iattr->ia_valid & ATTR_MODE) { 289 info.attr.mode = mode_set(IRUSR); 290 info.attr.mode |= mode_set(IWUSR); 291 info.attr.mode |= mode_set(IXUSR); 292 info.attr.mode |= mode_set(IRGRP); 293 info.attr.mode |= mode_set(IWGRP); 294 info.attr.mode |= mode_set(IXGRP); 295 info.attr.mode |= mode_set(IROTH); 296 info.attr.mode |= mode_set(IWOTH); 297 info.attr.mode |= mode_set(IXOTH); 298 299 if (iattr->ia_mode & S_IFDIR) 300 info.attr.mode |= SHFL_TYPE_DIRECTORY; 301 else 302 info.attr.mode |= SHFL_TYPE_FILE; 303 } 304 305 if (iattr->ia_valid & ATTR_ATIME) 306 info.access_time.ns_relative_to_unix_epoch = 307 timespec64_to_ns(&iattr->ia_atime); 308 309 if (iattr->ia_valid & ATTR_MTIME) 310 info.modification_time.ns_relative_to_unix_epoch = 311 timespec64_to_ns(&iattr->ia_mtime); 312 313 /* 314 * Ignore ctime (inode change time) as it can't be set 315 * from userland anyway. 316 */ 317 318 buf_len = sizeof(info); 319 err = vboxsf_fsinfo(sbi->root, params.handle, 320 SHFL_INFO_SET | SHFL_INFO_FILE, &buf_len, 321 &info); 322 if (err) { 323 vboxsf_close(sbi->root, params.handle); 324 return err; 325 } 326 327 /* the host may have given us different attr then requested */ 328 sf_i->force_restat = 1; 329 } 330 331 #undef mode_set 332 333 if (iattr->ia_valid & ATTR_SIZE) { 334 memset(&info, 0, sizeof(info)); 335 info.size = iattr->ia_size; 336 buf_len = sizeof(info); 337 err = vboxsf_fsinfo(sbi->root, params.handle, 338 SHFL_INFO_SET | SHFL_INFO_SIZE, &buf_len, 339 &info); 340 if (err) { 341 vboxsf_close(sbi->root, params.handle); 342 return err; 343 } 344 345 /* the host may have given us different attr then requested */ 346 sf_i->force_restat = 1; 347 } 348 349 vboxsf_close(sbi->root, params.handle); 350 351 /* Update the inode with what the host has actually given us. */ 352 if (sf_i->force_restat) 353 vboxsf_inode_revalidate(dentry); 354 355 return 0; 356 } 357 358 /* 359 * [dentry] contains string encoded in coding system that corresponds 360 * to [sbi]->nls, we must convert it to UTF8 here. 361 * Returns a shfl_string allocated through __getname (must be freed using 362 * __putname), or an ERR_PTR on error. 363 */ 364 struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi, 365 struct dentry *dentry) 366 { 367 struct shfl_string *shfl_path; 368 int path_len, out_len, nb; 369 char *buf, *path; 370 wchar_t uni; 371 u8 *out; 372 373 buf = __getname(); 374 if (!buf) 375 return ERR_PTR(-ENOMEM); 376 377 path = dentry_path_raw(dentry, buf, PATH_MAX); 378 if (IS_ERR(path)) { 379 __putname(buf); 380 return ERR_CAST(path); 381 } 382 path_len = strlen(path); 383 384 if (sbi->nls) { 385 shfl_path = __getname(); 386 if (!shfl_path) { 387 __putname(buf); 388 return ERR_PTR(-ENOMEM); 389 } 390 391 out = shfl_path->string.utf8; 392 out_len = PATH_MAX - SHFLSTRING_HEADER_SIZE - 1; 393 394 while (path_len) { 395 nb = sbi->nls->char2uni(path, path_len, &uni); 396 if (nb < 0) { 397 __putname(shfl_path); 398 __putname(buf); 399 return ERR_PTR(-EINVAL); 400 } 401 path += nb; 402 path_len -= nb; 403 404 nb = utf32_to_utf8(uni, out, out_len); 405 if (nb < 0) { 406 __putname(shfl_path); 407 __putname(buf); 408 return ERR_PTR(-ENAMETOOLONG); 409 } 410 out += nb; 411 out_len -= nb; 412 } 413 *out = 0; 414 shfl_path->length = out - shfl_path->string.utf8; 415 shfl_path->size = shfl_path->length + 1; 416 __putname(buf); 417 } else { 418 if ((SHFLSTRING_HEADER_SIZE + path_len + 1) > PATH_MAX) { 419 __putname(buf); 420 return ERR_PTR(-ENAMETOOLONG); 421 } 422 /* 423 * dentry_path stores the name at the end of buf, but the 424 * shfl_string string we return must be properly aligned. 425 */ 426 shfl_path = (struct shfl_string *)buf; 427 memmove(shfl_path->string.utf8, path, path_len); 428 shfl_path->string.utf8[path_len] = 0; 429 shfl_path->length = path_len; 430 shfl_path->size = path_len + 1; 431 } 432 433 return shfl_path; 434 } 435 436 int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len, 437 const unsigned char *utf8_name, size_t utf8_len) 438 { 439 const char *in; 440 char *out; 441 size_t out_len; 442 size_t out_bound_len; 443 size_t in_bound_len; 444 445 in = utf8_name; 446 in_bound_len = utf8_len; 447 448 out = name; 449 out_len = 0; 450 /* Reserve space for terminating 0 */ 451 out_bound_len = name_bound_len - 1; 452 453 while (in_bound_len) { 454 int nb; 455 unicode_t uni; 456 457 nb = utf8_to_utf32(in, in_bound_len, &uni); 458 if (nb < 0) 459 return -EINVAL; 460 461 in += nb; 462 in_bound_len -= nb; 463 464 nb = sbi->nls->uni2char(uni, out, out_bound_len); 465 if (nb < 0) 466 return nb; 467 468 out += nb; 469 out_bound_len -= nb; 470 out_len += nb; 471 } 472 473 *out = 0; 474 475 return 0; 476 } 477 478 static struct vboxsf_dir_buf *vboxsf_dir_buf_alloc(struct list_head *list) 479 { 480 struct vboxsf_dir_buf *b; 481 482 b = kmalloc(sizeof(*b), GFP_KERNEL); 483 if (!b) 484 return NULL; 485 486 b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL); 487 if (!b->buf) { 488 kfree(b); 489 return NULL; 490 } 491 492 b->entries = 0; 493 b->used = 0; 494 b->free = DIR_BUFFER_SIZE; 495 list_add(&b->head, list); 496 497 return b; 498 } 499 500 static void vboxsf_dir_buf_free(struct vboxsf_dir_buf *b) 501 { 502 list_del(&b->head); 503 kfree(b->buf); 504 kfree(b); 505 } 506 507 struct vboxsf_dir_info *vboxsf_dir_info_alloc(void) 508 { 509 struct vboxsf_dir_info *p; 510 511 p = kmalloc(sizeof(*p), GFP_KERNEL); 512 if (!p) 513 return NULL; 514 515 INIT_LIST_HEAD(&p->info_list); 516 return p; 517 } 518 519 void vboxsf_dir_info_free(struct vboxsf_dir_info *p) 520 { 521 struct list_head *list, *pos, *tmp; 522 523 list = &p->info_list; 524 list_for_each_safe(pos, tmp, list) { 525 struct vboxsf_dir_buf *b; 526 527 b = list_entry(pos, struct vboxsf_dir_buf, head); 528 vboxsf_dir_buf_free(b); 529 } 530 kfree(p); 531 } 532 533 int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d, 534 u64 handle) 535 { 536 struct vboxsf_dir_buf *b; 537 u32 entries, size; 538 int err = 0; 539 void *buf; 540 541 /* vboxsf_dirinfo returns 1 on end of dir */ 542 while (err == 0) { 543 b = vboxsf_dir_buf_alloc(&sf_d->info_list); 544 if (!b) { 545 err = -ENOMEM; 546 break; 547 } 548 549 buf = b->buf; 550 size = b->free; 551 552 err = vboxsf_dirinfo(sbi->root, handle, NULL, 0, 0, 553 &size, buf, &entries); 554 if (err < 0) 555 break; 556 557 b->entries += entries; 558 b->free -= size; 559 b->used += size; 560 } 561 562 if (b && b->used == 0) 563 vboxsf_dir_buf_free(b); 564 565 /* -EILSEQ means the host could not translate a filename, ignore */ 566 if (err > 0 || err == -EILSEQ) 567 err = 0; 568 569 return err; 570 } 571