Skip to content

Commit

Permalink
Sanitize annotation values
Browse files Browse the repository at this point in the history
Summary: When loading, check that the `value_arg` is in the expected range.

Reviewed By: thezhangwei

Differential Revision: D47972418

fbshipit-source-id: b8aa71e12c802de5fefb0d82f4c03af017b3ca7b
  • Loading branch information
agampe authored and facebook-github-bot committed Aug 2, 2023
1 parent 9a5a16a commit a39c8dd
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions libredex/DexAnnotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,50 +449,65 @@ std::unique_ptr<DexEncodedValue> DexEncodedValue::get_encoded_value(
uint8_t evarg = DEVT_HDR_ARG(evhdr);
switch (evt) {
case DEVT_SHORT:
always_assert(evarg <= 1);
[[fallthrough]];
case DEVT_INT:
always_assert(evarg <= 3);
[[fallthrough]];
case DEVT_LONG: {
always_assert(evarg <= 7);
uint64_t v = read_evarg(encdata, evarg, true /* sign_extend */);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValuePrimitive(evt, v));
}
case DEVT_BYTE:
always_assert(evarg == 0);
[[fallthrough]];
case DEVT_CHAR: {
always_assert(evarg <= 1);
uint64_t v = read_evarg(encdata, evarg, false /* sign_extend */);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValuePrimitive(evt, v));
}
case DEVT_FLOAT: {
always_assert_log(evarg <= 3, "Unexpected float size: %u", evarg);
// We sign extend floats so that they can be treated just like signed ints
uint64_t v = read_evarg(encdata, evarg, true /* sign_extend */)
<< ((3 - evarg) * 8);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValuePrimitive(evt, v));
}
case DEVT_DOUBLE: {
always_assert(evarg <= 7);
uint64_t v = read_evarg(encdata, evarg, false /* sign_extend */)
<< ((7 - evarg) * 8);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValuePrimitive(evt, v));
}
case DEVT_METHOD_TYPE: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
DexProto* evproto = idx->get_protoidx(evidx);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValueMethodType(evproto));
}
case DEVT_METHOD_HANDLE: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
DexMethodHandle* evmethodhandle = idx->get_methodhandleidx(evidx);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValueMethodHandle(evmethodhandle));
}

case DEVT_NULL:
always_assert(evarg == 0);
return std::unique_ptr<DexEncodedValue>(new DexEncodedValueBit(evt, false));
case DEVT_BOOLEAN:
always_assert(evarg <= 1);
return std::unique_ptr<DexEncodedValue>(
new DexEncodedValueBit(evt, evarg > 0));
case DEVT_STRING: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
auto evstring = idx->get_stringidx(evidx);
always_assert_log(evstring != nullptr,
Expand All @@ -501,14 +516,18 @@ std::unique_ptr<DexEncodedValue> DexEncodedValue::get_encoded_value(
new DexEncodedValueString(evstring));
}
case DEVT_TYPE: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
DexType* evtype = idx->get_typeidx(evidx);
always_assert_log(evtype != nullptr,
"Invalid type idx in annotation element");
return std::unique_ptr<DexEncodedValue>(new DexEncodedValueType(evtype));
}
case DEVT_FIELD:
always_assert(evarg <= 3);
[[fallthrough]];
case DEVT_ENUM: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
DexFieldRef* evfield = idx->get_fieldidx(evidx);
always_assert_log(evfield != nullptr,
Expand All @@ -517,6 +536,7 @@ std::unique_ptr<DexEncodedValue> DexEncodedValue::get_encoded_value(
new DexEncodedValueField(evt, evfield));
}
case DEVT_METHOD: {
always_assert(evarg <= 3);
uint32_t evidx = (uint32_t)read_evarg(encdata, evarg);
DexMethodRef* evmethod = idx->get_methodidx(evidx);
always_assert_log(evmethod != nullptr,
Expand All @@ -525,8 +545,10 @@ std::unique_ptr<DexEncodedValue> DexEncodedValue::get_encoded_value(
new DexEncodedValueMethod(evmethod));
}
case DEVT_ARRAY:
always_assert(evarg == 0);
return get_encoded_value_array(idx, encdata);
case DEVT_ANNOTATION: {
always_assert(evarg == 0);
EncodedAnnotations eanno{};
uint32_t tidx = read_uleb128(&encdata);
uint32_t count = read_uleb128(&encdata);
Expand Down

0 comments on commit a39c8dd

Please sign in to comment.