From 4f5ed463b5343cc560c5ed7994484102394b8412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 30 Jun 2018 15:27:11 +0200 Subject: [PATCH] kernel: vfs: common_fcntl() now uses memcpy() for kernel calls. instead of user_memcpy(). * fix #14204: the NTFS filesystem kernel addon uses the fcntl system call to lock the underlying device. The user_memcpy replacement in the x86 compat branch adds range checks for the user pointer, which exposes such problems. --- src/system/kernel/fs/vfs.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 4f1657a55c..9c5f3962c0 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -6116,10 +6116,11 @@ common_fcntl(int fd, int op, size_t argument, bool kernel) if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) { if (descriptor->type != FDTYPE_FILE) status = B_BAD_VALUE; + else if (kernel) + memcpy(&flock, (struct flock*)argument, sizeof(struct flock)); else if (user_memcpy(&flock, (struct flock*)argument, sizeof(struct flock)) != B_OK) status = B_BAD_ADDRESS; - if (status != B_OK) { put_fd(descriptor); return status; @@ -6208,16 +6209,26 @@ common_fcntl(int fd, int op, size_t argument, bool kernel) // no conflicting lock found, copy back the same struct // we were given except change type to F_UNLCK flock.l_type = F_UNLCK; - status = user_memcpy((struct flock*)argument, &flock, - sizeof(struct flock)); + if (kernel) { + memcpy((struct flock*)argument, &flock, + sizeof(struct flock)); + } else { + status = user_memcpy((struct flock*)argument, + &flock, sizeof(struct flock)); + } } else { // a conflicting lock was found, copy back its range and // type if (normalizedLock.l_len == OFF_MAX) normalizedLock.l_len = 0; - status = user_memcpy((struct flock*)argument, - &normalizedLock, sizeof(struct flock)); + if (kernel) { + memcpy((struct flock*)argument, + &normalizedLock, sizeof(struct flock)); + } else { + status = user_memcpy((struct flock*)argument, + &normalizedLock, sizeof(struct flock)); + } } } } else