Skip to content

Commit

Permalink
Fix a potential Ruby-upb use of uninitialized memory.
Browse files Browse the repository at this point in the history
Introduce a upb_MessageValue_Zero() function to use for the cases we do want a zero'd union (typically a zero MessageValue union is not needed)

PiperOrigin-RevId: 672592274
  • Loading branch information
protobuf-github-bot authored and zhangskz committed Sep 9, 2024
1 parent 5b4b3af commit 70b77de
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion ruby/ext/google/protobuf_c/defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ static VALUE FieldDescriptor__type(VALUE _self) {
static VALUE FieldDescriptor_default(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_FieldDef* f = self->fielddef;
upb_MessageValue default_val = {0};
upb_MessageValue default_val = upb_MessageValue_Zero();
if (upb_FieldDef_IsSubMessage(f)) {
return Qnil;
} else if (!upb_FieldDef_IsRepeated(f)) {
Expand Down
2 changes: 0 additions & 2 deletions upb/json/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) {
/* Parse UINT32 or UINT64 value. */
static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) {
upb_MessageValue val;
memset(&val, 0, sizeof(val));

switch (jsondec_peek(d)) {
case JD_NUMBER: {
Expand Down Expand Up @@ -750,7 +749,6 @@ static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) {
static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) {
upb_StringView str;
upb_MessageValue val;
memset(&val, 0, sizeof(val));

switch (jsondec_peek(d)) {
case JD_NUMBER:
Expand Down
26 changes: 26 additions & 0 deletions upb/message/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@
#define UPB_MESSAGE_VALUE_H_

#include <stdint.h>
#include <string.h>

#include "upb/base/string_view.h"

// Must be last.
#include "upb/port/def.inc"

#ifdef __cplusplus
extern "C" {
#endif

typedef union {
bool bool_val;
float float_val;
Expand All @@ -35,10 +43,28 @@ typedef union {
uintptr_t tagged_msg_val; // upb_TaggedMessagePtr
} upb_MessageValue;

UPB_API_INLINE upb_MessageValue upb_MessageValue_Zero(void) {
upb_MessageValue zero;
memset(&zero, 0, sizeof(zero));
return zero;
}

typedef union {
struct upb_Array* array;
struct upb_Map* map;
struct upb_Message* msg;
} upb_MutableMessageValue;

UPB_API_INLINE upb_MutableMessageValue upb_MutableMessageValue_Zero(void) {
upb_MutableMessageValue zero;
memset(&zero, 0, sizeof(zero));
return zero;
}

#ifdef __cplusplus
} /* extern "C" */
#endif

#include "upb/port/undef.inc"

#endif /* UPB_MESSAGE_VALUE_H_ */
3 changes: 1 addition & 2 deletions upb/reflection/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m,
const upb_MiniTable* mt = upb_MessageDef_MiniTable(m);
size_t i = *iter;
size_t n = upb_MiniTable_FieldCount(mt);
upb_MessageValue zero;
memset(&zero, 0, sizeof(zero));
upb_MessageValue zero = upb_MessageValue_Zero();
UPB_UNUSED(ext_pool);

// Iterate over normal fields, returning the first one that is set.
Expand Down

0 comments on commit 70b77de

Please sign in to comment.