Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * linux/fs/stat.c
4 : *
5 : * Copyright (C) 1991, 1992 Linus Torvalds
6 : */
7 :
8 : #include <linux/export.h>
9 : #include <linux/mm.h>
10 : #include <linux/errno.h>
11 : #include <linux/file.h>
12 : #include <linux/highuid.h>
13 : #include <linux/fs.h>
14 : #include <linux/namei.h>
15 : #include <linux/security.h>
16 : #include <linux/cred.h>
17 : #include <linux/syscalls.h>
18 : #include <linux/pagemap.h>
19 : #include <linux/compat.h>
20 :
21 : #include <linux/uaccess.h>
22 : #include <asm/unistd.h>
23 :
24 : #include "internal.h"
25 : #include "mount.h"
26 :
27 : /**
28 : * generic_fillattr - Fill in the basic attributes from the inode struct
29 : * @mnt_userns: user namespace of the mount the inode was found from
30 : * @inode: Inode to use as the source
31 : * @stat: Where to fill in the attributes
32 : *
33 : * Fill in the basic attributes in the kstat structure from data that's to be
34 : * found on the VFS inode structure. This is the default if no getattr inode
35 : * operation is supplied.
36 : *
37 : * If the inode has been found through an idmapped mount the user namespace of
38 : * the vfsmount must be passed through @mnt_userns. This function will then
39 : * take care to map the inode according to @mnt_userns before filling in the
40 : * uid and gid filds. On non-idmapped mounts or if permission checking is to be
41 : * performed on the raw inode simply passs init_user_ns.
42 : */
43 0 : void generic_fillattr(struct user_namespace *mnt_userns, struct inode *inode,
44 : struct kstat *stat)
45 : {
46 0 : stat->dev = inode->i_sb->s_dev;
47 0 : stat->ino = inode->i_ino;
48 0 : stat->mode = inode->i_mode;
49 0 : stat->nlink = inode->i_nlink;
50 0 : stat->uid = i_uid_into_mnt(mnt_userns, inode);
51 0 : stat->gid = i_gid_into_mnt(mnt_userns, inode);
52 0 : stat->rdev = inode->i_rdev;
53 0 : stat->size = i_size_read(inode);
54 0 : stat->atime = inode->i_atime;
55 0 : stat->mtime = inode->i_mtime;
56 0 : stat->ctime = inode->i_ctime;
57 0 : stat->blksize = i_blocksize(inode);
58 0 : stat->blocks = inode->i_blocks;
59 0 : }
60 : EXPORT_SYMBOL(generic_fillattr);
61 :
62 : /**
63 : * generic_fill_statx_attr - Fill in the statx attributes from the inode flags
64 : * @inode: Inode to use as the source
65 : * @stat: Where to fill in the attribute flags
66 : *
67 : * Fill in the STATX_ATTR_* flags in the kstat structure for properties of the
68 : * inode that are published on i_flags and enforced by the VFS.
69 : */
70 0 : void generic_fill_statx_attr(struct inode *inode, struct kstat *stat)
71 : {
72 0 : if (inode->i_flags & S_IMMUTABLE)
73 0 : stat->attributes |= STATX_ATTR_IMMUTABLE;
74 0 : if (inode->i_flags & S_APPEND)
75 0 : stat->attributes |= STATX_ATTR_APPEND;
76 0 : stat->attributes_mask |= KSTAT_ATTR_VFS_FLAGS;
77 0 : }
78 : EXPORT_SYMBOL(generic_fill_statx_attr);
79 :
80 : /**
81 : * vfs_getattr_nosec - getattr without security checks
82 : * @path: file to get attributes from
83 : * @stat: structure to return attributes in
84 : * @request_mask: STATX_xxx flags indicating what the caller wants
85 : * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
86 : *
87 : * Get attributes without calling security_inode_getattr.
88 : *
89 : * Currently the only caller other than vfs_getattr is internal to the
90 : * filehandle lookup code, which uses only the inode number and returns no
91 : * attributes to any user. Any other code probably wants vfs_getattr.
92 : */
93 0 : int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
94 : u32 request_mask, unsigned int query_flags)
95 : {
96 : struct user_namespace *mnt_userns;
97 0 : struct inode *inode = d_backing_inode(path->dentry);
98 :
99 0 : memset(stat, 0, sizeof(*stat));
100 0 : stat->result_mask |= STATX_BASIC_STATS;
101 0 : query_flags &= AT_STATX_SYNC_TYPE;
102 :
103 : /* allow the fs to override these if it really wants to */
104 : /* SB_NOATIME means filesystem supplies dummy atime value */
105 0 : if (inode->i_sb->s_flags & SB_NOATIME)
106 0 : stat->result_mask &= ~STATX_ATIME;
107 :
108 : /*
109 : * Note: If you add another clause to set an attribute flag, please
110 : * update attributes_mask below.
111 : */
112 0 : if (IS_AUTOMOUNT(inode))
113 0 : stat->attributes |= STATX_ATTR_AUTOMOUNT;
114 :
115 : if (IS_DAX(inode))
116 : stat->attributes |= STATX_ATTR_DAX;
117 :
118 0 : stat->attributes_mask |= (STATX_ATTR_AUTOMOUNT |
119 : STATX_ATTR_DAX);
120 :
121 0 : mnt_userns = mnt_user_ns(path->mnt);
122 0 : if (inode->i_op->getattr)
123 0 : return inode->i_op->getattr(mnt_userns, path, stat,
124 : request_mask, query_flags);
125 :
126 0 : generic_fillattr(mnt_userns, inode, stat);
127 0 : return 0;
128 : }
129 : EXPORT_SYMBOL(vfs_getattr_nosec);
130 :
131 : /*
132 : * vfs_getattr - Get the enhanced basic attributes of a file
133 : * @path: The file of interest
134 : * @stat: Where to return the statistics
135 : * @request_mask: STATX_xxx flags indicating what the caller wants
136 : * @query_flags: Query mode (AT_STATX_SYNC_TYPE)
137 : *
138 : * Ask the filesystem for a file's attributes. The caller must indicate in
139 : * request_mask and query_flags to indicate what they want.
140 : *
141 : * If the file is remote, the filesystem can be forced to update the attributes
142 : * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can
143 : * suppress the update by passing AT_STATX_DONT_SYNC.
144 : *
145 : * Bits must have been set in request_mask to indicate which attributes the
146 : * caller wants retrieving. Any such attribute not requested may be returned
147 : * anyway, but the value may be approximate, and, if remote, may not have been
148 : * synchronised with the server.
149 : *
150 : * 0 will be returned on success, and a -ve error code if unsuccessful.
151 : */
152 0 : int vfs_getattr(const struct path *path, struct kstat *stat,
153 : u32 request_mask, unsigned int query_flags)
154 : {
155 : int retval;
156 :
157 0 : retval = security_inode_getattr(path);
158 : if (retval)
159 : return retval;
160 0 : return vfs_getattr_nosec(path, stat, request_mask, query_flags);
161 : }
162 : EXPORT_SYMBOL(vfs_getattr);
163 :
164 : /**
165 : * vfs_fstat - Get the basic attributes by file descriptor
166 : * @fd: The file descriptor referring to the file of interest
167 : * @stat: The result structure to fill in.
168 : *
169 : * This function is a wrapper around vfs_getattr(). The main difference is
170 : * that it uses a file descriptor to determine the file location.
171 : *
172 : * 0 will be returned on success, and a -ve error code if unsuccessful.
173 : */
174 0 : int vfs_fstat(int fd, struct kstat *stat)
175 : {
176 : struct fd f;
177 : int error;
178 :
179 0 : f = fdget_raw(fd);
180 0 : if (!f.file)
181 : return -EBADF;
182 0 : error = vfs_getattr(&f.file->f_path, stat, STATX_BASIC_STATS, 0);
183 0 : fdput(f);
184 : return error;
185 : }
186 :
187 0 : int getname_statx_lookup_flags(int flags)
188 : {
189 0 : int lookup_flags = 0;
190 :
191 0 : if (!(flags & AT_SYMLINK_NOFOLLOW))
192 0 : lookup_flags |= LOOKUP_FOLLOW;
193 0 : if (!(flags & AT_NO_AUTOMOUNT))
194 0 : lookup_flags |= LOOKUP_AUTOMOUNT;
195 0 : if (flags & AT_EMPTY_PATH)
196 0 : lookup_flags |= LOOKUP_EMPTY;
197 :
198 0 : return lookup_flags;
199 : }
200 :
201 : /**
202 : * vfs_statx - Get basic and extra attributes by filename
203 : * @dfd: A file descriptor representing the base dir for a relative filename
204 : * @filename: The name of the file of interest
205 : * @flags: Flags to control the query
206 : * @stat: The result structure to fill in.
207 : * @request_mask: STATX_xxx flags indicating what the caller wants
208 : *
209 : * This function is a wrapper around vfs_getattr(). The main difference is
210 : * that it uses a filename and base directory to determine the file location.
211 : * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink
212 : * at the given name from being referenced.
213 : *
214 : * 0 will be returned on success, and a -ve error code if unsuccessful.
215 : */
216 0 : static int vfs_statx(int dfd, struct filename *filename, int flags,
217 : struct kstat *stat, u32 request_mask)
218 : {
219 : struct path path;
220 0 : unsigned int lookup_flags = getname_statx_lookup_flags(flags);
221 : int error;
222 :
223 0 : if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
224 : AT_STATX_SYNC_TYPE))
225 : return -EINVAL;
226 :
227 : retry:
228 0 : error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
229 0 : if (error)
230 : goto out;
231 :
232 0 : error = vfs_getattr(&path, stat, request_mask, flags);
233 0 : stat->mnt_id = real_mount(path.mnt)->mnt_id;
234 0 : stat->result_mask |= STATX_MNT_ID;
235 0 : if (path.mnt->mnt_root == path.dentry)
236 0 : stat->attributes |= STATX_ATTR_MOUNT_ROOT;
237 0 : stat->attributes_mask |= STATX_ATTR_MOUNT_ROOT;
238 0 : path_put(&path);
239 0 : if (retry_estale(error, lookup_flags)) {
240 0 : lookup_flags |= LOOKUP_REVAL;
241 0 : goto retry;
242 : }
243 : out:
244 : return error;
245 : }
246 :
247 0 : int vfs_fstatat(int dfd, const char __user *filename,
248 : struct kstat *stat, int flags)
249 : {
250 : int ret;
251 0 : int statx_flags = flags | AT_NO_AUTOMOUNT;
252 : struct filename *name;
253 :
254 0 : name = getname_flags(filename, getname_statx_lookup_flags(statx_flags), NULL);
255 0 : ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS);
256 0 : putname(name);
257 :
258 0 : return ret;
259 : }
260 :
261 : #ifdef __ARCH_WANT_OLD_STAT
262 :
263 : /*
264 : * For backward compatibility? Maybe this should be moved
265 : * into arch/i386 instead?
266 : */
267 0 : static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
268 : {
269 : static int warncount = 5;
270 : struct __old_kernel_stat tmp;
271 :
272 0 : if (warncount > 0) {
273 0 : warncount--;
274 0 : printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
275 : current->comm);
276 0 : } else if (warncount < 0) {
277 : /* it's laughable, but... */
278 0 : warncount = 0;
279 : }
280 :
281 0 : memset(&tmp, 0, sizeof(struct __old_kernel_stat));
282 0 : tmp.st_dev = old_encode_dev(stat->dev);
283 0 : tmp.st_ino = stat->ino;
284 0 : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
285 : return -EOVERFLOW;
286 0 : tmp.st_mode = stat->mode;
287 0 : tmp.st_nlink = stat->nlink;
288 0 : if (tmp.st_nlink != stat->nlink)
289 : return -EOVERFLOW;
290 0 : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
291 0 : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
292 0 : tmp.st_rdev = old_encode_dev(stat->rdev);
293 : #if BITS_PER_LONG == 32
294 : if (stat->size > MAX_NON_LFS)
295 : return -EOVERFLOW;
296 : #endif
297 0 : tmp.st_size = stat->size;
298 0 : tmp.st_atime = stat->atime.tv_sec;
299 0 : tmp.st_mtime = stat->mtime.tv_sec;
300 0 : tmp.st_ctime = stat->ctime.tv_sec;
301 0 : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
302 : }
303 :
304 0 : SYSCALL_DEFINE2(stat, const char __user *, filename,
305 : struct __old_kernel_stat __user *, statbuf)
306 : {
307 : struct kstat stat;
308 : int error;
309 :
310 0 : error = vfs_stat(filename, &stat);
311 0 : if (error)
312 0 : return error;
313 :
314 0 : return cp_old_stat(&stat, statbuf);
315 : }
316 :
317 0 : SYSCALL_DEFINE2(lstat, const char __user *, filename,
318 : struct __old_kernel_stat __user *, statbuf)
319 : {
320 : struct kstat stat;
321 : int error;
322 :
323 0 : error = vfs_lstat(filename, &stat);
324 0 : if (error)
325 0 : return error;
326 :
327 0 : return cp_old_stat(&stat, statbuf);
328 : }
329 :
330 0 : SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
331 : {
332 : struct kstat stat;
333 0 : int error = vfs_fstat(fd, &stat);
334 :
335 0 : if (!error)
336 0 : error = cp_old_stat(&stat, statbuf);
337 :
338 0 : return error;
339 : }
340 :
341 : #endif /* __ARCH_WANT_OLD_STAT */
342 :
343 : #ifdef __ARCH_WANT_NEW_STAT
344 :
345 : #if BITS_PER_LONG == 32
346 : # define choose_32_64(a,b) a
347 : #else
348 : # define choose_32_64(a,b) b
349 : #endif
350 :
351 : #ifndef INIT_STRUCT_STAT_PADDING
352 : # define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))
353 : #endif
354 :
355 0 : static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
356 : {
357 : struct stat tmp;
358 :
359 : if (sizeof(tmp.st_dev) < 4 && !old_valid_dev(stat->dev))
360 : return -EOVERFLOW;
361 : if (sizeof(tmp.st_rdev) < 4 && !old_valid_dev(stat->rdev))
362 : return -EOVERFLOW;
363 : #if BITS_PER_LONG == 32
364 : if (stat->size > MAX_NON_LFS)
365 : return -EOVERFLOW;
366 : #endif
367 :
368 0 : INIT_STRUCT_STAT_PADDING(tmp);
369 0 : tmp.st_dev = new_encode_dev(stat->dev);
370 0 : tmp.st_ino = stat->ino;
371 : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
372 : return -EOVERFLOW;
373 0 : tmp.st_mode = stat->mode;
374 0 : tmp.st_nlink = stat->nlink;
375 : if (tmp.st_nlink != stat->nlink)
376 : return -EOVERFLOW;
377 0 : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
378 0 : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
379 0 : tmp.st_rdev = new_encode_dev(stat->rdev);
380 0 : tmp.st_size = stat->size;
381 0 : tmp.st_atime = stat->atime.tv_sec;
382 0 : tmp.st_mtime = stat->mtime.tv_sec;
383 0 : tmp.st_ctime = stat->ctime.tv_sec;
384 : #ifdef STAT_HAVE_NSEC
385 0 : tmp.st_atime_nsec = stat->atime.tv_nsec;
386 0 : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
387 0 : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
388 : #endif
389 0 : tmp.st_blocks = stat->blocks;
390 0 : tmp.st_blksize = stat->blksize;
391 0 : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
392 : }
393 :
394 0 : SYSCALL_DEFINE2(newstat, const char __user *, filename,
395 : struct stat __user *, statbuf)
396 : {
397 : struct kstat stat;
398 0 : int error = vfs_stat(filename, &stat);
399 :
400 0 : if (error)
401 0 : return error;
402 0 : return cp_new_stat(&stat, statbuf);
403 : }
404 :
405 0 : SYSCALL_DEFINE2(newlstat, const char __user *, filename,
406 : struct stat __user *, statbuf)
407 : {
408 : struct kstat stat;
409 : int error;
410 :
411 0 : error = vfs_lstat(filename, &stat);
412 0 : if (error)
413 0 : return error;
414 :
415 0 : return cp_new_stat(&stat, statbuf);
416 : }
417 :
418 : #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
419 0 : SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
420 : struct stat __user *, statbuf, int, flag)
421 : {
422 : struct kstat stat;
423 : int error;
424 :
425 0 : error = vfs_fstatat(dfd, filename, &stat, flag);
426 0 : if (error)
427 0 : return error;
428 0 : return cp_new_stat(&stat, statbuf);
429 : }
430 : #endif
431 :
432 0 : SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
433 : {
434 : struct kstat stat;
435 0 : int error = vfs_fstat(fd, &stat);
436 :
437 0 : if (!error)
438 0 : error = cp_new_stat(&stat, statbuf);
439 :
440 0 : return error;
441 : }
442 : #endif
443 :
444 0 : static int do_readlinkat(int dfd, const char __user *pathname,
445 : char __user *buf, int bufsiz)
446 : {
447 : struct path path;
448 : int error;
449 0 : int empty = 0;
450 0 : unsigned int lookup_flags = LOOKUP_EMPTY;
451 :
452 0 : if (bufsiz <= 0)
453 : return -EINVAL;
454 :
455 : retry:
456 0 : error = user_path_at_empty(dfd, pathname, lookup_flags, &path, &empty);
457 0 : if (!error) {
458 0 : struct inode *inode = d_backing_inode(path.dentry);
459 :
460 0 : error = empty ? -ENOENT : -EINVAL;
461 : /*
462 : * AFS mountpoints allow readlink(2) but are not symlinks
463 : */
464 0 : if (d_is_symlink(path.dentry) || inode->i_op->readlink) {
465 0 : error = security_inode_readlink(path.dentry);
466 : if (!error) {
467 0 : touch_atime(&path);
468 0 : error = vfs_readlink(path.dentry, buf, bufsiz);
469 : }
470 : }
471 0 : path_put(&path);
472 0 : if (retry_estale(error, lookup_flags)) {
473 : lookup_flags |= LOOKUP_REVAL;
474 : goto retry;
475 : }
476 : }
477 : return error;
478 : }
479 :
480 0 : SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
481 : char __user *, buf, int, bufsiz)
482 : {
483 0 : return do_readlinkat(dfd, pathname, buf, bufsiz);
484 : }
485 :
486 0 : SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,
487 : int, bufsiz)
488 : {
489 0 : return do_readlinkat(AT_FDCWD, path, buf, bufsiz);
490 : }
491 :
492 :
493 : /* ---------- LFS-64 ----------- */
494 : #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
495 :
496 : #ifndef INIT_STRUCT_STAT64_PADDING
497 : # define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))
498 : #endif
499 :
500 : static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
501 : {
502 : struct stat64 tmp;
503 :
504 : INIT_STRUCT_STAT64_PADDING(tmp);
505 : #ifdef CONFIG_MIPS
506 : /* mips has weird padding, so we don't get 64 bits there */
507 : tmp.st_dev = new_encode_dev(stat->dev);
508 : tmp.st_rdev = new_encode_dev(stat->rdev);
509 : #else
510 : tmp.st_dev = huge_encode_dev(stat->dev);
511 : tmp.st_rdev = huge_encode_dev(stat->rdev);
512 : #endif
513 : tmp.st_ino = stat->ino;
514 : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
515 : return -EOVERFLOW;
516 : #ifdef STAT64_HAS_BROKEN_ST_INO
517 : tmp.__st_ino = stat->ino;
518 : #endif
519 : tmp.st_mode = stat->mode;
520 : tmp.st_nlink = stat->nlink;
521 : tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
522 : tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
523 : tmp.st_atime = stat->atime.tv_sec;
524 : tmp.st_atime_nsec = stat->atime.tv_nsec;
525 : tmp.st_mtime = stat->mtime.tv_sec;
526 : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
527 : tmp.st_ctime = stat->ctime.tv_sec;
528 : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
529 : tmp.st_size = stat->size;
530 : tmp.st_blocks = stat->blocks;
531 : tmp.st_blksize = stat->blksize;
532 : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
533 : }
534 :
535 : SYSCALL_DEFINE2(stat64, const char __user *, filename,
536 : struct stat64 __user *, statbuf)
537 : {
538 : struct kstat stat;
539 : int error = vfs_stat(filename, &stat);
540 :
541 : if (!error)
542 : error = cp_new_stat64(&stat, statbuf);
543 :
544 : return error;
545 : }
546 :
547 : SYSCALL_DEFINE2(lstat64, const char __user *, filename,
548 : struct stat64 __user *, statbuf)
549 : {
550 : struct kstat stat;
551 : int error = vfs_lstat(filename, &stat);
552 :
553 : if (!error)
554 : error = cp_new_stat64(&stat, statbuf);
555 :
556 : return error;
557 : }
558 :
559 : SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
560 : {
561 : struct kstat stat;
562 : int error = vfs_fstat(fd, &stat);
563 :
564 : if (!error)
565 : error = cp_new_stat64(&stat, statbuf);
566 :
567 : return error;
568 : }
569 :
570 : SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
571 : struct stat64 __user *, statbuf, int, flag)
572 : {
573 : struct kstat stat;
574 : int error;
575 :
576 : error = vfs_fstatat(dfd, filename, &stat, flag);
577 : if (error)
578 : return error;
579 : return cp_new_stat64(&stat, statbuf);
580 : }
581 : #endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */
582 :
583 : static noinline_for_stack int
584 0 : cp_statx(const struct kstat *stat, struct statx __user *buffer)
585 : {
586 : struct statx tmp;
587 :
588 0 : memset(&tmp, 0, sizeof(tmp));
589 :
590 0 : tmp.stx_mask = stat->result_mask;
591 0 : tmp.stx_blksize = stat->blksize;
592 0 : tmp.stx_attributes = stat->attributes;
593 0 : tmp.stx_nlink = stat->nlink;
594 0 : tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);
595 0 : tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);
596 0 : tmp.stx_mode = stat->mode;
597 0 : tmp.stx_ino = stat->ino;
598 0 : tmp.stx_size = stat->size;
599 0 : tmp.stx_blocks = stat->blocks;
600 0 : tmp.stx_attributes_mask = stat->attributes_mask;
601 0 : tmp.stx_atime.tv_sec = stat->atime.tv_sec;
602 0 : tmp.stx_atime.tv_nsec = stat->atime.tv_nsec;
603 0 : tmp.stx_btime.tv_sec = stat->btime.tv_sec;
604 0 : tmp.stx_btime.tv_nsec = stat->btime.tv_nsec;
605 0 : tmp.stx_ctime.tv_sec = stat->ctime.tv_sec;
606 0 : tmp.stx_ctime.tv_nsec = stat->ctime.tv_nsec;
607 0 : tmp.stx_mtime.tv_sec = stat->mtime.tv_sec;
608 0 : tmp.stx_mtime.tv_nsec = stat->mtime.tv_nsec;
609 0 : tmp.stx_rdev_major = MAJOR(stat->rdev);
610 0 : tmp.stx_rdev_minor = MINOR(stat->rdev);
611 0 : tmp.stx_dev_major = MAJOR(stat->dev);
612 0 : tmp.stx_dev_minor = MINOR(stat->dev);
613 0 : tmp.stx_mnt_id = stat->mnt_id;
614 :
615 0 : return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
616 : }
617 :
618 0 : int do_statx(int dfd, struct filename *filename, unsigned int flags,
619 : unsigned int mask, struct statx __user *buffer)
620 : {
621 : struct kstat stat;
622 : int error;
623 :
624 0 : if (mask & STATX__RESERVED)
625 : return -EINVAL;
626 0 : if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
627 : return -EINVAL;
628 :
629 0 : error = vfs_statx(dfd, filename, flags, &stat, mask);
630 0 : if (error)
631 : return error;
632 :
633 0 : return cp_statx(&stat, buffer);
634 : }
635 :
636 : /**
637 : * sys_statx - System call to get enhanced stats
638 : * @dfd: Base directory to pathwalk from *or* fd to stat.
639 : * @filename: File to stat or "" with AT_EMPTY_PATH
640 : * @flags: AT_* flags to control pathwalk.
641 : * @mask: Parts of statx struct actually required.
642 : * @buffer: Result buffer.
643 : *
644 : * Note that fstat() can be emulated by setting dfd to the fd of interest,
645 : * supplying "" as the filename and setting AT_EMPTY_PATH in the flags.
646 : */
647 0 : SYSCALL_DEFINE5(statx,
648 : int, dfd, const char __user *, filename, unsigned, flags,
649 : unsigned int, mask,
650 : struct statx __user *, buffer)
651 : {
652 : int ret;
653 : struct filename *name;
654 :
655 0 : name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL);
656 0 : ret = do_statx(dfd, name, flags, mask, buffer);
657 0 : putname(name);
658 :
659 0 : return ret;
660 : }
661 :
662 : #ifdef CONFIG_COMPAT
663 : static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
664 : {
665 : struct compat_stat tmp;
666 :
667 : if (sizeof(tmp.st_dev) < 4 && !old_valid_dev(stat->dev))
668 : return -EOVERFLOW;
669 : if (sizeof(tmp.st_rdev) < 4 && !old_valid_dev(stat->rdev))
670 : return -EOVERFLOW;
671 :
672 : memset(&tmp, 0, sizeof(tmp));
673 : tmp.st_dev = new_encode_dev(stat->dev);
674 : tmp.st_ino = stat->ino;
675 : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
676 : return -EOVERFLOW;
677 : tmp.st_mode = stat->mode;
678 : tmp.st_nlink = stat->nlink;
679 : if (tmp.st_nlink != stat->nlink)
680 : return -EOVERFLOW;
681 : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
682 : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
683 : tmp.st_rdev = new_encode_dev(stat->rdev);
684 : if ((u64) stat->size > MAX_NON_LFS)
685 : return -EOVERFLOW;
686 : tmp.st_size = stat->size;
687 : tmp.st_atime = stat->atime.tv_sec;
688 : tmp.st_atime_nsec = stat->atime.tv_nsec;
689 : tmp.st_mtime = stat->mtime.tv_sec;
690 : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
691 : tmp.st_ctime = stat->ctime.tv_sec;
692 : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
693 : tmp.st_blocks = stat->blocks;
694 : tmp.st_blksize = stat->blksize;
695 : return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
696 : }
697 :
698 : COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
699 : struct compat_stat __user *, statbuf)
700 : {
701 : struct kstat stat;
702 : int error;
703 :
704 : error = vfs_stat(filename, &stat);
705 : if (error)
706 : return error;
707 : return cp_compat_stat(&stat, statbuf);
708 : }
709 :
710 : COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
711 : struct compat_stat __user *, statbuf)
712 : {
713 : struct kstat stat;
714 : int error;
715 :
716 : error = vfs_lstat(filename, &stat);
717 : if (error)
718 : return error;
719 : return cp_compat_stat(&stat, statbuf);
720 : }
721 :
722 : #ifndef __ARCH_WANT_STAT64
723 : COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
724 : const char __user *, filename,
725 : struct compat_stat __user *, statbuf, int, flag)
726 : {
727 : struct kstat stat;
728 : int error;
729 :
730 : error = vfs_fstatat(dfd, filename, &stat, flag);
731 : if (error)
732 : return error;
733 : return cp_compat_stat(&stat, statbuf);
734 : }
735 : #endif
736 :
737 : COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
738 : struct compat_stat __user *, statbuf)
739 : {
740 : struct kstat stat;
741 : int error = vfs_fstat(fd, &stat);
742 :
743 : if (!error)
744 : error = cp_compat_stat(&stat, statbuf);
745 : return error;
746 : }
747 : #endif
748 :
749 : /* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
750 0 : void __inode_add_bytes(struct inode *inode, loff_t bytes)
751 : {
752 0 : inode->i_blocks += bytes >> 9;
753 0 : bytes &= 511;
754 0 : inode->i_bytes += bytes;
755 0 : if (inode->i_bytes >= 512) {
756 0 : inode->i_blocks++;
757 0 : inode->i_bytes -= 512;
758 : }
759 0 : }
760 : EXPORT_SYMBOL(__inode_add_bytes);
761 :
762 0 : void inode_add_bytes(struct inode *inode, loff_t bytes)
763 : {
764 0 : spin_lock(&inode->i_lock);
765 0 : __inode_add_bytes(inode, bytes);
766 0 : spin_unlock(&inode->i_lock);
767 0 : }
768 :
769 : EXPORT_SYMBOL(inode_add_bytes);
770 :
771 0 : void __inode_sub_bytes(struct inode *inode, loff_t bytes)
772 : {
773 0 : inode->i_blocks -= bytes >> 9;
774 0 : bytes &= 511;
775 0 : if (inode->i_bytes < bytes) {
776 0 : inode->i_blocks--;
777 0 : inode->i_bytes += 512;
778 : }
779 0 : inode->i_bytes -= bytes;
780 0 : }
781 :
782 : EXPORT_SYMBOL(__inode_sub_bytes);
783 :
784 0 : void inode_sub_bytes(struct inode *inode, loff_t bytes)
785 : {
786 0 : spin_lock(&inode->i_lock);
787 0 : __inode_sub_bytes(inode, bytes);
788 0 : spin_unlock(&inode->i_lock);
789 0 : }
790 :
791 : EXPORT_SYMBOL(inode_sub_bytes);
792 :
793 0 : loff_t inode_get_bytes(struct inode *inode)
794 : {
795 : loff_t ret;
796 :
797 0 : spin_lock(&inode->i_lock);
798 0 : ret = __inode_get_bytes(inode);
799 0 : spin_unlock(&inode->i_lock);
800 0 : return ret;
801 : }
802 :
803 : EXPORT_SYMBOL(inode_get_bytes);
804 :
805 0 : void inode_set_bytes(struct inode *inode, loff_t bytes)
806 : {
807 : /* Caller is here responsible for sufficient locking
808 : * (ie. inode->i_lock) */
809 0 : inode->i_blocks = bytes >> 9;
810 0 : inode->i_bytes = bytes & 511;
811 0 : }
812 :
813 : EXPORT_SYMBOL(inode_set_bytes);
|