diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index fa87df3938..34a3c37325 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -886,14 +886,14 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, bfs_inode& node = inode->Node(); bool updateTime = false; - uid_t uid = geteuid(); - - bool isOwnerOrRoot = uid == 0 || uid == (uid_t)node.UserID(); - bool hasWriteAccess = inode->CheckPermissions(W_OK) == B_OK; Transaction transaction(volume, inode->BlockNumber()); inode->WriteLockInTransaction(transaction); + if (check_write_stat_permissions(node.GroupID(), node.UserID(), node.Mode(), + mask, stat) != B_OK) + RETURN_ERROR(B_NOT_ALLOWED); + if ((mask & B_STAT_SIZE) != 0 && inode->Size() != stat->st_size) { // Since B_STAT_SIZE is the only thing that can fail directly, we // do it first, so that the inode state will still be consistent @@ -902,8 +902,6 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, return B_IS_A_DIRECTORY; if (!inode->IsFile()) return B_BAD_VALUE; - if (!hasWriteAccess) - RETURN_ERROR(B_NOT_ALLOWED); off_t oldSize = inode->Size(); @@ -929,25 +927,16 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, } if ((mask & B_STAT_UID) != 0) { - // only root should be allowed - if (uid != 0) - RETURN_ERROR(B_NOT_ALLOWED); node.uid = HOST_ENDIAN_TO_BFS_INT32(stat->st_uid); updateTime = true; } if ((mask & B_STAT_GID) != 0) { - // only the user or root can do that - if (!isOwnerOrRoot) - RETURN_ERROR(B_NOT_ALLOWED); node.gid = HOST_ENDIAN_TO_BFS_INT32(stat->st_gid); updateTime = true; } if ((mask & B_STAT_MODE) != 0) { - // only the user or root can do that - if (!isOwnerOrRoot) - RETURN_ERROR(B_NOT_ALLOWED); PRINT(("original mode = %u, stat->st_mode = %u\n", (unsigned int)node.Mode(), (unsigned int)stat->st_mode)); node.mode = HOST_ENDIAN_TO_BFS_INT32((node.Mode() & ~S_IUMSK) @@ -956,17 +945,11 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, } if ((mask & B_STAT_CREATION_TIME) != 0) { - // the user or root can do that or any user with write access - if (!isOwnerOrRoot && !hasWriteAccess) - RETURN_ERROR(B_NOT_ALLOWED); node.create_time = HOST_ENDIAN_TO_BFS_INT64(bfs_inode::ToInode(stat->st_crtim)); } if ((mask & B_STAT_MODIFICATION_TIME) != 0) { - // the user or root can do that or any user with write access - if (!isOwnerOrRoot && !hasWriteAccess) - RETURN_ERROR(B_NOT_ALLOWED); if (!inode->InLastModifiedIndex()) { // directory modification times are not part of the index node.last_modified_time @@ -980,9 +963,6 @@ bfs_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, } if ((mask & B_STAT_CHANGE_TIME) != 0 || updateTime) { - // the user or root can do that or any user with write access - if (!isOwnerOrRoot && !hasWriteAccess) - RETURN_ERROR(B_NOT_ALLOWED); bigtime_t newTime; if ((mask & B_STAT_CHANGE_TIME) == 0) newTime = bfs_inode::ToInode(real_time_clock_usecs()); diff --git a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp index b2039cc3a3..b68a4f19a7 100644 --- a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp @@ -625,22 +625,20 @@ ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, ext2_inode& node = inode->Node(); bool updateTime = false; - uid_t uid = geteuid(); - - bool isOwnerOrRoot = uid == 0 || uid == (uid_t)node.UserID(); - bool hasWriteAccess = inode->CheckPermissions(W_OK) == B_OK; TRACE("ext2_write_stat: Starting transaction\n"); Transaction transaction(volume->GetJournal()); inode->WriteLockInTransaction(transaction); + if (check_write_stat_permissions(node.GroupID(), node.UserID(), node.Mode(), + mask, stat) != B_OK) + return B_NOT_ALLOWED; + if ((mask & B_STAT_SIZE) != 0 && inode->Size() != stat->st_size) { if (inode->IsDirectory()) return B_IS_A_DIRECTORY; if (!inode->IsFile()) return B_BAD_VALUE; - if (!hasWriteAccess) - return B_NOT_ALLOWED; TRACE("ext2_write_stat: Old size: %ld, new size: %ld\n", (long)inode->Size(), (long)stat->st_size); @@ -661,34 +659,22 @@ ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, } if ((mask & B_STAT_MODE) != 0) { - // only the user or root can do that - if (!isOwnerOrRoot) - return B_NOT_ALLOWED; node.UpdateMode(stat->st_mode, S_IUMSK); updateTime = true; } if ((mask & B_STAT_UID) != 0) { - // only root should be allowed - if (uid != 0) - return B_NOT_ALLOWED; node.SetUserID(stat->st_uid); updateTime = true; } if ((mask & B_STAT_GID) != 0) { - // only the user or root can do that - if (!isOwnerOrRoot) - return B_NOT_ALLOWED; node.SetGroupID(stat->st_gid); updateTime = true; } if ((mask & B_STAT_MODIFICATION_TIME) != 0 || updateTime || (mask & B_STAT_CHANGE_TIME) != 0) { - // the user or root can do that or any user with write access - if (!isOwnerOrRoot && !hasWriteAccess) - return B_NOT_ALLOWED; struct timespec newTimespec = { 0, 0}; if ((mask & B_STAT_MODIFICATION_TIME) != 0) @@ -704,9 +690,6 @@ ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, inode->SetModificationTime(&newTimespec); } if ((mask & B_STAT_CREATION_TIME) != 0) { - // the user or root can do that or any user with write access - if (!isOwnerOrRoot && !hasWriteAccess) - return B_NOT_ALLOWED; inode->SetCreationTime(&stat->st_crtim); }