mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-16 15:58:06 -04:00
Moar checks
This commit is contained in:
parent
69fc251cd6
commit
9112f1f7ac
@ -136,6 +136,26 @@ void check_index_range(global_metadata::Meta const* meta) {
|
|||||||
auto num_inodes = meta->inodes().size();
|
auto num_inodes = meta->inodes().size();
|
||||||
bool v2_2 = !static_cast<bool>(meta->dir_entries());
|
bool v2_2 = !static_cast<bool>(meta->dir_entries());
|
||||||
|
|
||||||
|
if (num_modes >= std::numeric_limits<uint16_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of modes");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_uids >= std::numeric_limits<uint16_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of uids");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_gids >= std::numeric_limits<uint16_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of gids");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_names >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of names");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_inodes >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of inodes");
|
||||||
|
}
|
||||||
|
|
||||||
for (auto ino : meta->inodes()) {
|
for (auto ino : meta->inodes()) {
|
||||||
if (ino.mode_index() >= num_modes) {
|
if (ino.mode_index() >= num_modes) {
|
||||||
DWARFS_THROW(runtime_error, "mode_index out of range");
|
DWARFS_THROW(runtime_error, "mode_index out of range");
|
||||||
@ -154,6 +174,10 @@ void check_index_range(global_metadata::Meta const* meta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto dep = meta->dir_entries()) {
|
if (auto dep = meta->dir_entries()) {
|
||||||
|
if (dep->size() >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of dir_entries");
|
||||||
|
}
|
||||||
|
|
||||||
if (auto cn = meta->compact_names()) {
|
if (auto cn = meta->compact_names()) {
|
||||||
num_names = cn->index().size();
|
num_names = cn->index().size();
|
||||||
if (!cn->packed_index()) {
|
if (!cn->packed_index()) {
|
||||||
@ -173,6 +197,11 @@ void check_index_range(global_metadata::Meta const* meta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (meta->entry_table_v2_2().size() >=
|
||||||
|
std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of entries");
|
||||||
|
}
|
||||||
|
|
||||||
for (auto ent : meta->entry_table_v2_2()) {
|
for (auto ent : meta->entry_table_v2_2()) {
|
||||||
if (ent >= num_inodes) {
|
if (ent >= num_inodes) {
|
||||||
DWARFS_THROW(runtime_error, "entry_table_v2_2 value out of range");
|
DWARFS_THROW(runtime_error, "entry_table_v2_2 value out of range");
|
||||||
@ -182,6 +211,14 @@ void check_index_range(global_metadata::Meta const* meta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void check_packed_tables(global_metadata::Meta const* meta) {
|
void check_packed_tables(global_metadata::Meta const* meta) {
|
||||||
|
if (meta->directories().size() >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of directories");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meta->chunk_table().size() >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of chunk_table entries");
|
||||||
|
}
|
||||||
|
|
||||||
if (auto opt = meta->options(); opt and opt->packed_directories()) {
|
if (auto opt = meta->options(); opt and opt->packed_directories()) {
|
||||||
if (std::any_of(meta->directories().begin(), meta->directories().end(),
|
if (std::any_of(meta->directories().begin(), meta->directories().end(),
|
||||||
[](auto i) { return i.parent_entry() != 0; })) {
|
[](auto i) { return i.parent_entry() != 0; })) {
|
||||||
@ -229,6 +266,10 @@ void check_chunks(global_metadata::Meta const* meta) {
|
|||||||
DWARFS_THROW(runtime_error, "invalid block size");
|
DWARFS_THROW(runtime_error, "invalid block size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meta->chunks().size() >= std::numeric_limits<uint32_t>::max()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid number of chunks");
|
||||||
|
}
|
||||||
|
|
||||||
for (auto c : meta->chunks()) {
|
for (auto c : meta->chunks()) {
|
||||||
if (c.offset() >= block_size || c.size() > block_size) {
|
if (c.offset() >= block_size || c.size() > block_size) {
|
||||||
DWARFS_THROW(runtime_error, "chunk offset/size out of range");
|
DWARFS_THROW(runtime_error, "chunk offset/size out of range");
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
#include "dwarfs/gen-cpp2/metadata_layouts.h"
|
#include "dwarfs/gen-cpp2/metadata_layouts.h"
|
||||||
#include "dwarfs/gen-cpp2/metadata_types_custom_protocol.h"
|
#include "dwarfs/gen-cpp2/metadata_types_custom_protocol.h"
|
||||||
|
|
||||||
|
#include "thrift/lib/thrift/gen-cpp2/frozen_types_custom_protocol.h"
|
||||||
|
|
||||||
namespace dwarfs {
|
namespace dwarfs {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -89,9 +91,41 @@ freeze_to_buffer(const T& x) {
|
|||||||
return {schema_buffer, data_buffer};
|
return {schema_buffer, data_buffer};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_schema(folly::ByteRange data) {
|
||||||
|
using namespace ::apache::thrift;
|
||||||
|
frozen::schema::Schema schema;
|
||||||
|
size_t schemaSize = CompactSerializer::deserialize(data, schema);
|
||||||
|
// std::cerr << debugString(schema) << '\n';
|
||||||
|
if (schemaSize != data.size()) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid schema size");
|
||||||
|
}
|
||||||
|
if (schema.layouts_ref()->count(*schema.rootLayout_ref()) == 0) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid rootLayout in schema");
|
||||||
|
}
|
||||||
|
for (auto const& kvl : *schema.layouts_ref()) {
|
||||||
|
auto const& layout = kvl.second;
|
||||||
|
if (kvl.first >= static_cast<int64_t>(schema.layouts_ref()->size())) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid layout key in schema");
|
||||||
|
}
|
||||||
|
if (*layout.size_ref() < 0) {
|
||||||
|
DWARFS_THROW(runtime_error, "negative size in schema");
|
||||||
|
}
|
||||||
|
if (*layout.bits_ref() < 0) {
|
||||||
|
DWARFS_THROW(runtime_error, "negative bits in schema");
|
||||||
|
}
|
||||||
|
for (auto const& kvf : *layout.fields_ref()) {
|
||||||
|
auto const& field = kvf.second;
|
||||||
|
if (schema.layouts_ref()->count(*field.layoutId_ref()) == 0) {
|
||||||
|
DWARFS_THROW(runtime_error, "invalid layoutId in field");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
MappedFrozen<T> map_frozen(folly::ByteRange schema, folly::ByteRange data) {
|
MappedFrozen<T> map_frozen(folly::ByteRange schema, folly::ByteRange data) {
|
||||||
using namespace ::apache::thrift::frozen;
|
using namespace ::apache::thrift::frozen;
|
||||||
|
check_schema(schema);
|
||||||
auto layout = std::make_unique<Layout<T>>();
|
auto layout = std::make_unique<Layout<T>>();
|
||||||
deserializeRootLayout(schema, *layout);
|
deserializeRootLayout(schema, *layout);
|
||||||
MappedFrozen<T> ret(layout->view({data.begin(), 0}));
|
MappedFrozen<T> ret(layout->view({data.begin(), 0}));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user