зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1290481 - P5: Implement a function to generate padding size. r=bkelly
MozReview-Commit-ID: 6poDeyErBjc --HG-- extra : rebase_source : 982139c536c17a6699d700df7c8b3071939bb3c0
This commit is contained in:
Родитель
29522efbef
Коммит
a1e22fa9e7
|
@ -86,6 +86,7 @@ struct CacheResponse
|
|||
CacheReadStreamOrVoid body;
|
||||
IPCChannelInfo channelInfo;
|
||||
OptionalPrincipalInfo principalInfo;
|
||||
uint32_t paddingInfo;
|
||||
int64_t paddingSize;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ using mozilla::dom::quota::QuotaObject;
|
|||
|
||||
namespace {
|
||||
|
||||
// Const variable for generate padding size.
|
||||
// XXX This will be tweaked to something more meaningful in Bug 1383656.
|
||||
const int64_t kRoundUpNumber = 20480;
|
||||
|
||||
enum BodyFileType
|
||||
{
|
||||
BODY_FILE_FINAL,
|
||||
|
@ -42,7 +46,16 @@ BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
|||
nsIFile** aBodyFileOut);
|
||||
|
||||
int64_t
|
||||
BodyGeneratePadding(const int64_t aBodyFileSize);
|
||||
RoundUp(const int64_t aX, const int64_t aY);
|
||||
|
||||
// The alogrithm for generating padding refers to the mitigation approach in
|
||||
// https://github.com/whatwg/storage/issues/31.
|
||||
// First, generate a random number between 0 and 100kB.
|
||||
// Next, round up the sum of random number and response size to the nearest
|
||||
// 20kB.
|
||||
// Finally, the virtual padding size will be the result minus the response size.
|
||||
int64_t
|
||||
BodyGeneratePadding(const int64_t aBodyFileSize, const uint32_t aPaddingInfo);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -254,7 +267,8 @@ BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
|||
// static
|
||||
nsresult
|
||||
BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
const nsID& aId, int64_t* aPaddingSizeOut)
|
||||
const nsID& aId, const uint32_t aPaddingInfo,
|
||||
int64_t* aPaddingSizeOut)
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aBaseDir);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aPaddingSizeOut);
|
||||
|
@ -277,7 +291,7 @@ BodyMaybeUpdatePaddingSize(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
|||
MOZ_DIAGNOSTIC_ASSERT(fileSize >= 0);
|
||||
|
||||
if (*aPaddingSizeOut == InternalResponse::UNKNOWN_PADDING_SIZE) {
|
||||
*aPaddingSizeOut = BodyGeneratePadding(fileSize);
|
||||
*aPaddingSizeOut = BodyGeneratePadding(fileSize, aPaddingInfo);
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(*aPaddingSizeOut >= 0);
|
||||
|
@ -354,10 +368,24 @@ BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
|||
}
|
||||
|
||||
int64_t
|
||||
BodyGeneratePadding(const int64_t aBodyFileSize)
|
||||
RoundUp(const int64_t aX, const int64_t aY)
|
||||
{
|
||||
// XXXtt: Will deal with it in the next patch.
|
||||
return 0;
|
||||
MOZ_DIAGNOSTIC_ASSERT(aX >= 0);
|
||||
MOZ_DIAGNOSTIC_ASSERT(aY > 0);
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - ((aX - 1) / aY) * aY >= aY);
|
||||
return aY + ((aX - 1) / aY) * aY;
|
||||
}
|
||||
|
||||
int64_t
|
||||
BodyGeneratePadding(const int64_t aBodyFileSize, const uint32_t aPaddingInfo)
|
||||
{
|
||||
// Generate padding
|
||||
int64_t randomSize = static_cast<int64_t>(aPaddingInfo);
|
||||
MOZ_DIAGNOSTIC_ASSERT(INT64_MAX - aBodyFileSize >= randomSize);
|
||||
randomSize += aBodyFileSize;
|
||||
|
||||
return RoundUp(randomSize, kRoundUpNumber) - aBodyFileSize;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -785,6 +785,7 @@ private:
|
|||
// It'll generate padding if we've not set it yet.
|
||||
rv = BodyMaybeUpdatePaddingSize(mQuotaInfo.ref(), mDBDir,
|
||||
e.mResponseBodyId,
|
||||
e.mResponse.paddingInfo(),
|
||||
&e.mResponse.paddingSize());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
DoResolve(rv);
|
||||
|
|
|
@ -202,6 +202,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
|
|||
aOut.principalInfo() = void_t();
|
||||
}
|
||||
|
||||
aOut.paddingInfo() = aIn.GetPaddingInfo();
|
||||
aOut.paddingSize() = aIn.GetPaddingSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -433,9 +433,12 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse,
|
|||
case LoadTainting::CORS:
|
||||
filteredResponse = aResponse->CORSResponse();
|
||||
break;
|
||||
case LoadTainting::Opaque:
|
||||
case LoadTainting::Opaque: {
|
||||
filteredResponse = aResponse->OpaqueResponse();
|
||||
nsresult rv = filteredResponse->GeneratePaddingInfo();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; }
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unexpected case");
|
||||
}
|
||||
|
@ -614,6 +617,12 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||
// Resolves fetch() promise which may trigger code running in a worker. Make
|
||||
// sure the Response is fully initialized before calling this.
|
||||
mResponse = BeginAndGetFilteredResponse(response, foundOpaqueRedirect);
|
||||
if (NS_WARN_IF(!mResponse)) {
|
||||
// Fail to generate a paddingInfo for opaque response.
|
||||
MOZ_DIAGNOSTIC_ASSERT(mResponse->Type() == ResponseType::Opaque);
|
||||
FailWithNetworkError();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// From "Main Fetch" step 19: SRI-part1.
|
||||
if (ShouldCheckSRI(mRequest, mResponse) && mSRIMetadata.IsEmpty()) {
|
||||
|
|
|
@ -11,12 +11,21 @@
|
|||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "nsIRandomGenerator.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Const variable for generate padding size
|
||||
// XXX This will be tweaked to something more meaningful in Bug 1383656.
|
||||
const uint32_t kMaxRandomNumber = 102400;
|
||||
|
||||
} // namespace
|
||||
|
||||
InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusText)
|
||||
: mType(ResponseType::Default)
|
||||
, mStatus(aStatus)
|
||||
|
@ -145,6 +154,7 @@ InternalResponse::Clone(CloneType aCloneType)
|
|||
clone->mHeaders = new InternalHeaders(*mHeaders);
|
||||
|
||||
// Make sure the clone response will have the same padding size.
|
||||
clone->mPaddingInfo = mPaddingInfo;
|
||||
clone->mPaddingSize = mPaddingSize;
|
||||
|
||||
if (mWrappedResponse) {
|
||||
|
@ -194,6 +204,52 @@ InternalResponse::CORSResponse()
|
|||
return cors.forget();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
InternalResponse::GetPaddingInfo()
|
||||
{
|
||||
// If it's an opaque response, the paddingInfo should be generated only when
|
||||
// paddingSize is unknown size.
|
||||
// If it's not, the paddingInfo should be nothing and the paddingSize should
|
||||
// be unknown size.
|
||||
MOZ_DIAGNOSTIC_ASSERT((mType == ResponseType::Opaque &&
|
||||
mPaddingSize == UNKNOWN_PADDING_SIZE &&
|
||||
mPaddingInfo.isSome()) ||
|
||||
(mType == ResponseType::Opaque &&
|
||||
mPaddingSize != UNKNOWN_PADDING_SIZE &&
|
||||
mPaddingInfo.isNothing()) ||
|
||||
(mType != ResponseType::Opaque &&
|
||||
mPaddingSize == UNKNOWN_PADDING_SIZE &&
|
||||
mPaddingInfo.isNothing()));
|
||||
return mPaddingInfo.isSome() ? mPaddingInfo.ref() : 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
InternalResponse::GeneratePaddingInfo()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mType == ResponseType::Opaque);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPaddingSize == UNKNOWN_PADDING_SIZE);
|
||||
|
||||
// Utilize random generator to generator a random number
|
||||
nsresult rv;
|
||||
uint32_t randomNumber = 0;
|
||||
nsCOMPtr<nsIRandomGenerator> randomGenerator =
|
||||
do_GetService("@mozilla.org/security/random-generator;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(randomGenerator);
|
||||
|
||||
uint8_t* buffer;
|
||||
rv = randomGenerator->GenerateRandomBytes(sizeof(randomNumber), &buffer);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
memcpy(&randomNumber, buffer, sizeof(randomNumber));
|
||||
free(buffer);
|
||||
|
||||
mPaddingInfo.emplace(randomNumber % kMaxRandomNumber);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int64_t
|
||||
InternalResponse::GetPaddingSize()
|
||||
{
|
||||
|
|
|
@ -233,6 +233,12 @@ public:
|
|||
mBodySize = aBodySize;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GetPaddingInfo();
|
||||
|
||||
nsresult
|
||||
GeneratePaddingInfo();
|
||||
|
||||
int64_t
|
||||
GetPaddingSize();
|
||||
|
||||
|
@ -307,6 +313,9 @@ private:
|
|||
RefPtr<InternalHeaders> mHeaders;
|
||||
nsCOMPtr<nsIInputStream> mBody;
|
||||
int64_t mBodySize;
|
||||
// It's used to passed to the CacheResponse to generate padding size. Once, we
|
||||
// generate the padding size for resposne, we don't need it anymore.
|
||||
Maybe<uint32_t> mPaddingInfo;
|
||||
int64_t mPaddingSize;
|
||||
public:
|
||||
static const int64_t UNKNOWN_BODY_SIZE = -1;
|
||||
|
|
Загрузка…
Ссылка в новой задаче