From 51aecb15a408e89ce593b38bbd35d41cf4ab0e39 Mon Sep 17 00:00:00 2001 From: rootvector2 Date: Tue, 9 Jun 2026 17:45:49 +0530 Subject: [PATCH] reject out-of-range enum index in read_value the enum branch in read_value stored the wire index without range-checking it against the symbol count, so an out-of-range value reached avro_schema_enum_get and produced an uninitialized pointer read; mirror the union discriminant check. --- lang/c/src/value-read.c | 6 ++++++ lang/c/tests/test_avro_values.c | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lang/c/src/value-read.c b/lang/c/src/value-read.c index b6b6e79fadd..103eca9a523 100644 --- a/lang/c/src/value-read.c +++ b/lang/c/src/value-read.c @@ -329,10 +329,16 @@ read_value(avro_reader_t reader, avro_value_t *dest) case AVRO_ENUM: { + avro_schema_t schema = avro_value_get_schema(dest); int64_t val; check_prefix(rval, avro_binary_encoding. read_long(reader, &val), "Cannot read enum value: "); + if (val < 0 || + val >= avro_schema_enum_number_of_symbols(schema)) { + avro_set_error("Invalid enum value: %" PRId64, val); + return EINVAL; + } return avro_value_set_enum(dest, val); } diff --git a/lang/c/tests/test_avro_values.c b/lang/c/tests/test_avro_values.c index 4930b8ca3e7..5c589610187 100644 --- a/lang/c/tests/test_avro_values.c +++ b/lang/c/tests/test_avro_values.c @@ -965,6 +965,23 @@ test_enum(void) avro_value_decref(&val); } + /* A symbol index read from the wire that falls outside the declared + * symbols must be rejected, otherwise it is stored as-is and later + * dereferenced by avro_schema_enum_get. */ + { + /* zig-zag long 99 => {0xC6, 0x01}; "suits" has only 4 symbols */ + char bad_enum[] = { (char) 0xC6, 0x01 }; + avro_reader_t reader = + avro_reader_memory(bad_enum, sizeof(bad_enum)); + avro_value_t val; + try(avro_generic_value_new(enum_class, &val), + "Cannot create enum"); + try(!avro_value_read(reader, &val), + "Expected error reading out-of-range enum index"); + avro_value_decref(&val); + avro_reader_free(reader); + } + avro_schema_decref(enum_schema); avro_value_iface_decref(enum_class); return 0;