diff --git a/headers/private/file_systems/QueryParser.h b/headers/private/file_systems/QueryParser.h index 4208eb1785..95cd09b00c 100644 --- a/headers/private/file_systems/QueryParser.h +++ b/headers/private/file_systems/QueryParser.h @@ -966,7 +966,7 @@ Equation::GetNextMatching(Context* context, dirent->d_ino = QueryPolicy::EntryGetNodeID(entry); dirent->d_pdev = dirent->d_dev; dirent->d_pino = QueryPolicy::EntryGetParentID(entry); - dirent->d_reclen = sizeof(struct dirent) + strlen(dirent->d_name); + dirent->d_reclen = sizeof(struct dirent) + strlen(dirent->d_name) + 1; } if (status == MATCH_OK) diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp b/src/add-ons/kernel/file_systems/bfs/Query.cpp index 7b9042a1e3..2d07a83a39 100644 --- a/src/add-ons/kernel/file_systems/bfs/Query.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp @@ -673,7 +673,7 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* iterator, FATAL(("inode %" B_PRIdOFF " in query has no name!\n", inode->BlockNumber())); } else { - dirent->d_reclen += strlen(dirent->d_name); + dirent->d_reclen += strlen(dirent->d_name) + 1; } } 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 f98ea7e604..0ccc89e42f 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -1737,7 +1737,7 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, while (count < maxCount && bufferSize > sizeof(struct dirent)) { ino_t id; uint16 length; - size_t nameBufferSize = bufferSize - sizeof(struct dirent) + 1; + size_t nameBufferSize = bufferSize - sizeof(struct dirent); status_t status = iterator->GetNextEntry(dirent->d_name, &length, nameBufferSize, &id); @@ -1759,7 +1759,7 @@ bfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, dirent->d_dev = volume->ID(); dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); @@ -1867,7 +1867,7 @@ bfs_read_attr_dir(fs_volume* _volume, fs_vnode* node, void* _cookie, Volume* volume = (Volume*)_volume->private_volume; dirent->d_dev = volume->ID(); - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; *_num = 1; return B_OK; diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp index 5e8fe5fcba..1ac679141a 100644 --- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp @@ -814,7 +814,7 @@ btrfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, while (count < maxCount && bufferSize > sizeof(struct dirent)) { ino_t id; - size_t length = bufferSize - sizeof(struct dirent) + 1; + size_t length = bufferSize - sizeof(struct dirent); status_t status = iterator->GetNext(dirent->d_name, &length, &id); @@ -834,7 +834,7 @@ btrfs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, dirent->d_dev = volume->ID(); dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); @@ -928,7 +928,7 @@ btrfs_read_attr_dir(fs_volume* _volume, fs_vnode* _node, Volume* volume = (Volume*)_volume->private_volume; dirent->d_dev = volume->ID(); - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; *_num = 1; return B_OK; diff --git a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp index 0426564e05..b9c876b6ff 100644 --- a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp @@ -1907,7 +1907,7 @@ cdda_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, buffer->d_dev = volume->FSVolume()->id; buffer->d_ino = childNode->ID(); - buffer->d_reclen = strlen(name) + sizeof(struct dirent); + buffer->d_reclen = sizeof(struct dirent) + strlen(name) + 1; if (buffer->d_reclen > bufferSize) { if (count == 0) @@ -2041,7 +2041,7 @@ cdda_read_attr_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, size_t length = strlcpy(dirent->d_name, attribute->Name(), bufferSize); dirent->d_dev = volume->FSVolume()->id; dirent->d_ino = inode->ID(); - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; cookie->current = attribute->GetDoublyLinkedListLink()->next; *_num = 1; diff --git a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp index e9c88caa2a..f643db9068 100644 --- a/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp @@ -587,7 +587,7 @@ exfat_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, while (count < maxCount && bufferSize > sizeof(struct dirent)) { ino_t id; - size_t length = bufferSize - sizeof(struct dirent) + 1; + size_t length = bufferSize - sizeof(struct dirent); status_t status = iterator->GetNext(dirent->d_name, &length, &id); if (status == B_ENTRY_NOT_FOUND) @@ -605,7 +605,7 @@ exfat_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, dirent->d_dev = volume->ID(); dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); 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 ec42e57acf..b0400558f6 100644 --- a/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp @@ -1442,7 +1442,7 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, while (count < maxCount && bufferSize > sizeof(struct dirent)) { - size_t length = bufferSize - sizeof(struct dirent) + 1; + size_t length = bufferSize - sizeof(struct dirent); ino_t id; status_t status = iterator->GetNext(dirent->d_name, &length, &id); @@ -1465,7 +1465,7 @@ ext2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, dirent->d_dev = volume->ID(); dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); @@ -1565,7 +1565,7 @@ ext2_read_attr_dir(fs_volume* _volume, fs_vnode* _node, dirent->d_dev = volume->ID(); dirent->d_ino = inode->ID(); - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; *_num = 1; *(int32*)_cookie = index + 1; diff --git a/src/add-ons/kernel/file_systems/fat/attr.cpp b/src/add-ons/kernel/file_systems/fat/attr.cpp index ac413f70df..c5ea45e3ea 100644 --- a/src/add-ons/kernel/file_systems/fat/attr.cpp +++ b/src/add-ons/kernel/file_systems/fat/attr.cpp @@ -134,8 +134,8 @@ dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie, entry->d_ino = node->vnid; entry->d_dev = vol->id; - entry->d_reclen = 10; strcpy(entry->d_name, "BEOS:TYPE"); + entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name) + 1; } *cookie = 1; diff --git a/src/add-ons/kernel/file_systems/fat/dir.cpp b/src/add-ons/kernel/file_systems/fat/dir.cpp index 46d7986b48..530050e569 100644 --- a/src/add-ons/kernel/file_systems/fat/dir.cpp +++ b/src/add-ons/kernel/file_systems/fat/dir.cpp @@ -1195,10 +1195,10 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie, } else { if (cookie->current_index++ == 0) { strcpy(entry->d_name, "."); - entry->d_reclen = sizeof(struct dirent) + 1; + entry->d_reclen = sizeof(struct dirent) + 2; } else { strcpy(entry->d_name, ".."); - entry->d_reclen = sizeof(struct dirent) + 2; + entry->d_reclen = sizeof(struct dirent) + 3; } *num = 1; entry->d_ino = vol->root_vnode.vnid; @@ -1229,7 +1229,7 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie, if (result == B_NO_ERROR) { *num = 1; entry->d_dev = vol->id; - entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name); + entry->d_reclen = sizeof(struct dirent) + strlen(entry->d_name) + 1; DPRINTF(0, ("dosfs_readdir: found file %s\n", entry->d_name)); } else if (result == ENOENT) { // When you get to the end, don't return an error, just return 0 diff --git a/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c b/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c index e01f25c136..22117868d4 100644 --- a/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c +++ b/src/add-ons/kernel/file_systems/nfs/nfs_add_on.c @@ -1048,8 +1048,7 @@ fs_readdir(fs_volume *_volume, fs_vnode *_node, void *_cookie, buf->d_pdev = ns->nsid; buf->d_ino = vnid; buf->d_pino = node->vnid; - buf->d_reclen = 2 * (sizeof(dev_t) + sizeof(ino_t)) - + sizeof(unsigned short) + strlen(filename) + 1; + buf->d_reclen = sizeof(struct dirent) + strlen(filename) + 1; strcpy (buf->d_name,filename); // if ((ns->rootid == node->vnid))//XXX:mmu_man:test // dprintf("nfs: dirent %d {d:%ld pd:%ld i:%lld pi:%lld '%s'}\n", *num, buf->d_dev, buf->d_pdev, buf->d_ino, buf->d_pino, buf->d_name); diff --git a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp index de8bcae5bf..33ae59939d 100644 --- a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp @@ -1232,8 +1232,8 @@ fs_read_dir(fs_volume* _volume, fs_vnode* _node, void* _cookie, dirent->d_dev = _volume->id; dirent->d_ino = cookie->current->inode; - strlcpy(dirent->d_name, cookie->current->name, length + 1); - dirent->d_reclen = sizeof(struct dirent) + length; + strlcpy(dirent->d_name, cookie->current->name, length); + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); diff --git a/src/add-ons/kernel/file_systems/udf/Icb.cpp b/src/add-ons/kernel/file_systems/udf/Icb.cpp index 6f0fcc991a..1cd2aeff77 100644 --- a/src/add-ons/kernel/file_systems/udf/Icb.cpp +++ b/src/add-ons/kernel/file_systems/udf/Icb.cpp @@ -30,7 +30,7 @@ DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id) if (fAtBeginning) { TRACE(("DirectoryIterator::GetNextEntry: .\n")); sprintf(name, "."); - *length = 2; + *length = 1; *id = Parent()->Id(); fAtBeginning = false; } else { @@ -58,7 +58,7 @@ DirectoryIterator::GetNextEntry(char *name, uint32 *length, ino_t *id) if (entry->is_parent()) { TRACE(("DirectoryIterator::GetNextEntry: ..\n")); sprintf(name, ".."); - *length = 3; + *length = 2; } else { UdfString string(entry->id(), entry->id_length()); TRACE(("DirectoryIterator::GetNextEntry: UfdString id == `%s', " diff --git a/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp b/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp index 13b5399244..f9bf23d915 100644 --- a/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/udf/kernel_interface.cpp @@ -463,7 +463,7 @@ udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void *cookie, return B_BAD_VALUE; } - uint32 nameLength = bufferSize - sizeof(struct dirent) + 1; + uint32 nameLength = bufferSize - sizeof(struct dirent); ino_t id; status_t status = iterator->GetNextEntry(dirent->d_name, &nameLength, &id); if (!status) { @@ -471,7 +471,7 @@ udf_read_dir(fs_volume *_volume, fs_vnode *vnode, void *cookie, *_num = 1; dirent->d_dev = volume->ID(); dirent->d_ino = id; - dirent->d_reclen = sizeof(struct dirent) + nameLength - 1; + dirent->d_reclen = sizeof(struct dirent) + nameLength + 1; } else { *_num = 0; // Clear the status for end of directory diff --git a/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp index da326e2796..0ed88848ee 100644 --- a/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp +++ b/src/add-ons/kernel/file_systems/ufs2/DirectoryIterator.cpp @@ -80,6 +80,8 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id) fOffset = fOffset + 8 + remainder; if (direct.next_ino > 0) { + if ((direct.namlen + 1) > *_nameLength) + return B_BUFFER_OVERFLOW; strlcpy(name, direct.name, direct.namlen + 1); *_id = direct.next_ino; *_nameLength = direct.namlen; @@ -87,7 +89,6 @@ DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id) } return B_ENTRY_NOT_FOUND; - } return B_ERROR; diff --git a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp index 0234ee88ad..69af701dba 100644 --- a/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/ufs2/kernel_interface.cpp @@ -380,8 +380,8 @@ ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 count = 0; while (count < maxCount - && (bufferSize >= sizeof(struct dirent) + B_FILE_NAME_LENGTH)) { - size_t length = bufferSize; + && (bufferSize >= sizeof(struct dirent) + B_FILE_NAME_LENGTH)) { + size_t length = bufferSize - sizeof(struct dirent); ino_t iNodeNo; status_t status = iterator->GetNext(dirent->d_name, &length, &iNodeNo); @@ -397,7 +397,7 @@ ufs2_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, dirent->d_dev = volume->ID(); dirent->d_ino = iNodeNo; - dirent->d_reclen = sizeof(struct dirent) + length; + dirent->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= dirent->d_reclen; dirent = (struct dirent*)((uint8*)dirent + dirent->d_reclen); count++; diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp index 87538a9fd7..ebdda03771 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp @@ -95,12 +95,6 @@ struct FUSEVolume::DirEntryCache { return fEntryCount; } - size_t DirentLength(uint32 index) const - { - const Entry& entry = fEntries[index]; - return sizeof(dirent) + entry.nameSize - 1; - } - bool ReadDirent(uint32 index, dev_t volumeID, bool align, dirent* buffer, size_t bufferSize) const { @@ -110,7 +104,7 @@ struct FUSEVolume::DirEntryCache { const Entry& entry = fEntries[index]; // get and check the size - size_t size = sizeof(dirent) + entry.nameSize - 1; + size_t size = sizeof(dirent) + entry.nameSize; if (size > bufferSize) return false; @@ -254,7 +248,7 @@ struct FUSEVolume::AttrDirCookie : RWLockable { size_t nameLen = strlen(name); // get and check the size - size_t size = sizeof(dirent) + nameLen; + size_t size = sizeof(dirent) + nameLen + 1; if (size > bufferSize) return false; @@ -2995,7 +2989,7 @@ FUSEVolume::_AddReadDirEntry(ReadDirBuffer* buffer, const char* name, int type, return 1; // compute the entry length and check whether the entry still fits - entryLen = sizeof(dirent) + strlen(name); + entryLen = sizeof(dirent) + strlen(name) + 1; if (buffer->usedSize + entryLen > buffer->bufferSize) return 1; } diff --git a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp index 1ee159d897..e0fdbd8cfe 100644 --- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp @@ -428,7 +428,7 @@ xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 count = 0; while (count < maxCount && (bufferSize > sizeof(struct dirent))) { - size_t length = bufferSize - sizeof(struct dirent) + 1; + size_t length = bufferSize - sizeof(struct dirent); xfs_ino_t ino; status_t status = iterator->GetNext(buffer->d_name, &length, &ino); @@ -444,7 +444,7 @@ xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie, buffer->d_dev = volume->ID(); buffer->d_ino = ino; - buffer->d_reclen = sizeof(struct dirent) + length; + buffer->d_reclen = sizeof(struct dirent) + length + 1; bufferSize -= buffer->d_reclen; buffer = (struct dirent*)((uint8*)buffer + buffer->d_reclen); count++; diff --git a/src/kits/tracker/NodeWalker.cpp b/src/kits/tracker/NodeWalker.cpp index 6d23780aa8..d06df80f2d 100644 --- a/src/kits/tracker/NodeWalker.cpp +++ b/src/kits/tracker/NodeWalker.cpp @@ -397,7 +397,7 @@ build_dirent(const BEntry* source, struct dirent* ent, entry_ref ref; source->GetRef(&ref); - size_t recordLength = strlen(ref.name) + sizeof(dirent); + size_t recordLength = strlen(ref.name) + 1 + sizeof(dirent); if (recordLength > size || count <= 0) { // can't fit in buffer, bail return 0; diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index ec413dc8aa..341ea839ab 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -1417,7 +1417,7 @@ devfs_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, dirent->d_dev = fs->id; dirent->d_ino = childNode->id; - dirent->d_reclen = strlen(name) + sizeof(struct dirent); + dirent->d_reclen = strlen(name) + 1 + sizeof(struct dirent); if (dirent->d_reclen > bufferSize) return ENOBUFS; diff --git a/src/system/kernel/fs/rootfs.cpp b/src/system/kernel/fs/rootfs.cpp index fa255fe461..73388165ab 100644 --- a/src/system/kernel/fs/rootfs.cpp +++ b/src/system/kernel/fs/rootfs.cpp @@ -790,7 +790,7 @@ rootfs_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, dirent->d_dev = fs->id; dirent->d_ino = childNode->id; - dirent->d_reclen = strlen(name) + sizeof(struct dirent); + dirent->d_reclen = strlen(name) + 1 + sizeof(struct dirent); if (dirent->d_reclen > bufferSize) return ENOBUFS; diff --git a/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp b/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp index ddbb57d526..91f85fae79 100644 --- a/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp +++ b/src/tests/system/kernel/file_corruption/fs/checksumfs.cpp @@ -190,7 +190,7 @@ struct DirCookie { } } - size_t entrySize = sizeof(dirent) + nameLength; + size_t entrySize = sizeof(dirent) + nameLength + 1; if (entrySize > size) return B_BUFFER_OVERFLOW; @@ -2388,4 +2388,4 @@ fs_vnode_ops gCheckSumFSVnodeOps = { /* support for node and FS layers */ NULL, // create_special_node NULL // get_super_vnode -}; \ No newline at end of file +};