Modified: trunk/Source/WebCore/ChangeLog (258675 => 258676)
--- trunk/Source/WebCore/ChangeLog 2020-03-19 02:58:33 UTC (rev 258675)
+++ trunk/Source/WebCore/ChangeLog 2020-03-19 03:05:17 UTC (rev 258676)
@@ -1,3 +1,22 @@
+2020-03-18 Fujii Hironori <[email protected]>
+
+ AuthenticatorResponseData::decode should check bufferIsLargeEnoughToContain before allocating buffers
+ https://bugs.webkit.org/show_bug.cgi?id=209133
+
+ Reviewed by Darin Adler.
+
+ Check bufferIsLargeEnoughToContain with the decoded size before
+ allocating buffers.
+
+ Replaced ArrayBuffer::create with ArrayBuffer::tryCreate, and
+ added a null check.
+
+ * Modules/webauthn/AuthenticatorResponseData.h:
+ (WebCore::encodeArrayBuffer): Added.
+ (WebCore::decodeArrayBuffer): Added.
+ (WebCore::AuthenticatorResponseData::encode const):
+ (WebCore::AuthenticatorResponseData::decode):
+
2020-03-18 Andres Gonzalez <[email protected]>
Several TextMarker attributes need to run on the main thread.
Modified: trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h (258675 => 258676)
--- trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h 2020-03-19 02:58:33 UTC (rev 258675)
+++ trunk/Source/WebCore/Modules/webauthn/AuthenticatorResponseData.h 2020-03-19 03:05:17 UTC (rev 258676)
@@ -56,6 +56,31 @@
};
template<class Encoder>
+static void encodeArrayBuffer(Encoder& encoder, const ArrayBuffer& buffer)
+{
+ encoder << static_cast<uint64_t>(buffer.byteLength());
+ encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.byteLength(), 1);
+}
+
+template<class Decoder>
+RefPtr<ArrayBuffer> decodeArrayBuffer(Decoder& decoder)
+{
+ Optional<uint64_t> length;
+ decoder >> length;
+ if (!length)
+ return nullptr;
+
+ if (!decoder.template bufferIsLargeEnoughToContain<uint8_t>(length.value()))
+ return nullptr;
+ auto buffer = ArrayBuffer::tryCreate(length.value(), sizeof(uint8_t));
+ if (!buffer)
+ return nullptr;
+ if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(buffer->data()), length.value(), 1))
+ return nullptr;
+ return buffer;
+}
+
+template<class Encoder>
void AuthenticatorResponseData::encode(Encoder& encoder) const
{
if (!rawId) {
@@ -63,24 +88,19 @@
return;
}
encoder << false;
+ encodeArrayBuffer(encoder, *rawId);
- encoder << static_cast<uint64_t>(rawId->byteLength());
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(rawId->data()), rawId->byteLength(), 1);
-
encoder << isAuthenticatorAttestationResponse;
if (isAuthenticatorAttestationResponse && attestationObject) {
- encoder << static_cast<uint64_t>(attestationObject->byteLength());
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(attestationObject->data()), attestationObject->byteLength(), 1);
+ encodeArrayBuffer(encoder, *attestationObject);
return;
}
if (!authenticatorData || !signature)
return;
- encoder << static_cast<uint64_t>(authenticatorData->byteLength());
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(authenticatorData->data()), authenticatorData->byteLength(), 1);
- encoder << static_cast<uint64_t>(signature->byteLength());
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(signature->data()), signature->byteLength(), 1);
+ encodeArrayBuffer(encoder, *authenticatorData);
+ encodeArrayBuffer(encoder, *signature);
// Encode AppID before user handle to avoid the userHandle flag.
encoder << appid;
@@ -90,8 +110,7 @@
return;
}
encoder << true;
- encoder << static_cast<uint64_t>(userHandle->byteLength());
- encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(userHandle->data()), userHandle->byteLength(), 1);
+ encodeArrayBuffer(encoder, *userHandle);
}
template<class Decoder>
@@ -106,15 +125,10 @@
if (isEmpty.value())
return result;
- Optional<uint64_t> rawIdLength;
- decoder >> rawIdLength;
- if (!rawIdLength)
+ result.rawId = decodeArrayBuffer(decoder);
+ if (!result.rawId)
return WTF::nullopt;
- result.rawId = ArrayBuffer::create(rawIdLength.value(), sizeof(uint8_t));
- if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.rawId->data()), rawIdLength.value(), 1))
- return WTF::nullopt;
-
Optional<bool> isAuthenticatorAttestationResponse;
decoder >> isAuthenticatorAttestationResponse;
if (!isAuthenticatorAttestationResponse)
@@ -122,36 +136,20 @@
result.isAuthenticatorAttestationResponse = isAuthenticatorAttestationResponse.value();
if (result.isAuthenticatorAttestationResponse) {
- Optional<uint64_t> attestationObjectLength;
- decoder >> attestationObjectLength;
- if (!attestationObjectLength)
+ result.attestationObject = decodeArrayBuffer(decoder);
+ if (!result.attestationObject)
return WTF::nullopt;
-
- result.attestationObject = ArrayBuffer::create(attestationObjectLength.value(), sizeof(uint8_t));
- if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.attestationObject->data()), attestationObjectLength.value(), 1))
- return WTF::nullopt;
-
return result;
}
- Optional<uint64_t> authenticatorDataLength;
- decoder >> authenticatorDataLength;
- if (!authenticatorDataLength)
+ result.authenticatorData = decodeArrayBuffer(decoder);
+ if (!result.authenticatorData)
return WTF::nullopt;
- result.authenticatorData = ArrayBuffer::create(authenticatorDataLength.value(), sizeof(uint8_t));
- if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.authenticatorData->data()), authenticatorDataLength.value(), 1))
+ result.signature = decodeArrayBuffer(decoder);
+ if (!result.signature)
return WTF::nullopt;
- Optional<uint64_t> signatureLength;
- decoder >> signatureLength;
- if (!signatureLength)
- return WTF::nullopt;
-
- result.signature = ArrayBuffer::create(signatureLength.value(), sizeof(uint8_t));
- if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.signature->data()), signatureLength.value(), 1))
- return WTF::nullopt;
-
Optional<Optional<bool>> appid;
decoder >> appid;
if (!appid)
@@ -165,15 +163,10 @@
if (!*hasUserHandle)
return result;
- Optional<uint64_t> userHandleLength;
- decoder >> userHandleLength;
- if (!userHandleLength)
+ result.userHandle = decodeArrayBuffer(decoder);
+ if (!result.userHandle)
return WTF::nullopt;
- result.userHandle = ArrayBuffer::create(userHandleLength.value(), sizeof(uint8_t));
- if (!decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(result.userHandle->data()), userHandleLength.value(), 1))
- return WTF::nullopt;
-
return result;
}