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