this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Use Linux O_PATH flag for BSD O_SYMLINK

+15 -2
+6 -1
src/kernel/emulation/linux/fcntl/open.c
··· 17 17 #ifndef O_DIRECTORY 18 18 # define O_DIRECTORY 0x100000 19 19 #endif 20 + #ifndef LINUX_O_PATH 21 + #define LINUX_O_PATH 0x200000 22 + #endif 20 23 21 24 int oflags_bsd_to_linux(int flags); 22 25 ··· 55 58 linux_flags |= LINUX_O_EXCL; 56 59 if (flags & BSD_O_CLOEXEC) 57 60 linux_flags |= LINUX_O_CLOEXEC; 58 - if (flags & BSD_O_NOFOLLOW) 61 + if (flags & BSD_O_NOFOLLOW || flags & BSD_O_SYMLINK) 59 62 linux_flags |= LINUX_O_NOFOLLOW; 60 63 if (flags & BSD_O_DIRECTORY) 61 64 linux_flags |= LINUX_O_DIRECTORY; ··· 63 66 linux_flags |= LINUX_O_CLOEXEC; 64 67 if (flags & BSD_O_NOCTTY) 65 68 linux_flags |= LINUX_O_NOCTTY; 69 + if (flags & BSD_O_SYMLINK) 70 + linux_flags |= LINUX_O_PATH; 66 71 67 72 return linux_flags; 68 73 }
+9 -1
src/kernel/emulation/linux/fcntl/openat.c
··· 51 51 filename = "/dev/null"; 52 52 53 53 struct vchroot_expand_args vc; 54 - vc.flags = VCHROOT_FOLLOW; 54 + vc.flags = (flags & BSD_O_SYMLINK || flags & BSD_O_NOFOLLOW) ? 0 : VCHROOT_FOLLOW; 55 55 vc.dfd = atfd(fd); 56 56 57 57 strcpy(vc.path, filename); ··· 59 59 if (ret < 0) { 60 60 return errno_linux_to_bsd(ret); 61 61 } 62 + 63 + // when we're given O_SYMLINK, `oflags_bsd_to_linux` translates it into 64 + // O_NOFOLLOW and O_PATH 65 + // this is the only way to open the symlink itself on Linux 66 + // unfortunately, this presents additional challenges 67 + // only a select few Linux syscalls support O_PATH descriptors, which means 68 + // that for other syscalls, we either have to check for this and use an 69 + // `l` variant (e.g. `llistxattr` instead of `listxatrr`) or we're screwed 62 70 63 71 ret = LINUX_SYSCALL(__NR_openat, vc.dfd, vc.path, linux_flags, mode); 64 72 if (ret < 0)