Headline
CVE-2023-28081: Re-sync with internal repository (#960) · facebook/hermes@e6ed9c1
A bytecode optimization bug in Hermes prior to commit e6ed9c1a4b02dc219de1648f44cd808a56171b81 could be used to cause an use-after-free and obtain arbitrary code execution via a carefully crafted payload. Note that this is only exploitable in cases where Hermes is used to execute untrusted JavaScript. Hence, most React Native applications are not affected.
Expand Up @@ -60,6 +60,12 @@ class TypeInferenceImpl { bool runOnModule(Module *M); };
/// \return if the given \p type is a BigInt|Object, which used to determine if /// unary/binary operations may have a BigInt result. static bool isBigIntOrObject(Type type) { return type.canBeBigInt() || type.canBeObject(); }
static bool inferUnaryArith(UnaryOperatorInst *UOI, Type numberResultType) { Value *op = UOI->getSingleOperand();
Expand All @@ -73,10 +79,11 @@ static bool inferUnaryArith(UnaryOperatorInst *UOI, Type numberResultType) { return true; }
Type mayBeBigInt = op->getType().canBeBigInt() ? Type::createBigInt() : Type::createNoType(); Type mayBeBigInt = isBigIntOrObject(op->getType()) ? Type::createBigInt() : Type::createNoType();
// - ?? => Number|?BigInt. BigInt is only possible if op.Type canBeBigInt. // - ?? => Number|?BigInt. BigInt is only possible if op.Type is // BigInt|Object. UOI->setType(Type::unionTy(numberResultType, mayBeBigInt)); return true; } Expand Down Expand Up @@ -298,12 +305,12 @@ static bool inferBinaryArith( return true; }
Type mayBeBigInt = LeftTy.canBeBigInt() && RightTy.canBeBigInt() Type mayBeBigInt = (isBigIntOrObject(LeftTy) && isBigIntOrObject(RightTy)) ? Type::createBigInt() : Type::createNoType();
// ?? - ?? => Number|?BigInt. BigInt is only possible if both operands can be // BigInt due to the no automatic BigInt conversion. // ?? - ?? => Number|?BigInt. BigInt is only possible if both operands are // BigInt|Object due to the no automatic BigInt conversion. BOI->setType(Type::unionTy(numberType, mayBeBigInt)); return true; } Expand All @@ -312,12 +319,12 @@ static bool inferBinaryBitwise(BinaryOperatorInst *BOI) { Type LeftTy = BOI->getLeftHandSide()->getType(); Type RightTy = BOI->getRightHandSide()->getType();
Type mayBeBigInt = LeftTy.canBeBigInt() && RightTy.canBeBigInt() Type mayBeBigInt = (isBigIntOrObject(LeftTy) && isBigIntOrObject(RightTy)) ? Type::createBigInt() : Type::createNoType();
// ?? - ?? => Int32|?BigInt. BigInt is only possible if both operands can be // BigInt due to the no automatic BigInt conversion. // ?? - ?? => Int32|?BigInt. BigInt is only possible if both operands are // BigInt|Object due to the no automatic BigInt conversion. BOI->setType(Type::unionTy(Type::createInt32(), mayBeBigInt)); return true; } Expand Down Expand Up @@ -391,7 +398,7 @@ static bool inferBinaryInst(BinaryOperatorInst *BOI) { // ?BigInt + ?BigInt => ?BigInt. Both operands need to “may be a BigInt” // for a possible BigInt result from this operator. This is true because // there’s no automative BigInt type conversion. Type mayBeBigInt = (LeftTy.canBeBigInt() && RightTy.canBeBigInt()) Type mayBeBigInt = (isBigIntOrObject(LeftTy) && isBigIntOrObject(RightTy)) ? Type::createBigInt() : Type::createNoType();
Expand Down