b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 2) #include <linux/file.h>
74f9fdfa1f229 (Dave Hansen 2008-02-15 14:37:42 -0800 3) #include <linux/mount.h>
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 4) #include <linux/namei.h>
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 5) #include <linux/utime.h>
12c2ab5e8fdfd (Adrian Bunk 2008-02-06 01:36:47 -0800 6) #include <linux/syscalls.h>
7c0f6ba682b9c (Linus Torvalds 2016-12-24 11:46:01 -0800 7) #include <linux/uaccess.h>
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 8) #include <linux/compat.h>
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 9) #include <asm/unistd.h>
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 10)
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 11) static bool nsec_valid(long nsec)
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 12) {
4cca92264e61a (Michael Kerrisk 2008-06-09 21:16:08 -0700 13) if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 14) return true;
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 15)
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 16) return nsec >= 0 && nsec <= 999999999;
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 17) }
043f46f6151df (Miklos Szeredi 2007-10-16 23:27:07 -0700 18)
fd5ad30c78235 (Christoph Hellwig 2020-07-15 08:19:55 +0200 19) int vfs_utimes(const struct path *path, struct timespec64 *times)
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 20) {
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 21) int error;
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 22) struct iattr newattrs;
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 23) struct inode *inode = path->dentry->d_inode;
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 24) struct inode *delegated_inode = NULL;
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 25)
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 26) if (times) {
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 27) if (!nsec_valid(times[0].tv_nsec) ||
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 28) !nsec_valid(times[1].tv_nsec))
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 29) return -EINVAL;
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 30) if (times[0].tv_nsec == UTIME_NOW &&
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 31) times[1].tv_nsec == UTIME_NOW)
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 32) times = NULL;
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 33) }
27eb11c9632c6 (Christoph Hellwig 2020-07-15 08:15:36 +0200 34)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 35) error = mnt_want_write(path->mnt);
74f9fdfa1f229 (Dave Hansen 2008-02-15 14:37:42 -0800 36) if (error)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 37) goto out;
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 38)
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 39) newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 40) if (times) {
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 41) if (times[0].tv_nsec == UTIME_OMIT)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 42) newattrs.ia_valid &= ~ATTR_ATIME;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 43) else if (times[0].tv_nsec != UTIME_NOW) {
eb31e2f63d85d (Amir Goldstein 2019-11-24 21:31:45 +0200 44) newattrs.ia_atime = times[0];
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 45) newattrs.ia_valid |= ATTR_ATIME_SET;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 46) }
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 47)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 48) if (times[1].tv_nsec == UTIME_OMIT)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 49) newattrs.ia_valid &= ~ATTR_MTIME;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 50) else if (times[1].tv_nsec != UTIME_NOW) {
eb31e2f63d85d (Amir Goldstein 2019-11-24 21:31:45 +0200 51) newattrs.ia_mtime = times[1];
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 52) newattrs.ia_valid |= ATTR_MTIME_SET;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 53) }
4cca92264e61a (Michael Kerrisk 2008-06-09 21:16:08 -0700 54) /*
31051c85b5e2a (Jan Kara 2016-05-26 16:55:18 +0200 55) * Tell setattr_prepare(), that this is an explicit time
9767d74957450 (Miklos Szeredi 2008-07-01 15:01:26 +0200 56) * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
9767d74957450 (Miklos Szeredi 2008-07-01 15:01:26 +0200 57) * were used.
4cca92264e61a (Michael Kerrisk 2008-06-09 21:16:08 -0700 58) */
9767d74957450 (Miklos Szeredi 2008-07-01 15:01:26 +0200 59) newattrs.ia_valid |= ATTR_TIMES_SET;
4cca92264e61a (Michael Kerrisk 2008-06-09 21:16:08 -0700 60) } else {
f2b20f6ee8423 (Miklos Szeredi 2016-09-16 12:44:20 +0200 61) newattrs.ia_valid |= ATTR_TOUCH;
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 62) }
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 63) retry_deleg:
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 64) inode_lock(inode);
d06c26f196dd5 (Christian Brauner 2021-01-21 14:19:37 +0100 65) error = notify_change(mnt_user_ns(path->mnt), path->dentry, &newattrs,
2f221d6f7b881 (Christian Brauner 2021-01-21 14:19:26 +0100 66) &delegated_inode);
5955102c9984f (Al Viro 2016-01-22 15:40:57 -0500 67) inode_unlock(inode);
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 68) if (delegated_inode) {
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 69) error = break_deleg_wait(&delegated_inode);
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 70) if (!error)
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 71) goto retry_deleg;
27ac0ffeac80b (J. Bruce Fields 2011-09-20 17:19:26 -0400 72) }
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 73)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 74) mnt_drop_write(path->mnt);
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 75) out:
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 76) return error;
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 77) }
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 78)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 79) static int do_utimes_path(int dfd, const char __user *filename,
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 80) struct timespec64 *times, int flags)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 81) {
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 82) struct path path;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 83) int lookup_flags = 0, error;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 84)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 85) if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 86) return -EINVAL;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 87)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 88) if (!(flags & AT_SYMLINK_NOFOLLOW))
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 89) lookup_flags |= LOOKUP_FOLLOW;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 90) if (flags & AT_EMPTY_PATH)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 91) lookup_flags |= LOOKUP_EMPTY;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 92)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 93) retry:
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 94) error = user_path_at(dfd, filename, lookup_flags, &path);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 95) if (error)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 96) return error;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 97)
fd5ad30c78235 (Christoph Hellwig 2020-07-15 08:19:55 +0200 98) error = vfs_utimes(&path, times);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 99) path_put(&path);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 100) if (retry_estale(error, lookup_flags)) {
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 101) lookup_flags |= LOOKUP_REVAL;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 102) goto retry;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 103) }
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 104)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 105) return error;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 106) }
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 107)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 108) static int do_utimes_fd(int fd, struct timespec64 *times, int flags)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 109) {
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 110) struct fd f;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 111) int error;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 112)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 113) if (flags)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 114) return -EINVAL;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 115)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 116) f = fdget(fd);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 117) if (!f.file)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 118) return -EBADF;
fd5ad30c78235 (Christoph Hellwig 2020-07-15 08:19:55 +0200 119) error = vfs_utimes(&f.file->f_path, times);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 120) fdput(f);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 121) return error;
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 122) }
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 123)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 124) /*
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 125) * do_utimes - change times on filename or file descriptor
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 126) * @dfd: open file descriptor, -1 or AT_FDCWD
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 127) * @filename: path name or NULL
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 128) * @times: new times or NULL
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 129) * @flags: zero or more flags (only AT_SYMLINK_NOFOLLOW for the moment)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 130) *
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 131) * If filename is NULL and dfd refers to an open file, then operate on
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 132) * the file. Otherwise look up filename, possibly using dfd as a
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 133) * starting point.
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 134) *
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 135) * If times==NULL, set access and modification to current time,
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 136) * must be owner or have write permission.
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 137) * Else, update from *times, must be owner or super user.
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 138) */
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 139) long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
c7887325230ae (David Howells 2010-08-11 11:26:22 +0100 140) int flags)
e9b76fedc6123 (Miklos Szeredi 2008-07-01 15:01:27 +0200 141) {
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 142) if (filename == NULL && dfd != AT_FDCWD)
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 143) return do_utimes_fd(dfd, times, flags);
9d4b74aee8043 (Christoph Hellwig 2020-06-07 18:26:37 +0200 144) return do_utimes_path(dfd, filename, times, flags);
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 145) }
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 146)
c7887325230ae (David Howells 2010-08-11 11:26:22 +0100 147) SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
a4f7a3004630f (Arnd Bergmann 2018-04-17 09:11:58 +0200 148) struct __kernel_timespec __user *, utimes, int, flags)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 149) {
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 150) struct timespec64 tstimes[2];
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 151)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 152) if (utimes) {
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 153) if ((get_timespec64(&tstimes[0], &utimes[0]) ||
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 154) get_timespec64(&tstimes[1], &utimes[1])))
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 155) return -EFAULT;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 156)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 157) /* Nothing to do, we must not even check the path. */
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 158) if (tstimes[0].tv_nsec == UTIME_OMIT &&
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 159) tstimes[1].tv_nsec == UTIME_OMIT)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 160) return 0;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 161) }
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 162)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 163) return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags);
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 164) }
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 165)
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 166) #ifdef __ARCH_WANT_SYS_UTIME
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 167) /*
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 168) * futimesat(), utimes() and utime() are older versions of utimensat()
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 169) * that are provided for compatibility with traditional C libraries.
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 170) * On modern architectures, we always use libc wrappers around
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 171) * utimensat() instead.
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 172) */
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 173) static long do_futimesat(int dfd, const char __user *filename,
75d319c06e6a7 (Arnd Bergmann 2019-10-25 22:56:17 +0200 174) struct __kernel_old_timeval __user *utimes)
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 175) {
75d319c06e6a7 (Arnd Bergmann 2019-10-25 22:56:17 +0200 176) struct __kernel_old_timeval times[2];
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 177) struct timespec64 tstimes[2];
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 178)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 179) if (utimes) {
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 180) if (copy_from_user(×, utimes, sizeof(times)))
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 181) return -EFAULT;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 182)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 183) /* This test is needed to catch all invalid values. If we
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 184) would test only in do_utimes we would miss those invalid
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 185) values truncated by the multiplication with 1000. Note
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 186) that we also catch UTIME_{NOW,OMIT} here which are only
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 187) valid for utimensat. */
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 188) if (times[0].tv_usec >= 1000000 || times[0].tv_usec < 0 ||
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 189) times[1].tv_usec >= 1000000 || times[1].tv_usec < 0)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 190) return -EINVAL;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 191)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 192) tstimes[0].tv_sec = times[0].tv_sec;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 193) tstimes[0].tv_nsec = 1000 * times[0].tv_usec;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 194) tstimes[1].tv_sec = times[1].tv_sec;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 195) tstimes[1].tv_nsec = 1000 * times[1].tv_usec;
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 196) }
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 197)
1c710c896eb46 (Ulrich Drepper 2007-05-08 00:33:25 -0700 198) return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0);
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 199) }
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 200)
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 201)
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 202) SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
75d319c06e6a7 (Arnd Bergmann 2019-10-25 22:56:17 +0200 203) struct __kernel_old_timeval __user *, utimes)
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 204) {
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 205) return do_futimesat(dfd, filename, utimes);
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 206) }
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 207)
003d7ab479168 (Heiko Carstens 2009-01-14 14:14:21 +0100 208) SYSCALL_DEFINE2(utimes, char __user *, filename,
75d319c06e6a7 (Arnd Bergmann 2019-10-25 22:56:17 +0200 209) struct __kernel_old_timeval __user *, utimes)
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 210) {
f13903587c189 (Dominik Brodowski 2018-03-11 11:34:29 +0100 211) return do_futimesat(AT_FDCWD, filename, utimes);
82b0547cfae1f (Alexey Dobriyan 2006-09-30 23:27:22 -0700 212) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 213)
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 214) SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 215) {
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 216) struct timespec64 tv[2];
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 217)
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 218) if (times) {
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 219) if (get_user(tv[0].tv_sec, ×->actime) ||
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 220) get_user(tv[1].tv_sec, ×->modtime))
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 221) return -EFAULT;
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 222) tv[0].tv_nsec = 0;
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 223) tv[1].tv_nsec = 0;
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 224) }
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 225) return do_utimes(AT_FDCWD, filename, times ? tv : NULL, 0);
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 226) }
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 227) #endif
185cfaf7641e1 (Arnd Bergmann 2018-04-17 09:11:58 +0200 228)
4faea239e529d (Arnd Bergmann 2018-04-17 12:03:19 +0200 229) #ifdef CONFIG_COMPAT_32BIT_TIME
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 230) /*
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 231) * Not all architectures have sys_utime, so implement this in terms
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 232) * of sys_utimes.
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 233) */
4faea239e529d (Arnd Bergmann 2018-04-17 12:03:19 +0200 234) #ifdef __ARCH_WANT_SYS_UTIME32
8dabe7245bbc1 (Arnd Bergmann 2019-01-07 00:33:08 +0100 235) SYSCALL_DEFINE2(utime32, const char __user *, filename,
8dabe7245bbc1 (Arnd Bergmann 2019-01-07 00:33:08 +0100 236) struct old_utimbuf32 __user *, t)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 237) {
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 238) struct timespec64 tv[2];
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 239)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 240) if (t) {
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 241) if (get_user(tv[0].tv_sec, &t->actime) ||
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 242) get_user(tv[1].tv_sec, &t->modtime))
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 243) return -EFAULT;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 244) tv[0].tv_nsec = 0;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 245) tv[1].tv_nsec = 0;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 246) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 247) return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 248) }
4faea239e529d (Arnd Bergmann 2018-04-17 12:03:19 +0200 249) #endif
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 250)
8dabe7245bbc1 (Arnd Bergmann 2019-01-07 00:33:08 +0100 251) SYSCALL_DEFINE4(utimensat_time32, unsigned int, dfd, const char __user *, filename, struct old_timespec32 __user *, t, int, flags)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 252) {
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 253) struct timespec64 tv[2];
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 254)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 255) if (t) {
9afc5eee65ca7 (Arnd Bergmann 2018-07-13 12:52:28 +0200 256) if (get_old_timespec32(&tv[0], &t[0]) ||
9afc5eee65ca7 (Arnd Bergmann 2018-07-13 12:52:28 +0200 257) get_old_timespec32(&tv[1], &t[1]))
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 258) return -EFAULT;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 259)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 260) if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 261) return 0;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 262) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 263) return do_utimes(dfd, filename, t ? tv : NULL, flags);
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 264) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 265)
4faea239e529d (Arnd Bergmann 2018-04-17 12:03:19 +0200 266) #ifdef __ARCH_WANT_SYS_UTIME32
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 267) static long do_compat_futimesat(unsigned int dfd, const char __user *filename,
9afc5eee65ca7 (Arnd Bergmann 2018-07-13 12:52:28 +0200 268) struct old_timeval32 __user *t)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 269) {
aaed2dd8a3135 (Deepa Dinamani 2017-08-02 19:51:15 -0700 270) struct timespec64 tv[2];
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 271)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 272) if (t) {
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 273) if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 274) get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 275) get_user(tv[1].tv_sec, &t[1].tv_sec) ||
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 276) get_user(tv[1].tv_nsec, &t[1].tv_usec))
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 277) return -EFAULT;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 278) if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 279) tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 280) return -EINVAL;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 281) tv[0].tv_nsec *= 1000;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 282) tv[1].tv_nsec *= 1000;
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 283) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 284) return do_utimes(dfd, filename, t ? tv : NULL, 0);
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 285) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 286)
8dabe7245bbc1 (Arnd Bergmann 2019-01-07 00:33:08 +0100 287) SYSCALL_DEFINE3(futimesat_time32, unsigned int, dfd,
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 288) const char __user *, filename,
9afc5eee65ca7 (Arnd Bergmann 2018-07-13 12:52:28 +0200 289) struct old_timeval32 __user *, t)
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 290) {
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 291) return do_compat_futimesat(dfd, filename, t);
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 292) }
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 293)
8dabe7245bbc1 (Arnd Bergmann 2019-01-07 00:33:08 +0100 294) SYSCALL_DEFINE2(utimes_time32, const char __user *, filename, struct old_timeval32 __user *, t)
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 295) {
ab641afa73fbc (Dominik Brodowski 2018-03-20 19:39:44 +0100 296) return do_compat_futimesat(AT_FDCWD, filename, t);
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 297) }
1a060ba3c862b (Al Viro 2017-04-08 18:04:59 -0400 298) #endif
4faea239e529d (Arnd Bergmann 2018-04-17 12:03:19 +0200 299) #endif