]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/vfscore: Exit sys_utimensat on all UTIME_OMIT
authorMarc Rittinghaus <marc.rittinghaus@unikraft.io>
Mon, 24 Apr 2023 15:12:07 +0000 (17:12 +0200)
committerUnikraft <monkey@unikraft.io>
Tue, 2 May 2023 20:19:25 +0000 (20:19 +0000)
This commit restructures the sanity checks of the input timespecs
to come before all other checks and to include an early exit of
both times are UTIME_OMIT. This is inline with the behavior on
Linux.

Signed-off-by: Marc Rittinghaus <marc.rittinghaus@unikraft.io>
Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com>
Reviewed-by: Rares Miculescu <miculescur@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #865

lib/vfscore/syscalls.c

index d85c08f55b2f02a8e9685f12971306abb75a9984..f02c12333721d7018647c1917ae3d69bf86ffa68 100644 (file)
@@ -1401,19 +1401,31 @@ sys_utimensat(int dirfd, const char *pathname, const struct timespec times[2], i
        struct dentry *dp = NULL;
        struct vfscore_file *fp = NULL;
 
+       if (times) {
+               /* Make the behavior compatible with Linux */
+               if (unlikely(times[0].tv_nsec == UTIME_OMIT &&
+                            times[1].tv_nsec == UTIME_OMIT))
+                       return 0;
+
+               if (unlikely(!is_timespec_valid(&times[0]) ||
+                            !is_timespec_valid(&times[1])))
+                       return EINVAL;
+
+               init_timespec(&timespec_times[0], times + 0);
+               init_timespec(&timespec_times[1], times + 1);
+       } else {
+               init_timespec(&timespec_times[0], NULL);
+               init_timespec(&timespec_times[1], NULL);
+       }
+
        /* utimensat should return ENOENT when pathname is empty */
        if(pathname && pathname[0] == 0)
                return ENOENT;
 
+       /* Only the AT_SYMLINK_NOFOLLOW is allowed */
        if (flags && !(flags & AT_SYMLINK_NOFOLLOW))
                return EINVAL;
 
-       if (times && (!is_timespec_valid(&times[0]) || !is_timespec_valid(&times[1])))
-               return EINVAL;
-
-       init_timespec(&timespec_times[0], times ? times + 0 : NULL);
-       init_timespec(&timespec_times[1], times ? times + 1 : NULL);
-
        if (pathname && pathname[0] == '/') {
                ap = strdup(pathname);
                if (!ap)