mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-15 23:35:42 -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();
|
||||
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()) {
|
||||
if (ino.mode_index() >= num_modes) {
|
||||
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 (dep->size() >= std::numeric_limits<uint32_t>::max()) {
|
||||
DWARFS_THROW(runtime_error, "invalid number of dir_entries");
|
||||
}
|
||||
|
||||
if (auto cn = meta->compact_names()) {
|
||||
num_names = cn->index().size();
|
||||
if (!cn->packed_index()) {
|
||||
@ -173,6 +197,11 @@ void check_index_range(global_metadata::Meta const* meta) {
|
||||
}
|
||||
}
|
||||
} 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()) {
|
||||
if (ent >= num_inodes) {
|
||||
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) {
|
||||
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 (std::any_of(meta->directories().begin(), meta->directories().end(),
|
||||
[](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");
|
||||
}
|
||||
|
||||
if (meta->chunks().size() >= std::numeric_limits<uint32_t>::max()) {
|
||||
DWARFS_THROW(runtime_error, "invalid number of chunks");
|
||||
}
|
||||
|
||||
for (auto c : meta->chunks()) {
|
||||
if (c.offset() >= block_size || c.size() > block_size) {
|
||||
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_types_custom_protocol.h"
|
||||
|
||||
#include "thrift/lib/thrift/gen-cpp2/frozen_types_custom_protocol.h"
|
||||
|
||||
namespace dwarfs {
|
||||
|
||||
namespace {
|
||||
@ -89,9 +91,41 @@ freeze_to_buffer(const T& x) {
|
||||
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>
|
||||
MappedFrozen<T> map_frozen(folly::ByteRange schema, folly::ByteRange data) {
|
||||
using namespace ::apache::thrift::frozen;
|
||||
check_schema(schema);
|
||||
auto layout = std::make_unique<Layout<T>>();
|
||||
deserializeRootLayout(schema, *layout);
|
||||
MappedFrozen<T> ret(layout->view({data.begin(), 0}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user