]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/vfscore: Change faccessat with AT_SYMLINK_NOFOLLOW
authorRobert Zamfir <georobi.016@gmail.com>
Mon, 14 Oct 2024 18:51:25 +0000 (21:51 +0300)
committerUnikraft Bot <monkey@unikraft.io>
Fri, 1 Nov 2024 14:54:58 +0000 (14:54 +0000)
* Change faccessat with AT_SYMLINK_NOFOLLOW
* Move the path creation and logic before the AT_SYMLINK_NOFOLLOW
* Apply AT_SYMLINK_NOFOLLOW only if the file is an actual symlink
* I didn't implement the `don't follow link logic`

Checkpatch-Ignore: LONG_LINE_STRING
Checkpatch-Ignore: STRLCPY
Signed-off-by: Robert Zamfir <georobi.016@gmail.com>
Reviewed-by: Mihnea Firoiu <mihneafiroiu0@gmail.com>
Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com>
Approved-by: Andrei Tatar <andrei@unikraft.io>
GitHub-Closes: #1462

lib/vfscore/main.c

index 7a3f2e1349776b8090f9874d72c09d691b1e1787..718ea7410b98648420b0c425ffd7df4a8d34a14b 100644 (file)
@@ -2061,37 +2061,47 @@ UK_SYSCALL_R_DEFINE(int, access, const char*, pathname, int, mode)
 
 UK_SYSCALL_R_DEFINE(int, faccessat, int, dirfd, const char*, pathname, int, mode, int, flags)
 {
-       if (flags & AT_SYMLINK_NOFOLLOW) {
-               UK_CRASH("UNIMPLEMENTED: faccessat() with AT_SYMLINK_NOFOLLOW");
-       }
+       char tmp[PATH_MAX];
+       const char *p;
+       struct vfscore_file *fp;
+       int error;
 
-       if (pathname[0] == '/' || dirfd == AT_FDCWD) {
-               return uk_syscall_r_access((long) pathname, (long) mode);
-       }
+       if (pathname[0] == '/' ||
+           dirfd == AT_FDCWD) {        /* Full path inside pathname */
+               p = pathname;
+       } else { /* Create Relative Path */
+               error = fget(dirfd, &fp);
+               if (error)
+                       goto out_error;
 
-       struct vfscore_file *fp;
-       int error = fget(dirfd, &fp);
-       if (error) {
-               goto out_error;
-       }
+               struct vnode *vp = fp->f_dentry->d_vnode;
 
-       struct vnode *vp = fp->f_dentry->d_vnode;
-       vn_lock(vp);
+               vn_lock(vp);
 
-       char p[PATH_MAX];
+               /* build absolute path */
+               strlcpy(tmp, fp->f_dentry->d_mount->m_path, PATH_MAX);
+               strlcat(tmp, fp->f_dentry->d_path, PATH_MAX);
+               strlcat(tmp, "/", PATH_MAX);
+               strlcat(tmp, pathname, PATH_MAX);
 
-       /* build absolute path */
-       strlcpy(p, fp->f_dentry->d_mount->m_path, PATH_MAX);
-       strlcat(p, fp->f_dentry->d_path, PATH_MAX);
-       strlcat(p, "/", PATH_MAX);
-       strlcat(p, pathname, PATH_MAX);
+               vn_unlock(vp);
+               fdrop(fp);
 
-       vn_unlock(vp);
-       fdrop(fp);
+               p = tmp;
+       }
 
-       error = uk_syscall_r_access((long) p, (long) mode);
+       if (flags & AT_SYMLINK_NOFOLLOW) {
+               struct stat st;
 
-       out_error:
+               error = uk_syscall_r_lstat((long)p, (long)&st);
+               /* Check if the file is an actual symlink */
+               if (error == 0 && S_ISLNK(st.st_mode))
+                       UK_CRASH("UNIMPLEMENTED: faccessat() with AT_SYMLINK_NOFOLLOW\n");
+       }
+
+       error = uk_syscall_r_access((long)p, (long)mode);
+
+out_error:
        return error;
 }