From 89f0513425b174bc0ec51ca49d3ce0b4384c184b Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Mon, 2 Jul 2012 19:24:40 +0200 Subject: [PATCH] nfs4: Enforce checking lock type against open mode --- .../kernel/file_systems/nfs4/Inode.cpp | 36 +++++++++++++++++++ src/add-ons/kernel/file_systems/nfs4/Inode.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 5ee4849e43..0386cf8173 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -650,9 +650,41 @@ Inode::WriteStat(const struct stat* st, uint32 mask) } +inline status_t +Inode::_CheckLockType(short ltype, uint32 mode) +{ + switch (ltype) { + case F_UNLCK: + return B_OK; + + case F_RDLCK: + if ((mode & O_RDONLY) == 0 && (mode & O_RDWR) == 0) + return EBADF; + else + return B_OK; + + case F_WRLCK: + if ((mode & O_WRONLY) == 0 && (mode & O_RDWR) == 0) + return EBADF; + else + return B_OK; + + default: + return B_BAD_VALUE; + } +} + + status_t Inode::TestLock(OpenFileCookie* cookie, struct flock* lock) { + if (lock->l_type == F_UNLCK) + return B_OK; + + status_t result = _CheckLockType(lock->l_type, cookie->fMode); + if (result != B_OK) + return result; + do { RPC::Server* serv = fFilesystem->Server(); Request request(serv); @@ -693,6 +725,10 @@ status_t Inode::AcquireLock(OpenFileCookie* cookie, const struct flock* lock, bool wait) { + status_t result = _CheckLockType(lock->l_type, cookie->fMode); + if (result != B_OK) + return result; + LockInfo* linfo = new LockInfo; if (linfo == NULL) return B_NO_MEMORY; diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index 4beed54e1f..f7f6646384 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -85,6 +85,8 @@ protected: status_t _ReadDirUp(struct dirent* de, uint32 pos, uint32 size); + static inline status_t _CheckLockType(short ltype, uint32 mode); + static inline ino_t _FileIdToInoT(uint64 fileid); uint64 fFileId;