From: Andrei Tatar Date: Thu, 6 Feb 2025 15:38:57 +0000 (+0100) Subject: lib/posix-fdio: Adopt fch* syscalls from vfscore X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f2d91e671643853cf8eb9217780592286b5b4bee;p=unikraft%2Funikraft.git lib/posix-fdio: Adopt fch* syscalls from vfscore This change moves the implementation of the fchmod and fchown syscalls from vfscore to posix-fdio, allowing shim operation on both ukfiles and legacy vfscore files. In addition, this move fixes a file ref leak in vfscore's fchmod due to a missing fdrop after fd lookup. Signed-off-by: Andrei Tatar Approved-by: Sergiu Moga Reviewed-by: Sergiu Moga GitHub-Closes: #1581 --- diff --git a/lib/posix-fdio/Makefile.uk b/lib/posix-fdio/Makefile.uk index ec299602d..0fd0b12e4 100644 --- a/lib/posix-fdio/Makefile.uk +++ b/lib/posix-fdio/Makefile.uk @@ -22,6 +22,8 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += write-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += lseek-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += fstat-2 +UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += fchmod-2 +UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += fchown-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += fsync-1 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDIO) += fdatasync-1 diff --git a/lib/posix-fdio/fd-shim.c b/lib/posix-fdio/fd-shim.c index 1bb008d34..7fb073308 100644 --- a/lib/posix-fdio/fd-shim.c +++ b/lib/posix-fdio/fd-shim.c @@ -322,6 +322,52 @@ UK_SYSCALL_R_DEFINE(int, fstat, int, fd, struct stat *, statbuf) return r; } +UK_SYSCALL_R_DEFINE(int, fchmod, int, fd, mode_t, mode) +{ + int r; + union uk_shim_file sf; + + switch (uk_fdtab_shim_get(fd, &sf)) { + case UK_SHIM_OFILE: + r = uk_sys_fchmod(sf.ofile, mode); + uk_fdtab_ret(sf.ofile); + break; +#if CONFIG_LIBVFSCORE + case UK_SHIM_LEGACY: + /* vfscore_fchmod returns positive error codes */ + r = -vfscore_fchmod(sf.vfile, mode); + fdrop(sf.vfile); + break; +#endif /* CONFIG_LIBVFSCORE */ + default: + r = -EBADF; + } + return r; +} + +UK_SYSCALL_R_DEFINE(int, fchown, int, fd, uid_t, owner, gid_t, group) +{ + int r; + union uk_shim_file sf; + + switch (uk_fdtab_shim_get(fd, &sf)) { + case UK_SHIM_OFILE: + r = uk_sys_fchown(sf.ofile, owner, group); + uk_fdtab_ret(sf.ofile); + break; +#if CONFIG_LIBVFSCORE + case UK_SHIM_LEGACY: + /* vfscore does not support fchown; stub out */ + fdrop(sf.vfile); + r = 0; + break; +#endif /* CONFIG_LIBVFSCORE */ + default: + r = -EBADF; + } + return r; +} + /* Ctl */ UK_SYSCALL_R_DEFINE(int, fsync, int, fd) diff --git a/lib/vfscore/Makefile.uk b/lib/vfscore/Makefile.uk index 0165d7ed3..85f8475b8 100644 --- a/lib/vfscore/Makefile.uk +++ b/lib/vfscore/Makefile.uk @@ -32,7 +32,6 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += faccessat-4 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += chdir-1 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fchdir-1 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += chmod-2 -UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fchmod-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += utime-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += utimes-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += mknod-3 @@ -49,7 +48,6 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += sync-0 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += mount-5 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += statfs-2 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fstatfs-2 -UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fchown-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += lchown-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += chown-3 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += stat-2 diff --git a/lib/vfscore/exportsyms.uk b/lib/vfscore/exportsyms.uk index 2b045078b..87ba23a09 100644 --- a/lib/vfscore/exportsyms.uk +++ b/lib/vfscore/exportsyms.uk @@ -48,12 +48,6 @@ uk_syscall_r_stat chmod uk_syscall_e_chmod uk_syscall_r_chmod -fchmod -uk_syscall_e_fchmod -uk_syscall_r_fchmod -fchown -uk_syscall_e_fchown -uk_syscall_r_fchown dup uk_syscall_e_dup uk_syscall_r_dup @@ -264,5 +258,6 @@ vfscore_fsync vfscore_ftruncate vfscore_fallocate vfscore_fstat +vfscore_fchmod vfscore_fcntl vfscore_ioctl diff --git a/lib/vfscore/include/vfscore/syscalls.h b/lib/vfscore/include/vfscore/syscalls.h index 3b7766b53..0467fff0e 100644 --- a/lib/vfscore/include/vfscore/syscalls.h +++ b/lib/vfscore/include/vfscore/syscalls.h @@ -29,6 +29,7 @@ ssize_t vfscore_write(struct vfscore_file *fp, const void *buf, size_t count); int vfscore_lseek(struct vfscore_file *fp, off_t off, int type, off_t *origin); int vfscore_fstat(struct vfscore_file *fp, struct stat *st); +int vfscore_fchmod(struct vfscore_file *fp, mode_t mode); int vfscore_fsync(struct vfscore_file *fp); diff --git a/lib/vfscore/main.c b/lib/vfscore/main.c index 4e72dbab6..bee76756a 100644 --- a/lib/vfscore/main.c +++ b/lib/vfscore/main.c @@ -2363,32 +2363,6 @@ out_error: return -error; } -UK_TRACEPOINT(trace_vfs_fchmod, "\"%d\" 0%0o", int, mode_t); -UK_TRACEPOINT(trace_vfs_fchmod_ret, ""); - -UK_SYSCALL_R_DEFINE(int, fchmod, int, fd, mode_t, mode) -{ - trace_vfs_fchmod(fd, mode); - int error = sys_fchmod(fd, mode & UK_ALLPERMS); - trace_vfs_fchmod_ret(); - if (error) { - return -error; - } - - return 0; -} - -UK_TRACEPOINT(trace_vfs_fchown, "\"%d\" %d %d", int, uid_t, gid_t); -UK_TRACEPOINT(trace_vfs_fchown_ret, ""); - -UK_SYSCALL_R_DEFINE(int, fchown, int, fd, uid_t, owner, gid_t, group) -{ - trace_vfs_fchown(fd, owner, group); - UK_WARN_STUBBED(); - trace_vfs_fchown_ret(); - return 0; -} - UK_SYSCALL_R_DEFINE(int, chown, const char*, path, uid_t, owner, gid_t, group) { UK_WARN_STUBBED(); diff --git a/lib/vfscore/syscalls.c b/lib/vfscore/syscalls.c index e72df7f1d..5b6e2570b 100644 --- a/lib/vfscore/syscalls.c +++ b/lib/vfscore/syscalls.c @@ -1570,11 +1570,8 @@ sys_chmod(const char *path, mode_t mode) } int -sys_fchmod(int fd, mode_t mode) +vfscore_fchmod(struct vfscore_file *f, mode_t mode) { - struct vfscore_file *f = vfscore_get_file(fd); - if (!f) - return EBADF; // Posix is ambivalent on what fchmod() should do on an fd that does not // refer to a real file. It suggests an implementation may (but not must) // fail EINVAL on a pipe, can behave in an "unspecified" manner on a @@ -1586,6 +1583,6 @@ sys_fchmod(int fd, mode_t mode) if (f->f_dentry->d_mount->m_flags & MNT_RDONLY) { return EROFS; } else { - return vn_setmode(f->f_dentry->d_vnode, mode); + return vn_setmode(f->f_dentry->d_vnode, mode & UK_ALLPERMS); } } diff --git a/lib/vfscore/vfs.h b/lib/vfscore/vfs.h index b726b20bb..c4db5ac02 100644 --- a/lib/vfscore/vfs.h +++ b/lib/vfscore/vfs.h @@ -517,19 +517,6 @@ void sync(void); */ int sys_chmod(const char *path, mode_t mode); -/** - * Changes mode of the file specified by the open file descriptor fd. - * - * @param fd - * An open file descriptor - * @param mode - * The new file mode - * @return - * - (0): Completed successfully - * - (<0): Negative value with error code - */ -int sys_fchmod(int fd, mode_t mode); - /** * Converts to full path from the cwd of task and path. *