protobuf/CVE-2022-1941.patch
Adrian Reber 32a0119716
Applied patch for CVE-2022-1941 (#RHEL-40872)
Applied patch to make emacs dependency optional (#RHEL-40572)

Resolves: #RHEL-40872
Resolves: #RHEL-40572

Signed-off-by: Adrian Reber <areber@redhat.com>
2024-06-17 13:25:38 +02:00

190 lines
7.2 KiB
Diff

--- protobuf-3.14.0/src/google/protobuf/extension_set_inl.h 2024-06-17 08:34:37.710063457 +0200
+++ protobuf-3.14.0/src/google/protobuf/extension_set_inl.h.org 2024-06-17 08:30:35.432690742 +0200
@@ -206,16 +206,21 @@
const char* ptr, const Msg* containing_type,
internal::InternalMetadata* metadata, internal::ParseContext* ctx) {
std::string payload;
+ uint32_t type_id;
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
- uint32 type_id = 0;
- bool payload_read = false;
while (!ctx->Done(&ptr)) {
uint32 tag = static_cast<uint8>(*ptr++);
if (tag == WireFormatLite::kMessageSetTypeIdTag) {
uint64 tmp;
ptr = ParseBigVarint(ptr, &tmp);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ type_id = tmp;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
+ type_id = tmp;
- type_id = tmp;
- if (payload_read) {
ExtensionInfo extension;
bool was_packed_on_wire;
if (!FindExtension(2, type_id, containing_type, ctx, &extension,
@@ -241,20 +236,24 @@
GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
tmp_ctx.EndedAtLimit());
}
+ state = State::kDone;
- type_id = 0;
}
} else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (state == State::kHasType) {
- if (type_id != 0) {
ptr = ParseFieldMaybeLazily(static_cast<uint64>(type_id) * 8 + 2, ptr,
containing_type, metadata, ctx);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+ state = State::kDone;
- type_id = 0;
} else {
+ std::string tmp;
int32 size = ReadSize(&ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->ReadString(ptr, size, &tmp);
- ptr = ctx->ReadString(ptr, size, &payload);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ payload = std::move(tmp);
+ state = State::kHasPayload;
+ }
- payload_read = true;
}
} else {
ptr = ReadTag(ptr - 1, &tag);
--- protobuf-3.14.0/src/google/protobuf/wire_format.cc 2024-06-17 08:38:49.003336799 +0200
+++ protobuf-3.14.0/src/google/protobuf/wire_format.cc.org 2024-06-17 08:35:18.445621561 +0200
@@ -659,9 +659,11 @@
const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
// Parse a MessageSetItem
auto metadata = reflection->MutableInternalMetadata(msg);
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
std::string payload;
uint32 type_id = 0;
- bool payload_read = false;
while (!ctx->Done(&ptr)) {
// We use 64 bit tags in order to allow typeid's that span the whole
// range of 32 bit numbers.
@@ -670,8 +668,11 @@
uint64 tmp;
ptr = ParseBigVarint(ptr, &tmp);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ if (state == State::kNoTag) {
+ type_id = tmp;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
+ type_id = tmp;
- type_id = tmp;
- if (payload_read) {
const FieldDescriptor* field;
if (ctx->data().pool == nullptr) {
field = reflection->FindKnownExtensionByNumber(type_id);
@@ -698,17 +693,17 @@
GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
tmp_ctx.EndedAtLimit());
}
+ state = State::kDone;
- type_id = 0;
}
continue;
} else if (tag == WireFormatLite::kMessageSetMessageTag) {
+ if (state == State::kNoTag) {
- if (type_id == 0) {
int32 size = ReadSize(&ptr);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
ptr = ctx->ReadString(ptr, size, &payload);
GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ state = State::kHasPayload;
+ } else if (state == State::kHasType) {
- payload_read = true;
- } else {
// We're now parsing the payload
const FieldDescriptor* field = nullptr;
if (descriptor->IsExtensionNumber(type_id)) {
@@ -722,7 +717,12 @@
ptr = WireFormat::_InternalParseAndMergeField(
msg, ptr, ctx, static_cast<uint64>(type_id) * 8 + 2, reflection,
field);
+ state = State::kDone;
+ } else {
+ int32_t size = ReadSize(&ptr);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+ ptr = ctx->Skip(ptr, size);
+ GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
- type_id = 0;
}
} else {
// An unknown field in MessageSetItem.
--- protobuf-3.14.0/src/google/protobuf/wire_format_lite.h 2024-06-17 08:43:18.156450819 +0200
+++ protobuf-3.14.0/src/google/protobuf/wire_format_lite.h.org 2024-06-17 08:39:03.671177609 +0200
@@ -1798,6 +1798,9 @@
// we can parse it later.
std::string message_data;
+ enum class State { kNoTag, kHasType, kHasPayload, kDone };
+ State state = State::kNoTag;
+
while (true) {
const uint32 tag = input->ReadTagNoLastTag();
if (tag == 0) return false;
@@ -1806,26 +1809,35 @@
case WireFormatLite::kMessageSetTypeIdTag: {
uint32 type_id;
if (!input->ReadVarint32(&type_id)) return false;
- last_type_id = type_id;
+ if (state == State::kNoTag) {
+ last_type_id = type_id;
+ state = State::kHasType;
+ } else if (state == State::kHasPayload) {
- if (!message_data.empty()) {
// We saw some message data before the type_id. Have to parse it
// now.
io::CodedInputStream sub_input(
reinterpret_cast<const uint8*>(message_data.data()),
static_cast<int>(message_data.size()));
sub_input.SetRecursionLimit(input->RecursionBudget());
+ if (!ms.ParseField(type_id, &sub_input)) {
- if (!ms.ParseField(last_type_id, &sub_input)) {
return false;
}
message_data.clear();
+ state = State::kDone;
}
break;
}
case WireFormatLite::kMessageSetMessageTag: {
+ if (state == State::kHasType) {
+ // Already saw type_id, so we can parse this directly.
+ if (!ms.ParseField(last_type_id, input)) {
+ return false;
+ }
+ state = State::kDone;
+ } else if (state == State::kNoTag) {
- if (last_type_id == 0) {
// We haven't seen a type_id yet. Append this data to message_data.
uint32 length;
if (!input->ReadVarint32(&length)) return false;
@@ -1836,11 +1824,9 @@
auto ptr = reinterpret_cast<uint8*>(&message_data[0]);
ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr);
if (!input->ReadRaw(ptr, length)) return false;
+ state = State::kHasPayload;
} else {
+ if (!ms.SkipField(tag, input)) return false;
- // Already saw type_id, so we can parse this directly.
- if (!ms.ParseField(last_type_id, input)) {
- return false;
- }
}
break;