xref: /linux/fs/vboxsf/utils.c (revision ef14aa143f1dd8adcba6c9277c3bbed2fe0969b4)
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 
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] */
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 
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 
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, &params);
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 
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 
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 
236 int vboxsf_getattr(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 
261 int vboxsf_setattr(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, &params);
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  */
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 
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 
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 
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_obj(*p);
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 
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 
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