From 81d61fa324c2bc96faa8a25e94a8d481e9b35284 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Tue, 3 Sep 2024 10:19:02 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1265036 - Use NS_ABORT_OOM() if try_realloc() fails. r=billm (c30f4f83d5) - Bug 1263292 - Handle calling realloc(0) (r=jld) (f292859ee9) - Bug 1256366 - Remove linear and exponential stats collection from histogram.cc. r=gfritzsche (f9a1c869a1) - Bug 1263953 - Reduce the growth rate of Pickle. r=wmccloskey (6eb5228490) - Bug 1233275 - Copy environment for IPC using NSPR. r=jld (2004db748e) - Bug 1261094 - Improve how MessageChannel::mInterruptStack is used in IPC code, r=jld (56e2c114a4) - Bug 1246931: Include dbus.h in DBus IPC headers, r=shuang (43e797c2d8) - Bug 1264887: Make DBus helpers available on desktop builds, r=shuang (58bff1f640) - Bug 1268130, part 1 - Reimplement ByteLengthIsValid using CheckedInt. r=froydnj (6018e22ae0) - Bug 1268130, part 2 - Make ByteLengthIsValid failures fatal in release builds. r=froydnj (f9d934a498) - Bug 1269365, part 1 - Swap fallible and infallible TArray ParamTraits. r=froydnj (ad423bc04d) - Bug 1269365, part 2 - Make ParamTraits>::Read use infallible allocation. r=froydnj (9b902a5bc4) - Bug 1269365, part 3 - Use infallible array allocation in implementSpecialArrayPickling. r=froydnj (592fe648d3) - Bug 1264820 - Measure IPC reply size in telemetry (r=mccr8) (62c54d3141) - Bug 1268938 - Use the name of the original message in Send for reply telemetry. r=billm (a2de5c6a91) - Bug 1266954: Remove temporary |ScopedClose| from PDU receive code, r=jacheng (cb06315c33) - Bug 1142109 - Fix IPDL tests (r=dvander) (df3f0cda32) - Bug 1177013 - Fix IPDL tests for not allowing CPOWs during sync (r=dvander) (5da0a8a4c9) - Bug 1261307: Convert RIL sockets to |UniquePtr|, r=nfroyd (08609783b3) - Bug 1253622 - Move the mozilla-trace.h generation into moz.build; r=ted (f01dc418bc) - Bug 1267318 ignore cert expiration for mozilla-signed packages, r=dkeeler (7a1ddd6090) - Bug 1029173 - Clean up nsDataSignatureVerifier. r=keeler (f9602341ea) - bug 1267463 - add a more nuanced subject common name fallback option for prerelease channels r=Cykesiopka,jcj (9b55320c9b) - Bug 1253108 - Enable ESLint "strict" rule for PSM. r=keeler (54802bdc38) - Bug 1255425 - part 1 - clearly delineate steps when outputting HSTS preload list; r=keeler (79f73189c8) - Bug 1251801 - Fully implement nsNSSShutDownObject and obviate manual NSS resource management. r=keeler (af32315d3f) - Bug 1251801 - Improve handling of PK11_* function error codes. r=keeler (9f2c8ac64b) - Fix unified-build bustage from bug 1264706. r=bustage (11bc0417c7) - Bug 1265164 - Always use nsCOMPtrs with getNSSDialogs(). r=keeler (ce5a703972) --- dom/plugins/ipc/PluginMessageUtils.cpp | 4 +- dom/plugins/ipc/PluginMessageUtils.h | 4 +- dom/plugins/ipc/PluginModuleChild.h | 3 +- dom/plugins/ipc/PluginModuleParent.h | 3 +- ipc/chromium/src/base/buffer.cc | 9 +- ipc/chromium/src/base/histogram.cc | 17 +- ipc/chromium/src/base/histogram.h | 21 +- ipc/chromium/src/base/pickle.cc | 5 +- ipc/chromium/src/base/process_util_bsd.cc | 7 +- ipc/chromium/src/chrome/common/ipc_message.h | 15 + ipc/dbus/DBusUtils.h | 6 +- ipc/glue/IPCMessageUtils.cpp | 23 ++ ipc/glue/IPCMessageUtils.h | 69 ++-- ipc/glue/MessageChannel.cpp | 23 +- ipc/glue/MessageChannel.h | 3 +- ipc/glue/MessageLink.h | 5 +- ipc/glue/moz.build | 1 + ipc/hal/DaemonSocketPDU.cpp | 2 +- ipc/ipdl/ipdl/lower.py | 16 +- ipc/ipdl/test/cxx/PTestHighestPrio.ipdl | 2 +- ipc/ipdl/test/cxx/PTestRPC.ipdl | 11 +- ipc/ipdl/test/cxx/PTestUrgency.ipdl | 2 +- ipc/ipdl/test/cxx/TestHangs.cpp | 2 + ipc/ipdl/test/cxx/TestInterruptRaces.cpp | 6 +- ipc/ipdl/test/cxx/TestInterruptRaces.h | 10 +- ipc/ipdl/test/cxx/TestRPC.cpp | 88 +---- ipc/ipdl/test/cxx/TestRPC.h | 23 +- ipc/ipdl/test/cxx/TestRaceDeadlock.cpp | 10 +- ipc/ipdl/test/cxx/TestRaceDeadlock.h | 6 +- ipc/ipdl/test/cxx/TestRaceDeferral.cpp | 10 +- ipc/ipdl/test/cxx/TestRaceDeferral.h | 6 +- ipc/moz.build | 2 +- ipc/ril/Ril.cpp | 24 +- ipc/ril/Ril.h | 8 +- ipc/ril/RilSocket.cpp | 10 +- ipc/ril/RilSocket.h | 2 +- ipc/ril/RilSocketConsumer.h | 4 +- netwerk/base/security-prefs.js | 4 +- probes/Makefile.in | 14 - probes/moz.build | 12 + probes/trace-gen.py | 15 + security/apps/AppSignatureVerification.cpp | 30 +- .../certverifier/BRNameMatchingPolicy.cpp | 7 + security/certverifier/BRNameMatchingPolicy.h | 7 +- security/manager/.eslintrc.json | 3 + .../pki/resources/content/certManager.js | 1 + .../pki/resources/content/certpicker.js | 1 + .../pki/resources/content/choosetoken.js | 1 + .../pki/resources/content/clientauthask.js | 1 + .../pki/resources/content/createCertInfo.js | 1 + .../pki/resources/content/deletecert.js | 1 + .../pki/resources/content/device_manager.js | 1 + .../pki/resources/content/downloadcert.js | 1 + .../pki/resources/content/editcerts.js | 1 + .../pki/resources/content/exceptionDialog.js | 1 + .../manager/pki/resources/content/password.js | 2 + .../manager/pki/resources/content/pippki.js | 1 + .../pki/resources/content/protectedAuth.js | 1 + .../pki/resources/content/resetpassword.js | 1 + .../pki/resources/content/viewCertDetails.js | 1 + security/manager/ssl/ScopedNSSTypes.h | 3 + security/manager/ssl/nsCertPicker.cpp | 36 +- .../manager/ssl/nsDataSignatureVerifier.cpp | 164 +++++---- .../manager/ssl/nsDataSignatureVerifier.h | 25 +- security/manager/ssl/nsKeygenHandler.cpp | 20 +- security/manager/ssl/nsKeygenHandler.h | 15 +- security/manager/ssl/nsNSSCallbacks.cpp | 9 +- security/manager/ssl/nsNSSComponent.cpp | 36 +- security/manager/ssl/nsNSSIOLayer.cpp | 9 +- security/manager/ssl/nsNSSIOLayer.h | 13 +- security/manager/ssl/nsPK11TokenDB.cpp | 336 ++++++++++-------- security/manager/ssl/nsPK11TokenDB.h | 25 +- .../browser/browser_bug627234_perwindowpb.js | 3 +- .../mochitest/browser/browser_certViewer.js | 3 +- .../browser/browser_certificateManagerLeak.js | 3 +- .../ssl/tests/mochitest/browser/head.js | 2 + .../mochitest/mixedcontent/backward.html | 2 +- .../tests/mochitest/mixedcontent/bug329869.js | 2 + .../mixedcontent/bug383369step2.html | 2 + .../mixedcontent/bug383369step3.html | 1 + .../tests/mochitest/mixedcontent/iframe.html | 1 + .../tests/mochitest/mixedcontent/iframe2.html | 1 + .../mixedcontent/mixedContentTest.js | 2 + .../mixedcontent/test_bug329869.html | 1 + .../mixedcontent/test_bug383369.html | 1 + .../mixedcontent/test_bug455367.html | 1 + .../mixedcontent/test_bug472986.html | 1 + .../mixedcontent/test_bug477118.html | 1 + .../mixedcontent/test_bug521461.html | 1 + .../mixedcontent/test_cssBefore1.html | 1 + .../mixedcontent/test_cssContent1.html | 1 + .../mixedcontent/test_cssContent2.html | 1 + .../mixedcontent/test_documentWrite1.html | 1 + .../mixedcontent/test_documentWrite2.html | 1 + .../test_dynDelayedUnsecurePicture.html | 1 + .../test_dynDelayedUnsecureXHR.html | 1 + .../test_dynUnsecureBackground.html | 1 + .../test_dynUnsecureIframeRedirect.html | 1 + .../mixedcontent/test_dynUnsecurePicture.html | 1 + .../test_dynUnsecurePicturePreload.html | 1 + .../test_dynUnsecureRedirect.html | 1 + .../test_innerHtmlDelayedUnsecurePicture.html | 1 + .../test_innerHtmlUnsecurePicture.html | 1 + .../mixedcontent/test_javascriptPicture.html | 1 + .../mixedcontent/test_secureAll.html | 1 + .../mixedcontent/test_securePicture.html | 1 + .../mixedcontent/test_unsecureBackground.html | 1 + .../mixedcontent/test_unsecureCSS.html | 1 + .../mixedcontent/test_unsecureIframe.html | 1 + .../mixedcontent/test_unsecureIframe2.html | 1 + .../test_unsecureIframeMetaRedirect.html | 1 + .../test_unsecureIframeRedirect.html | 1 + .../mixedcontent/test_unsecurePicture.html | 1 + .../mixedcontent/test_unsecurePictureDup.html | 1 + .../test_unsecurePictureInIframe.html | 1 + .../mixedcontent/test_unsecureRedirect.html | 1 + .../mixedcontent/unsecurePictureDup.html | 1 + .../nosts_bootstrap.html | 1 + .../plain_bootstrap.html | 1 + .../subdom_bootstrap.html | 1 + .../test_stricttransportsecurity.html | 2 + .../test_sts_privatebrowsing_perwindowpb.html | 5 +- .../tests/unit/sss_readstate_child_worker.js | 1 + .../unit/test_baseline_requirements/moz.build | 2 + .../no-san-older.pem | 17 + .../no-san-older.pem.certspec | 3 + .../san-contains-no-hostnames-older.pem | 18 + ...n-contains-no-hostnames-older.pem.certspec | 4 + ...seline_requirements_subject_common_name.js | 59 ++- .../ssl/tests/unit/test_cert_blocklist.js | 1 + .../tests/unit/test_datasignatureverifier.js | 2 +- .../ssl/tests/unit/test_hash_algorithms.js | 2 + .../tests/unit/test_hash_algorithms_wrap.js | 2 + .../ssl/tests/unit/test_pinning_dynamic.js | 1 + .../tests/unit/test_pinning_header_parsing.js | 1 + .../ssl/tests/unit/test_sss_eviction.js | 1 + .../ssl/tests/unit/test_sss_readstate.js | 1 + .../tests/unit/test_sss_readstate_child.js | 1 + .../tests/unit/test_sss_readstate_empty.js | 1 + .../tests/unit/test_sss_readstate_garbage.js | 1 + .../ssl/tests/unit/test_sss_readstate_huge.js | 1 + .../ssl/tests/unit/test_sss_savestate.js | 1 + .../ssl/tests/unit/test_sts_ipv4_ipv6.js | 2 + .../unit/test_sts_preloadlist_perwindowpb.js | 1 + .../unit/test_sts_preloadlist_selfdestruct.js | 1 + security/manager/tools/dumpGoogleRoots.js | 3 +- security/manager/tools/genRootCAHashes.js | 11 +- security/manager/tools/getHSTSPreloadList.js | 112 ++++-- security/manager/tools/makeCNNICHashes.js | 1 + toolkit/components/telemetry/Histograms.json | 10 + toolkit/components/telemetry/Telemetry.cpp | 13 - 151 files changed, 961 insertions(+), 640 deletions(-) create mode 100644 ipc/glue/IPCMessageUtils.cpp delete mode 100644 probes/Makefile.in create mode 100644 probes/trace-gen.py create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec diff --git a/dom/plugins/ipc/PluginMessageUtils.cpp b/dom/plugins/ipc/PluginMessageUtils.cpp index 5dcc4c4b5f..47653fe6ee 100644 --- a/dom/plugins/ipc/PluginMessageUtils.cpp +++ b/dom/plugins/ipc/PluginMessageUtils.cpp @@ -65,8 +65,8 @@ NPRemoteWindow::NPRemoteWindow() : } ipc::RacyInterruptPolicy -MediateRace(const MessageChannel::Message& parent, - const MessageChannel::Message& child) +MediateRace(const MessageChannel::MessageInfo& parent, + const MessageChannel::MessageInfo& child) { switch (parent.type()) { case PPluginInstance::Msg_Paint__ID: diff --git a/dom/plugins/ipc/PluginMessageUtils.h b/dom/plugins/ipc/PluginMessageUtils.h index 97a1247259..3019ac3231 100644 --- a/dom/plugins/ipc/PluginMessageUtils.h +++ b/dom/plugins/ipc/PluginMessageUtils.h @@ -45,8 +45,8 @@ enum ScriptableObjectType }; mozilla::ipc::RacyInterruptPolicy -MediateRace(const mozilla::ipc::MessageChannel::Message& parent, - const mozilla::ipc::MessageChannel::Message& child); +MediateRace(const mozilla::ipc::MessageChannel::MessageInfo& parent, + const mozilla::ipc::MessageChannel::MessageInfo& child); std::string MungePluginDsoPath(const std::string& path); diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index d06a2a3730..9b383fe877 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -65,7 +65,8 @@ class PluginModuleChild : public PPluginModuleChild typedef mozilla::dom::PCrashReporterChild PCrashReporterChild; protected: virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override { return MediateRace(parent, child); } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index f445c49cd4..de4788df7d 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -147,7 +147,8 @@ public: protected: virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override { return MediateRace(parent, child); } diff --git a/ipc/chromium/src/base/buffer.cc b/ipc/chromium/src/base/buffer.cc index 35559e9513..789a8873ce 100644 --- a/ipc/chromium/src/base/buffer.cc +++ b/ipc/chromium/src/base/buffer.cc @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "buffer.h" +#include "nsDebug.h" Buffer::Buffer() : mBuffer(nullptr), @@ -51,7 +52,7 @@ void Buffer::try_realloc(size_t newlength) { char* buffer = (char*)realloc(mBuffer, newlength); - if (buffer) { + if (buffer || !newlength) { mBuffer = buffer; mReserved = newlength; return; @@ -59,7 +60,9 @@ Buffer::try_realloc(size_t newlength) // If we're growing the buffer, crash. If we're shrinking, then we continue to // use the old (larger) buffer. - MOZ_RELEASE_ASSERT(newlength <= mReserved); + if (newlength > mReserved) { + NS_ABORT_OOM(newlength); + } } void @@ -107,6 +110,8 @@ Buffer::reserve(size_t size) char* Buffer::trade_bytes(size_t count) { + MOZ_RELEASE_ASSERT(count); + char* result = mBuffer; mSize = mReserved = mSize - count; mBuffer = mReserved ? (char*)malloc(mReserved) : nullptr; diff --git a/ipc/chromium/src/base/histogram.cc b/ipc/chromium/src/base/histogram.cc index f5a58c70af..5d2a7ac5e7 100644 --- a/ipc/chromium/src/base/histogram.cc +++ b/ipc/chromium/src/base/histogram.cc @@ -567,7 +567,7 @@ const std::string Histogram::GetAsciiBucketRange(size_t i) const { // Update histogram data with new sample. void Histogram::Accumulate(Sample value, Count count, size_t index) { - sample_.AccumulateWithLinearStats(value, count, index); + sample_.Accumulate(value, count, index); } void Histogram::SetBucketRange(size_t i, Sample value) { @@ -720,9 +720,6 @@ void Histogram::WriteAsciiBucketGraph(double current_size, double max_size, Histogram::SampleSet::SampleSet() : counts_(), sum_(0), - sum_squares_(0), - log_sum_(0), - log_sum_squares_(0), redundant_count_(0), mutex_("Histogram::SampleSet::SampleSet") { } @@ -747,12 +744,11 @@ void Histogram::SampleSet::Accumulate(const OffTheBooksMutexAutoLock& ev, DCHECK_GE(redundant_count_, 0); } -void Histogram::SampleSet::AccumulateWithLinearStats(Sample value, - Count count, - size_t index) { +void Histogram::SampleSet::Accumulate(Sample value, + Count count, + size_t index) { OffTheBooksMutexAutoLock locker(mutex_); Accumulate(locker, value, count, index); - sum_squares_ += static_cast(count) * value * value; } Count Histogram::SampleSet::TotalCount(const OffTheBooksMutexAutoLock& ev) @@ -770,9 +766,6 @@ void Histogram::SampleSet::Add(const SampleSet& other) { OffTheBooksMutexAutoLock locker(mutex_); DCHECK_EQ(counts_.size(), other.counts_.size()); sum_ += other.sum_; - sum_squares_ += other.sum_squares_; - log_sum_ += other.log_sum_; - log_sum_squares_ += other.log_sum_squares_; redundant_count_ += other.redundant_count_; for (size_t index = 0; index < counts_.size(); ++index) counts_[index] += other.counts_[index]; @@ -868,7 +861,7 @@ Histogram::ClassType LinearHistogram::histogram_type() const { } void LinearHistogram::Accumulate(Sample value, Count count, size_t index) { - sample_.AccumulateWithLinearStats(value, count, index); + sample_.Accumulate(value, count, index); } void LinearHistogram::SetRangeDescriptions( diff --git a/ipc/chromium/src/base/histogram.h b/ipc/chromium/src/base/histogram.h index a5a5aebbc8..6cba6a3887 100644 --- a/ipc/chromium/src/base/histogram.h +++ b/ipc/chromium/src/base/histogram.h @@ -353,7 +353,7 @@ class Histogram { void Resize(const Histogram& histogram); // Accessor for histogram to make routine additions. - void AccumulateWithLinearStats(Sample value, Count count, size_t index); + void Accumulate(Sample value, Count count, size_t index); // Arithmetic manipulation of corresponding elements of the set. void Add(const SampleSet& other); @@ -375,15 +375,6 @@ class Histogram { int64_t sum(const OffTheBooksMutexAutoLock& ev) const { return sum_; } - uint64_t sum_squares(const OffTheBooksMutexAutoLock& ev) const { - return sum_squares_; - } - double log_sum(const OffTheBooksMutexAutoLock& ev) const { - return log_sum_; - } - double log_sum_squares(const OffTheBooksMutexAutoLock& ev) const { - return log_sum_squares_; - } int64_t redundant_count(const OffTheBooksMutexAutoLock& ev) const { return redundant_count_; } @@ -396,9 +387,6 @@ class Histogram { const SampleSet& operator=(const SampleSet& other) { counts_ = other.counts_; sum_ = other.sum_; - sum_squares_ = other.sum_squares_; - log_sum_ = other.log_sum_; - log_sum_squares_ = other.log_sum_squares_; redundant_count_ = other.redundant_count_; return *this; } @@ -415,13 +403,6 @@ class Histogram { // Save simple stats locally. Note that this MIGHT get done in base class // without shared memory at some point. int64_t sum_; // sum of samples. - uint64_t sum_squares_; // sum of squares of samples. - - // These fields may or may not be updated at the discretion of the - // histogram. We use the natural log and compute ln(sample+1) so that - // zeros are handled sanely. - double log_sum_; // sum of logs of samples. - double log_sum_squares_; // sum of squares of logs of samples // To help identify memory corruption, we reduntantly save the number of // samples we've accumulated into all of our buckets. We can compare this diff --git a/ipc/chromium/src/base/pickle.cc b/ipc/chromium/src/base/pickle.cc index 209d25133a..3d50784550 100644 --- a/ipc/chromium/src/base/pickle.cc +++ b/ipc/chromium/src/base/pickle.cc @@ -24,6 +24,8 @@ static_assert(MOZ_ALIGNOF(Pickle::memberAlignmentType) >= MOZ_ALIGNOF(uint32_t), // static const int Pickle::kPayloadUnit = 64; +const uint32_t kFastGrowthCap = 128 * 1024; + // We mark a read only pickle with a special capacity_. static const uint32_t kCapacityReadOnly = (uint32_t) -1; @@ -500,7 +502,8 @@ char* Pickle::BeginWrite(uint32_t length, uint32_t alignment) { uint32_t needed_size = header_size_ + new_size; if (needed_size > capacity_) { - Resize(std::max(capacity_ * 2, needed_size)); + double growth_rate = capacity_ < kFastGrowthCap ? 2.0 : 1.4; + Resize(std::max(static_cast(capacity_ * growth_rate), needed_size)); } DCHECK(intptr_t(header_) % alignment == 0); diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc index e10149b1f0..2e032ae9df 100644 --- a/ipc/chromium/src/base/process_util_bsd.cc +++ b/ipc/chromium/src/base/process_util_bsd.cc @@ -12,10 +12,9 @@ #include +#include "nspr.h" #include "base/eintr_wrapper.h" -extern "C" char **environ __attribute__((__visibility__("default"))); - namespace base { void FreeEnvVarsArray(char* array[], int length) @@ -66,6 +65,7 @@ bool LaunchApp(const std::vector& argv, // Existing variables are overwritten by env_vars_to_set. int pos = 0; environment_map combined_env_vars = env_vars_to_set; + char **environ = PR_DuplicateEnvironment(); while(environ[pos] != NULL) { std::string varString = environ[pos]; std::string varName = varString.substr(0, varString.find_first_of('=')); @@ -73,8 +73,9 @@ bool LaunchApp(const std::vector& argv, if (combined_env_vars.find(varName) == combined_env_vars.end()) { combined_env_vars[varName] = varValue; } - pos++; + PR_Free(environ[pos++]); } + PR_Free(environ); int varsLen = combined_env_vars.size() + 1; char** vars = new char*[varsLen]; diff --git a/ipc/chromium/src/chrome/common/ipc_message.h b/ipc/chromium/src/chrome/common/ipc_message.h index 0fffe8c751..df7d5033b0 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.h +++ b/ipc/chromium/src/chrome/common/ipc_message.h @@ -358,6 +358,21 @@ class Message : public Pickle { }; +class MessageInfo { +public: + typedef uint32_t msgid_t; + + explicit MessageInfo(const Message& aMsg) + : mSeqno(aMsg.seqno()), mType(aMsg.type()) {} + + int32_t seqno() const { return mSeqno; } + msgid_t type() const { return mType; } + +private: + int32_t mSeqno; + msgid_t mType; +}; + //------------------------------------------------------------------------------ } // namespace IPC diff --git a/ipc/dbus/DBusUtils.h b/ipc/dbus/DBusUtils.h index 42e046d1ed..1fcc2ed123 100644 --- a/ipc/dbus/DBusUtils.h +++ b/ipc/dbus/DBusUtils.h @@ -19,6 +19,7 @@ #ifndef mozilla_ipc_dbus_dbusutils_h__ #define mozilla_ipc_dbus_dbusutils_h__ +#include #include "mozilla/RefPtr.h" // LOGE and free a D-Bus error @@ -26,16 +27,13 @@ #define LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg) log_and_free_dbus_error(err, __FUNCTION__, msg); #define LOG_AND_FREE_DBUS_ERROR(err) log_and_free_dbus_error(err, __FUNCTION__); -struct DBusError; -struct DBusMessage; - namespace mozilla { namespace ipc { class DBusMessageRefPtr { public: - DBusMessageRefPtr(DBusMessage* aMsg); + explicit DBusMessageRefPtr(DBusMessage* aMsg); ~DBusMessageRefPtr(); operator DBusMessage* () diff --git a/ipc/glue/IPCMessageUtils.cpp b/ipc/glue/IPCMessageUtils.cpp new file mode 100644 index 0000000000..0e6e258f63 --- /dev/null +++ b/ipc/glue/IPCMessageUtils.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "IPCMessageUtils.h" +#include "mozilla/CheckedInt.h" + +namespace IPC { + +bool +ByteLengthIsValid(uint32_t aNumElements, size_t aElementSize, int* aByteLength) +{ + auto length = CheckedInt(aNumElements) * aElementSize; + if (!length.isValid()) { + return false; + } + *aByteLength = length.value(); + return true; +} + +} // namespace IPC diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index 202aa440cb..6fb40ff4e6 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -421,10 +421,19 @@ struct ParamTraits : ParamTraits typedef nsLiteralString paramType; }; +// Pickle::ReadBytes and ::WriteBytes take the length in ints, so we must +// ensure there is no overflow. This returns |false| if it would overflow. +// Otherwise, it returns |true| and places the byte length in |aByteLength|. +bool ByteLengthIsValid(uint32_t aNumElements, size_t aElementSize, int* aByteLength); + +// Note: IPDL will sometimes codegen specialized implementations of +// nsTArray serialization and deserialization code in +// implementSpecialArrayPickling(). This is needed when ParamTraits +// is not defined. template -struct ParamTraits > +struct ParamTraits> { - typedef FallibleTArray paramType; + typedef nsTArray paramType; // We write arrays of integer or floating-point data using a single pickling // call, rather than writing each element individually. We deliberately do @@ -434,29 +443,6 @@ struct ParamTraits > static const bool sUseWriteBytes = (mozilla::IsIntegral::value || mozilla::IsFloatingPoint::value); - // Compute the byte length for |aNumElements| of type E. If that length - // would overflow an int, return false. Otherwise, return true and place - // the byte length in |aTotalLength|. - // - // Pickle's ReadBytes/WriteBytes interface takes lengths in ints, hence this - // dance. - static bool ByteLengthIsValid(size_t aNumElements, int* aTotalLength) { - static_assert(sizeof(int) == sizeof(int32_t), "int is an unexpected size!"); - - // nsTArray only handles sizes up to INT32_MAX. - if (aNumElements > size_t(INT32_MAX)) { - return false; - } - - int64_t numBytes = static_cast(aNumElements) * sizeof(E); - if (numBytes > int64_t(INT32_MAX)) { - return false; - } - - *aTotalLength = static_cast(numBytes); - return true; - } - static void Write(Message* aMsg, const paramType& aParam) { uint32_t length = aParam.Length(); @@ -464,8 +450,7 @@ struct ParamTraits > if (sUseWriteBytes) { int pickledLength = 0; - mozilla::DebugOnly valid = ByteLengthIsValid(length, &pickledLength); - MOZ_ASSERT(valid); + MOZ_RELEASE_ASSERT(ByteLengthIsValid(length, sizeof(E), &pickledLength)); aMsg->WriteBytes(aParam.Elements(), pickledLength); } else { for (uint32_t index = 0; index < length; index++) { @@ -474,6 +459,8 @@ struct ParamTraits > } } + // This method uses infallible allocation so that an OOM failure will + // show up as an OOM crash rather than an IPC FatalError. static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { uint32_t length; @@ -483,7 +470,7 @@ struct ParamTraits > if (sUseWriteBytes) { int pickledLength = 0; - if (!ByteLengthIsValid(length, &pickledLength)) { + if (!ByteLengthIsValid(length, sizeof(E), &pickledLength)) { return false; } @@ -492,20 +479,14 @@ struct ParamTraits > return false; } - E* elements = aResult->AppendElements(length, mozilla::fallible); - if (!elements) { - return false; - } + E* elements = aResult->AppendElements(length); memcpy(elements, outdata, pickledLength); } else { - if (!aResult->SetCapacity(length, mozilla::fallible)) { - return false; - } + aResult->SetCapacity(length); for (uint32_t index = 0; index < length; index++) { - E* element = aResult->AppendElement(mozilla::fallible); - MOZ_ASSERT(element); + E* element = aResult->AppendElement(); if (!ReadParam(aMsg, aIter, element)) { return false; } @@ -527,19 +508,19 @@ struct ParamTraits > }; template -struct ParamTraits > +struct ParamTraits> { - typedef InfallibleTArray paramType; + typedef FallibleTArray paramType; static void Write(Message* aMsg, const paramType& aParam) { - WriteParam(aMsg, static_cast&>(aParam)); + WriteParam(aMsg, static_cast&>(aParam)); } - // deserialize the array fallibly, but return an InfallibleTArray + // Deserialize the array infallibly, but return a FallibleTArray. static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { - FallibleTArray temp; + nsTArray temp; if (!ReadParam(aMsg, aIter, &temp)) return false; @@ -549,7 +530,7 @@ struct ParamTraits > static void Log(const paramType& aParam, std::wstring* aLog) { - LogParam(static_cast&>(aParam), aLog); + LogParam(static_cast&>(aParam), aLog); } }; @@ -797,7 +778,7 @@ struct ParamTraits }; template -struct ParamTraits< mozilla::Maybe > +struct ParamTraits> { typedef mozilla::Maybe paramType; diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index e5d8d49e5d..86a8f1ccdd 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -758,7 +758,7 @@ MessageChannel::Send(Message* aMsg) { if (aMsg->capacity() >= kMinTelemetryMessageSize) { Telemetry::Accumulate(Telemetry::IPC_MESSAGE_SIZE, - nsCString(aMsg->name()), aMsg->capacity()); + nsDependentCString(aMsg->name()), aMsg->capacity()); } CxxStackFrame frame(*this, OUT_MESSAGE, aMsg); @@ -1059,7 +1059,7 @@ MessageChannel::Send(Message* aMsg, Message* aReply) { if (aMsg->capacity() >= kMinTelemetryMessageSize) { Telemetry::Accumulate(Telemetry::IPC_MESSAGE_SIZE, - nsCString(aMsg->name()), aMsg->capacity()); + nsDependentCString(aMsg->name()), aMsg->capacity()); } nsAutoPtr msg(aMsg); @@ -1158,6 +1158,9 @@ MessageChannel::Send(Message* aMsg, Message* aReply) IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction); + // msg will be destroyed soon, but name() is not owned by msg. + const char* msgName = msg->name(); + mLink->SendMessage(msg.forget()); while (true) { @@ -1244,6 +1247,10 @@ MessageChannel::Send(Message* aMsg, Message* aReply) MOZ_RELEASE_ASSERT(reply->is_sync()); *aReply = Move(*reply); + if (aReply->capacity() >= kMinTelemetryMessageSize) { + Telemetry::Accumulate(Telemetry::IPC_REPLY_SIZE, + nsDependentCString(msgName), aReply->capacity()); + } return true; } @@ -1284,7 +1291,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply) msg->set_seqno(NextSeqno()); msg->set_interrupt_remote_stack_depth_guess(mRemoteStackDepthGuess); msg->set_interrupt_local_stack_depth(1 + InterruptStackDepth()); - mInterruptStack.push(*msg); + mInterruptStack.push(MessageInfo(*msg)); mLink->SendMessage(msg.forget()); while (true) { @@ -1369,7 +1376,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply) // If this is not a reply the call we've initiated, add it to our // out-of-turn replies and keep polling for events. { - const Message &outcall = mInterruptStack.top(); + const MessageInfo &outcall = mInterruptStack.top(); // Note, In the parent, sequence numbers increase from 0, and // in the child, they decrease from 0. @@ -1671,9 +1678,11 @@ MessageChannel::DispatchInterruptMessage(const Message& aMsg, size_t stackDepth) // processing of the other side's in-call. bool defer; const char* winner; - const Message& parentMsg = (mSide == ChildSide) ? aMsg : mInterruptStack.top(); - const Message& childMsg = (mSide == ChildSide) ? mInterruptStack.top() : aMsg; - switch (mListener->MediateInterruptRace(parentMsg, childMsg)) + const MessageInfo parentMsgInfo = + (mSide == ChildSide) ? MessageInfo(aMsg) : mInterruptStack.top(); + const MessageInfo childMsgInfo = + (mSide == ChildSide) ? mInterruptStack.top() : MessageInfo(aMsg); + switch (mListener->MediateInterruptRace(parentMsgInfo, childMsgInfo)) { case RIPChildWins: winner = "child"; diff --git a/ipc/glue/MessageChannel.h b/ipc/glue/MessageChannel.h index d73a0c28fc..8660f6496c 100644 --- a/ipc/glue/MessageChannel.h +++ b/ipc/glue/MessageChannel.h @@ -74,6 +74,7 @@ class MessageChannel : HasResultCodes static const int32_t kNoTimeout; typedef IPC::Message Message; + typedef IPC::MessageInfo MessageInfo; typedef mozilla::ipc::Transport Transport; explicit MessageChannel(MessageListener *aListener); @@ -643,7 +644,7 @@ class MessageChannel : HasResultCodes // Each stack refers to a different protocol and the stacks are mutually // exclusive: multiple outcalls of the same kind cannot be initiated while // another is active. - std::stack mInterruptStack; + std::stack mInterruptStack; // This is what we think the Interrupt stack depth is on the "other side" of this // Interrupt channel. We maintain this variable so that we can detect racy Interrupt diff --git a/ipc/glue/MessageLink.h b/ipc/glue/MessageLink.h index d0ad978dbd..aa189bb858 100644 --- a/ipc/glue/MessageLink.h +++ b/ipc/glue/MessageLink.h @@ -62,6 +62,7 @@ class MessageListener public: MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MessageListener) typedef IPC::Message Message; + typedef IPC::MessageInfo MessageInfo; virtual ~MessageListener() { } @@ -120,8 +121,8 @@ class MessageListener virtual void OnExitedCall() { NS_RUNTIMEABORT("default impl shouldn't be invoked"); } - virtual RacyInterruptPolicy MediateInterruptRace(const Message& parent, - const Message& child) + virtual RacyInterruptPolicy MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) { return RIPChildWins; } diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index 1d00648167..2db7affe11 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -114,6 +114,7 @@ UNIFIED_SOURCES += [ 'FileDescriptor.cpp', 'FileDescriptorUtils.cpp', 'InputStreamUtils.cpp', + 'IPCMessageUtils.cpp', 'MessageChannel.cpp', 'MessageLink.cpp', 'MessagePump.cpp', diff --git a/ipc/hal/DaemonSocketPDU.cpp b/ipc/hal/DaemonSocketPDU.cpp index e92d4cbcdc..de6aa0da7b 100644 --- a/ipc/hal/DaemonSocketPDU.cpp +++ b/ipc/hal/DaemonSocketPDU.cpp @@ -150,7 +150,7 @@ DaemonSocketPDU::Receive(int aFd) size_t fdCount = (chdr->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))) / sizeof(int); for (size_t i = 0; i < fdCount; i++) { int* receivedFd = static_cast(CMSG_DATA(chdr)) + i; - mReceivedFds.AppendElement(ScopedClose(*receivedFd)); + mReceivedFds.AppendElement(*receivedFd); } } diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 46d60a0a9e..043eb2b5f9 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -327,18 +327,12 @@ def _cxxManagedContainerType(basetype, const=0, ref=0): return Type('ManagedContainer', T=basetype, const=const, ref=ref, hasimplicitcopyctor=False) -def _cxxFallibleArrayType(basetype, const=0, ref=0): - return Type('FallibleTArray', T=basetype, const=const, ref=ref) - def _callCxxArrayLength(arr): return ExprCall(ExprSelect(arr, '.', 'Length')) -def _callCxxCheckedArraySetLength(arr, lenexpr, sel='.'): - ifbad = StmtIf(ExprNot(ExprCall(ExprSelect(arr, sel, 'SetLength'), - args=[ lenexpr, ExprVar('mozilla::fallible') ]))) - ifbad.addifstmt(_fatalError('Error setting the array length')) - ifbad.addifstmt(StmtReturn.FALSE) - return ifbad +def _callCxxArraySetLength(arr, lenexpr, sel='.'): + return ExprCall(ExprSelect(arr, sel, 'SetLength'), + args=[ lenexpr ]) def _callCxxSwapArrayElements(arr1, arr2, sel='.'): return ExprCall(ExprSelect(arr1, sel, 'SwapElements'), @@ -4449,14 +4443,14 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): msgvar, itervar, errfnRead, eltipdltype.name() + '[i]')) read.addstmts([ - StmtDecl(Decl(_cxxFallibleArrayType(_cxxBareType(arraytype.basetype, self.side)), favar.name)), + StmtDecl(Decl(_cxxArrayType(_cxxBareType(arraytype.basetype, self.side)), favar.name)), StmtDecl(Decl(Type.UINT32, lenvar.name)), self.checkedRead(None, ExprAddrOf(lenvar), msgvar, itervar, errfnRead, 'length\' (' + Type.UINT32.name + ') of \'' + arraytype.name()), Whitespace.NL, - _callCxxCheckedArraySetLength(favar, lenvar), + StmtExpr(_callCxxArraySetLength(favar, lenvar)), forread, StmtExpr(_callCxxSwapArrayElements(var, favar, '->')), StmtReturn.TRUE diff --git a/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl b/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl index ce3a41b546..692b7e83b1 100644 --- a/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl +++ b/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl @@ -5,7 +5,7 @@ prio(normal upto urgent) sync protocol PTestHighestPrio { parent: prio(urgent) async Msg1(); - sync Msg2(); + prio(high) sync Msg2(); prio(urgent) async Msg3(); prio(urgent) sync Msg4(); diff --git a/ipc/ipdl/test/cxx/PTestRPC.ipdl b/ipc/ipdl/test/cxx/PTestRPC.ipdl index 177467364f..dc214fcc20 100644 --- a/ipc/ipdl/test/cxx/PTestRPC.ipdl +++ b/ipc/ipdl/test/cxx/PTestRPC.ipdl @@ -7,19 +7,14 @@ parent: prio(high) sync Test1_Start() returns (uint32_t result); prio(high) sync Test1_InnerEvent() returns (uint32_t result); async Test2_Start(); - prio(high) sync Test2_Msg2(); - prio(high) sync Test2_FirstUrgent(); - prio(high) sync Test2_SecondUrgent(); - sync Test3_Start() returns (uint32_t result); - prio(high) sync Test3_InnerEvent() returns (uint32_t result); + prio(high) sync Test2_OutOfOrder(); child: async Start(); prio(high) sync Test1_InnerQuery() returns (uint32_t result); prio(high) sync Test1_NoReenter() returns (uint32_t result); - prio(high) sync Test2_Msg1(); - prio(high) sync Test2_Msg3(); - prio(high) sync Test3_WakeUp() returns (uint32_t result); + prio(high) sync Test2_FirstUrgent(); + prio(high) sync Test2_SecondUrgent(); }; } // namespace _ipdltest diff --git a/ipc/ipdl/test/cxx/PTestUrgency.ipdl b/ipc/ipdl/test/cxx/PTestUrgency.ipdl index dcc7253336..d1ae87e6fd 100644 --- a/ipc/ipdl/test/cxx/PTestUrgency.ipdl +++ b/ipc/ipdl/test/cxx/PTestUrgency.ipdl @@ -4,7 +4,7 @@ namespace _ipdltest { prio(normal upto high) sync protocol PTestUrgency { parent: - sync Test1() returns (uint32_t result); + prio(high) sync Test1() returns (uint32_t result); async Test2(); sync Test3() returns (uint32_t result); sync FinalTest_Begin(); diff --git a/ipc/ipdl/test/cxx/TestHangs.cpp b/ipc/ipdl/test/cxx/TestHangs.cpp index 8588cee67b..ef80e02e15 100644 --- a/ipc/ipdl/test/cxx/TestHangs.cpp +++ b/ipc/ipdl/test/cxx/TestHangs.cpp @@ -84,6 +84,8 @@ TestHangsParent::ShouldContinueFromReplyTimeout() MessageLoop::current()->PostTask( FROM_HERE, NewRunnableMethod(this, &TestHangsParent::CleanUp)); + GetIPCChannel()->CloseWithTimeout(); + return false; } diff --git a/ipc/ipdl/test/cxx/TestInterruptRaces.cpp b/ipc/ipdl/test/cxx/TestInterruptRaces.cpp index 295859a98e..a5a566777a 100644 --- a/ipc/ipdl/test/cxx/TestInterruptRaces.cpp +++ b/ipc/ipdl/test/cxx/TestInterruptRaces.cpp @@ -16,11 +16,11 @@ namespace mozilla { namespace _ipdltest { ipc::RacyInterruptPolicy -MediateRace(const MessageChannel::Message& parent, - const MessageChannel::Message& child) +MediateRace(const MessageChannel::MessageInfo& parent, + const MessageChannel::MessageInfo& child) { return (PTestInterruptRaces::Msg_Child__ID == parent.type()) ? - ipc::RIPParentWins : ipc::RIPChildWins; + ipc::RIPParentWins : ipc::RIPChildWins; } //----------------------------------------------------------------------------- diff --git a/ipc/ipdl/test/cxx/TestInterruptRaces.h b/ipc/ipdl/test/cxx/TestInterruptRaces.h index 92891a22ac..f83c49fd11 100644 --- a/ipc/ipdl/test/cxx/TestInterruptRaces.h +++ b/ipc/ipdl/test/cxx/TestInterruptRaces.h @@ -10,8 +10,8 @@ namespace mozilla { namespace _ipdltest { mozilla::ipc::RacyInterruptPolicy -MediateRace(const mozilla::ipc::MessageChannel::Message& parent, - const mozilla::ipc::MessageChannel::Message& child); +MediateRace(const mozilla::ipc::MessageChannel::MessageInfo& parent, + const mozilla::ipc::MessageChannel::MessageInfo& child); class TestInterruptRacesParent : public PTestInterruptRacesParent @@ -48,7 +48,8 @@ protected: RecvGetAnsweredParent(bool* answeredParent) override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override { return MediateRace(parent, child); } @@ -105,7 +106,8 @@ protected: AnswerChild() override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override { return MediateRace(parent, child); } diff --git a/ipc/ipdl/test/cxx/TestRPC.cpp b/ipc/ipdl/test/cxx/TestRPC.cpp index 86745f8a5b..2dfc51d33b 100644 --- a/ipc/ipdl/test/cxx/TestRPC.cpp +++ b/ipc/ipdl/test/cxx/TestRPC.cpp @@ -14,6 +14,8 @@ namespace _ipdltest { // parent TestRPCParent::TestRPCParent() + : reentered_(false), + resolved_first_cpow_(false) { MOZ_COUNT_CTOR(TestRPCParent); } @@ -59,46 +61,25 @@ TestRPCParent::RecvTest1_InnerEvent(uint32_t* aResult) bool TestRPCParent::RecvTest2_Start() { - if (!SendTest2_Msg1()) - fail("SendTest2_Msg1"); + // Send a CPOW. During this time, we must NOT process the RPC message, as + // we could start receiving CPOW replies out-of-order. + if (!SendTest2_FirstUrgent()) + fail("SendTest2_FirstUrgent"); + MOZ_ASSERT(!reentered_); + resolved_first_cpow_ = true; return true; } bool -TestRPCParent::RecvTest2_Msg2() +TestRPCParent::RecvTest2_OutOfOrder() { - if (!SendTest2_Msg3()) - fail("SendTest2_Msg3"); + // Send a CPOW. If this RPC call was initiated while waiting for the first + // CPOW to resolve, replies will be processed out of order, and we'll crash. + if (!SendTest2_SecondUrgent()) + fail("SendTest2_SecondUrgent"); - return true; -} - -bool -TestRPCParent::RecvTest2_FirstUrgent() -{ - return true; -} - -bool -TestRPCParent::RecvTest2_SecondUrgent() -{ - return true; -} - -bool -TestRPCParent::RecvTest3_Start(uint32_t* aResult) -{ - if (!SendTest3_WakeUp(aResult)) - fail("SendTest3_WakeUp"); - - return true; -} - -bool -TestRPCParent::RecvTest3_InnerEvent(uint32_t* aResult) -{ - *aResult = 200; + reentered_ = true; return true; } @@ -107,8 +88,6 @@ TestRPCParent::RecvTest3_InnerEvent(uint32_t* aResult) TestRPCChild::TestRPCChild() - : reentered_(false), - resolved_first_cpow_(false) { MOZ_COUNT_CTOR(TestRPCChild); } @@ -130,14 +109,8 @@ TestRPCChild::RecvStart() if (!SendTest2_Start()) fail("SendTest2_Start"); - if (!SendTest2_Msg2()) - fail("SendTest2_Msg2"); - - result = 0; - if (!SendTest3_Start(&result)) - fail("SendTest3_Start"); - if (result != 200) - fail("Wrong result (expected 200)"); + if (!SendTest2_OutOfOrder()) + fail("SendTest2_OutOfOrder"); Close(); return true; @@ -163,38 +136,15 @@ TestRPCChild::RecvTest1_NoReenter(uint32_t* aResult) return true; } -bool TestRPCChild::RecvTest2_Msg1() +bool +TestRPCChild::RecvTest2_FirstUrgent() { - MOZ_ASSERT(resolved_first_cpow_); - - // Send a CPOW. If this RPC call was initiated while waiting for the first - // CPOW to resolve, replies will be processed out of order, and we'll crash. - if (!SendTest2_SecondUrgent()) - fail("SendTest2_SecondUrgent"); - - reentered_ = true; return true; } bool -TestRPCChild::RecvTest2_Msg3() +TestRPCChild::RecvTest2_SecondUrgent() { - // Send a CPOW. During this time, we must NOT process the RPC message, as - // we could start receiving CPOW replies out-of-order. - if (!SendTest2_FirstUrgent()) - fail("SendTest2_FirstUrgent"); - - MOZ_ASSERT(!reentered_); - resolved_first_cpow_ = true; - return true; -} - -bool -TestRPCChild::RecvTest3_WakeUp(uint32_t* aResult) -{ - if (!SendTest3_InnerEvent(aResult)) - fail("SendTest3_InnerEvent"); - return true; } diff --git a/ipc/ipdl/test/cxx/TestRPC.h b/ipc/ipdl/test/cxx/TestRPC.h index b65b71424a..0a11b3e761 100644 --- a/ipc/ipdl/test/cxx/TestRPC.h +++ b/ipc/ipdl/test/cxx/TestRPC.h @@ -25,19 +25,23 @@ public: bool RecvTest1_Start(uint32_t* aResult) override; bool RecvTest1_InnerEvent(uint32_t* aResult) override; bool RecvTest2_Start() override; - bool RecvTest2_Msg2() override; - bool RecvTest2_FirstUrgent() override; - bool RecvTest2_SecondUrgent() override; - bool RecvTest3_Start(uint32_t* aResult) override; - bool RecvTest3_InnerEvent(uint32_t* aResult) override; + bool RecvTest2_OutOfOrder() override; virtual void ActorDestroy(ActorDestroyReason why) override { if (NormalShutdown != why) fail("unexpected destruction!"); + if (!reentered_) + fail("never processed raced RPC call!"); + if (!resolved_first_cpow_) + fail("never resolved first CPOW!"); passed("ok"); QuitParent(); } + +private: + bool reentered_; + bool resolved_first_cpow_; }; @@ -51,9 +55,8 @@ public: bool RecvStart() override; bool RecvTest1_InnerQuery(uint32_t* aResult) override; bool RecvTest1_NoReenter(uint32_t* aResult) override; - bool RecvTest2_Msg1() override; - bool RecvTest2_Msg3() override; - bool RecvTest3_WakeUp(uint32_t* aResult) override; + bool RecvTest2_FirstUrgent() override; + bool RecvTest2_SecondUrgent() override; virtual void ActorDestroy(ActorDestroyReason why) override { @@ -61,10 +64,6 @@ public: fail("unexpected destruction!"); QuitChild(); } - -private: - bool reentered_; - bool resolved_first_cpow_; }; diff --git a/ipc/ipdl/test/cxx/TestRaceDeadlock.cpp b/ipc/ipdl/test/cxx/TestRaceDeadlock.cpp index 1d6ec4f58b..2ad3a74958 100644 --- a/ipc/ipdl/test/cxx/TestRaceDeadlock.cpp +++ b/ipc/ipdl/test/cxx/TestRaceDeadlock.cpp @@ -11,7 +11,7 @@ namespace mozilla { namespace _ipdltest { static RacyInterruptPolicy -MediateRace(const Message& parent, const Message& child) +MediateRace(const MessageInfo& parent, const MessageInfo& child) { return (PTestRaceDeadlock::Msg_Win__ID == parent.type()) ? RIPParentWins : RIPChildWins; @@ -67,8 +67,8 @@ TestRaceDeadlockParent::AnswerLose() } RacyInterruptPolicy -TestRaceDeadlockParent::MediateInterruptRace(const Message& parent, - const Message& child) +TestRaceDeadlockParent::MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) { return MediateRace(parent, child); } @@ -120,8 +120,8 @@ TestRaceDeadlockChild::AnswerRpc() } RacyInterruptPolicy -TestRaceDeadlockChild::MediateInterruptRace(const Message& parent, - const Message& child) +TestRaceDeadlockChild::MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) { return MediateRace(parent, child); } diff --git a/ipc/ipdl/test/cxx/TestRaceDeadlock.h b/ipc/ipdl/test/cxx/TestRaceDeadlock.h index 6bb8012898..7723c7629a 100644 --- a/ipc/ipdl/test/cxx/TestRaceDeadlock.h +++ b/ipc/ipdl/test/cxx/TestRaceDeadlock.h @@ -30,7 +30,8 @@ protected: virtual bool AnswerLose() override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override; + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override; virtual void ActorDestroy(ActorDestroyReason why) override { @@ -57,7 +58,8 @@ protected: virtual bool AnswerRpc() override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override; + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override; virtual void ActorDestroy(ActorDestroyReason why) override { diff --git a/ipc/ipdl/test/cxx/TestRaceDeferral.cpp b/ipc/ipdl/test/cxx/TestRaceDeferral.cpp index 81acae975a..2b88fc87b8 100644 --- a/ipc/ipdl/test/cxx/TestRaceDeferral.cpp +++ b/ipc/ipdl/test/cxx/TestRaceDeferral.cpp @@ -9,7 +9,7 @@ namespace mozilla { namespace _ipdltest { static RacyInterruptPolicy -MediateRace(const Message& parent, const Message& child) +MediateRace(const MessageInfo& parent, const MessageInfo& child) { return (PTestRaceDeferral::Msg_Win__ID == parent.type()) ? RIPParentWins : RIPChildWins; @@ -67,8 +67,8 @@ TestRaceDeferralParent::AnswerLose() } RacyInterruptPolicy -TestRaceDeferralParent::MediateInterruptRace(const Message& parent, - const Message& child) +TestRaceDeferralParent::MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) { return MediateRace(parent, child); } @@ -107,8 +107,8 @@ TestRaceDeferralChild::AnswerRpc() } RacyInterruptPolicy -TestRaceDeferralChild::MediateInterruptRace(const Message& parent, - const Message& child) +TestRaceDeferralChild::MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) { return MediateRace(parent, child); } diff --git a/ipc/ipdl/test/cxx/TestRaceDeferral.h b/ipc/ipdl/test/cxx/TestRaceDeferral.h index 6f9cc4a06a..e465cf77c8 100644 --- a/ipc/ipdl/test/cxx/TestRaceDeferral.h +++ b/ipc/ipdl/test/cxx/TestRaceDeferral.h @@ -27,7 +27,8 @@ protected: virtual bool AnswerLose() override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override; + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override; virtual void ActorDestroy(ActorDestroyReason why) override { @@ -56,7 +57,8 @@ protected: virtual bool AnswerRpc() override; virtual mozilla::ipc::RacyInterruptPolicy - MediateInterruptRace(const Message& parent, const Message& child) override; + MediateInterruptRace(const MessageInfo& parent, + const MessageInfo& child) override; virtual void ActorDestroy(ActorDestroyReason why) override { diff --git a/ipc/moz.build b/ipc/moz.build index ab07dc6945..0a05646cb3 100644 --- a/ipc/moz.build +++ b/ipc/moz.build @@ -14,7 +14,7 @@ DIRS += [ if CONFIG['MOZ_B2G_RIL']: DIRS += ['ril'] -if CONFIG['MOZ_B2G_BT_BLUEZ']: +if CONFIG['MOZ_ENABLE_DBUS'] or CONFIG['MOZ_B2G_BT_BLUEZ']: DIRS += ['dbus'] if CONFIG['MOZ_NFC']: diff --git a/ipc/ril/Ril.cpp b/ipc/ril/Ril.cpp index 68b532ef5e..0975aa0adc 100644 --- a/ipc/ril/Ril.cpp +++ b/ipc/ril/Ril.cpp @@ -38,7 +38,7 @@ class RilConsumer; static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy"; -static nsTArray> sRilConsumers; +static nsTArray> sRilConsumers; // // RilConsumer @@ -60,7 +60,7 @@ public: void ReceiveSocketData(JSContext* aCx, int aIndex, - nsAutoPtr& aBuffer) override; + UniquePtr& aBuffer) override; void OnConnectSuccess(int aIndex) override; void OnConnectError(int aIndex) override; void OnDisconnect(int aIndex) override; @@ -179,7 +179,7 @@ RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs) return NS_OK; } - nsAutoPtr raw; + UniquePtr raw; Value v = aArgs[1]; @@ -190,7 +190,7 @@ RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs) return NS_ERROR_FAILURE; } - raw = new UnixSocketRawData(abs.ptr(), abs.length()); + raw = MakeUnique(abs.ptr(), abs.length()); } else if (!v.isPrimitive()) { JSObject* obj = v.toObjectOrNull(); if (!JS_IsTypedArrayObject(obj)) { @@ -218,7 +218,7 @@ RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs) aCx, "Incorrect argument. Shared memory not supported"); return NS_ERROR_FAILURE; } - raw = new UnixSocketRawData(data, size); + raw = MakeUnique(data, size); } else { JS_ReportError( aCx, "Incorrect argument. Expecting a string or a typed array"); @@ -230,7 +230,7 @@ RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs) return NS_ERROR_FAILURE; } - mSocket->SendSocketData(raw.forget()); + mSocket->SendSocketData(raw.release()); return NS_OK; } @@ -280,9 +280,9 @@ RilConsumer::Close() void RilConsumer::ReceiveSocketData(JSContext* aCx, int aIndex, - nsAutoPtr& aBuffer) + UniquePtr& aBuffer) { - Receive(aCx, (uint32_t)aIndex, aBuffer); + Receive(aCx, (uint32_t)aIndex, aBuffer.get()); } void @@ -314,7 +314,7 @@ RilConsumer::OnDisconnect(int aIndex) // RilWorker // -nsTArray> RilWorker::sRilWorkers; +nsTArray> RilWorker::sRilWorkers; nsresult RilWorker::Register(unsigned int aClientId, @@ -330,7 +330,7 @@ RilWorker::Register(unsigned int aClientId, } // Now that we're set up, connect ourselves to the RIL thread. - sRilWorkers[aClientId] = new RilWorker(aDispatcher); + sRilWorkers[aClientId] = MakeUnique(aDispatcher); nsresult rv = sRilWorkers[aClientId]->RegisterConsumer(aClientId); if (NS_FAILED(rv)) { @@ -377,7 +377,7 @@ public: MOZ_ASSERT(!sRilConsumers[mClientId]); - nsAutoPtr rilConsumer(new RilConsumer()); + auto rilConsumer = MakeUnique(); nsresult rv = rilConsumer->ConnectWorkerToRIL(aCx); if (NS_FAILED(rv)) { @@ -388,7 +388,7 @@ public: if (NS_FAILED(rv)) { return false; } - sRilConsumers[mClientId] = rilConsumer; + sRilConsumers[mClientId] = Move(rilConsumer); return true; } diff --git a/ipc/ril/Ril.h b/ipc/ril/Ril.h index 22164c3dad..206d3977ef 100644 --- a/ipc/ril/Ril.h +++ b/ipc/ril/Ril.h @@ -7,7 +7,6 @@ #ifndef mozilla_ipc_Ril_h #define mozilla_ipc_Ril_h 1 -#include "nsAutoPtr.h" #include "nsError.h" #include "nsTArray.h" @@ -34,16 +33,17 @@ public: static void Shutdown(); + // Public for |MakeUnique| Call |Register| instead. + RilWorker(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher); + private: class RegisterConsumerTask; class UnregisterConsumerTask; - RilWorker(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher); - nsresult RegisterConsumer(unsigned int aClientId); void UnregisterConsumer(unsigned int aClientId); - static nsTArray> sRilWorkers; + static nsTArray> sRilWorkers; RefPtr mDispatcher; }; diff --git a/ipc/ril/RilSocket.cpp b/ipc/ril/RilSocket.cpp index 6b86e31bee..cb5d96e9aa 100644 --- a/ipc/ril/RilSocket.cpp +++ b/ipc/ril/RilSocket.cpp @@ -93,7 +93,7 @@ private: /** * I/O buffer for received data */ - nsAutoPtr mBuffer; + UniquePtr mBuffer; }; RilSocketIO::RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher, @@ -170,7 +170,7 @@ RilSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) MOZ_ASSERT(aBuffer); if (!mBuffer) { - mBuffer = new UnixSocketRawData(MAX_READ_SIZE); + mBuffer = MakeUnique(MAX_READ_SIZE); } *aBuffer = mBuffer.get(); @@ -212,13 +212,13 @@ public: private: RilSocketIO* mIO; - nsAutoPtr mBuffer; + UniquePtr mBuffer; }; void RilSocketIO::ConsumeBuffer() { - RefPtr task = new ReceiveTask(this, mBuffer.forget()); + RefPtr task = new ReceiveTask(this, mBuffer.release()); NS_WARN_IF(!mDispatcher->PostTask(task)); } @@ -346,7 +346,7 @@ RilSocket::~RilSocket() void RilSocket::ReceiveSocketData(JSContext* aCx, - nsAutoPtr& aBuffer) + UniquePtr& aBuffer) { mConsumer->ReceiveSocketData(aCx, mIndex, aBuffer); } diff --git a/ipc/ril/RilSocket.h b/ipc/ril/RilSocket.h index 9a1f4d7f95..a768b0eb77 100644 --- a/ipc/ril/RilSocket.h +++ b/ipc/ril/RilSocket.h @@ -48,7 +48,7 @@ public: * @param aCx The RIL worker's JS context. * @param aBuffer Data received from the socket. */ - void ReceiveSocketData(JSContext* aCx, nsAutoPtr& aBuffer); + void ReceiveSocketData(JSContext* aCx, UniquePtr& aBuffer); /** * Starts a task on the socket that will try to connect to a socket in a diff --git a/ipc/ril/RilSocketConsumer.h b/ipc/ril/RilSocketConsumer.h index 510517b4ad..03007dc158 100644 --- a/ipc/ril/RilSocketConsumer.h +++ b/ipc/ril/RilSocketConsumer.h @@ -7,7 +7,7 @@ #ifndef mozilla_ipc_RilSocketConsumer_h #define mozilla_ipc_RilSocketConsumer_h -#include "nsAutoPtr.h" +#include "mozilla/UniquePtr.h" class JSContext; @@ -31,7 +31,7 @@ public: */ virtual void ReceiveSocketData(JSContext* aCx, int aIndex, - nsAutoPtr& aBuffer) = 0; + UniquePtr& aBuffer) = 0; /** * Callback for socket success. Consumer-thread only. diff --git a/netwerk/base/security-prefs.js b/netwerk/base/security-prefs.js index decc9ffe2e..7cc14c0840 100644 --- a/netwerk/base/security-prefs.js +++ b/netwerk/base/security-prefs.js @@ -92,7 +92,9 @@ pref("security.pki.sha1_enforcement_level", 3); // contain any DNS names or IP addresses) // 1: fall back to the subject common name for certificates valid before 23 // August 2016 if necessary -// 2: only use name information from the subject alternative name extension +// 2: fall back to the subject common name for certificates valid before 23 +// August 2015 if necessary +// 3: only use name information from the subject alternative name extension #ifdef RELEASE_BUILD pref("security.pki.name_matching_mode", 1); #else diff --git a/probes/Makefile.in b/probes/Makefile.in deleted file mode 100644 index deec83f654..0000000000 --- a/probes/Makefile.in +++ /dev/null @@ -1,14 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -ifdef HAVE_DTRACE -export:: $(DIST)/include/mozilla-trace.h - -# Replace _DTRACE_VERSION with INCLUDE_MOZILLA_DTRACE -$(DIST)/include/mozilla-trace.h: mozilla-trace.d Makefile - dtrace -x nolibs -h -s $(srcdir)/mozilla-trace.d -o mozilla-trace.h.tmp - sed -e 's/if _DTRACE_VERSION/ifdef INCLUDE_MOZILLA_DTRACE/' \ - mozilla-trace.h.tmp > $(DIST)/include/mozilla-trace.h - rm mozilla-trace.h.tmp -endif diff --git a/probes/moz.build b/probes/moz.build index 895d11993c..83bc93b545 100644 --- a/probes/moz.build +++ b/probes/moz.build @@ -4,3 +4,15 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +if CONFIG['HAVE_DTRACE']: + EXPORTS += [ + '!mozilla-trace.h', + ] + + GENERATED_FILES += [ + 'mozilla-trace.h', + ] + + trace = GENERATED_FILES['mozilla-trace.h'] + trace.script = 'trace-gen.py' + trace.inputs += ['mozilla-trace.d'] diff --git a/probes/trace-gen.py b/probes/trace-gen.py new file mode 100644 index 0000000000..586ad01f8e --- /dev/null +++ b/probes/trace-gen.py @@ -0,0 +1,15 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import subprocess + +def main(fp, input): + temporary_file = 'mozilla-trace.h.tmp' + subprocess.check_call(['dtrace', '-x', 'nolibs', '-h', '-s', input, '-o', temporary_file]) + + with open(temporary_file, 'r') as temporary_fp: + output = temporary_fp.read() + fp.write(output.replace('if _DTRACE_VERSION', 'ifdef INCLUDE_MOZILLA_DTRACE')) + os.remove(temporary_file) diff --git a/security/apps/AppSignatureVerification.cpp b/security/apps/AppSignatureVerification.cpp index 1bf97caae6..fdfd18d424 100644 --- a/security/apps/AppSignatureVerification.cpp +++ b/security/apps/AppSignatureVerification.cpp @@ -651,6 +651,27 @@ VerifyCertificate(CERTCertificate* signerCert, void* voidContext, void* pinArg) KeyPurposeId::id_kp_codeSigning, CertPolicyId::anyPolicy, nullptr/*stapledOCSPResponse*/); + if (rv == Result::ERROR_EXPIRED_CERTIFICATE) { + // For code-signing you normally need trusted 3rd-party timestamps to + // handle expiration properly. The signer could always mess with their + // system clock so you can't trust the certificate was un-expired when + // the signing took place. The choice is either to ignore expiration + // or to enforce expiration at time of use. The latter leads to the + // user-hostile result that perfectly good code stops working. + // + // Our package format doesn't support timestamps (nor do we have a + // trusted 3rd party timestamper), but since we sign all of our apps and + // add-ons ourselves we can trust ourselves not to mess with the clock + // on the signing systems. We also have a revocation mechanism if we + // need it. It's OK to ignore cert expiration under these conditions. + // + // This is an invalid approach if + // * we issue certs to let others sign their own packages + // * mozilla::pkix returns "expired" when there are "worse" problems + // with the certificate or chain. + // (see bug 1267318) + rv = Success; + } if (rv != Success) { return mozilla::psm::GetXPCOMFromNSSError(MapResultToPRErrorCode(rv)); } @@ -663,11 +684,18 @@ VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer, const SECItem& detachedDigest, /*out*/ ScopedCERTCertList& builtChain) { + // Currently, this function is only called within the CalculateResult() method + // of CryptoTasks. As such, NSS should not be shut down at this point and the + // CryptoTask implementation should already hold a nsNSSShutDownPreventionLock. + // We acquire a nsNSSShutDownPreventionLock here solely to prove we did to + // VerifyCMSDetachedSignatureIncludingCertificate(). + nsNSSShutDownPreventionLock locker; VerifyCertificateContext context = { trustedRoot, builtChain }; // XXX: missing pinArg return VerifyCMSDetachedSignatureIncludingCertificate(buffer, detachedDigest, VerifyCertificate, - &context, nullptr); + &context, nullptr, + locker); } NS_IMETHODIMP diff --git a/security/certverifier/BRNameMatchingPolicy.cpp b/security/certverifier/BRNameMatchingPolicy.cpp index 47e6a1c2b9..cab267a953 100644 --- a/security/certverifier/BRNameMatchingPolicy.cpp +++ b/security/certverifier/BRNameMatchingPolicy.cpp @@ -16,6 +16,8 @@ BRNameMatchingPolicy::FallBackToCommonName( Time notBefore, /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) { + // (new Date("2015-08-23T00:00:00Z")).getTime() / 1000 + static const Time AUGUST_23_2015 = TimeFromEpochInSeconds(1440288000); // (new Date("2016-08-23T00:00:00Z")).getTime() / 1000 static const Time AUGUST_23_2016 = TimeFromEpochInSeconds(1471910400); switch (mMode) @@ -23,6 +25,11 @@ BRNameMatchingPolicy::FallBackToCommonName( case Mode::Enforce: fallBackToCommonName = FallBackToSearchWithinSubject::No; break; + case Mode::EnforceAfter23August2015: + fallBackToCommonName = notBefore > AUGUST_23_2015 + ? FallBackToSearchWithinSubject::No + : FallBackToSearchWithinSubject::Yes; + break; case Mode::EnforceAfter23August2016: fallBackToCommonName = notBefore > AUGUST_23_2016 ? FallBackToSearchWithinSubject::No diff --git a/security/certverifier/BRNameMatchingPolicy.h b/security/certverifier/BRNameMatchingPolicy.h index 3b817ec8b4..4134948fc1 100644 --- a/security/certverifier/BRNameMatchingPolicy.h +++ b/security/certverifier/BRNameMatchingPolicy.h @@ -23,7 +23,9 @@ namespace mozilla { namespace psm { // maintaining some backwards compatibility. If configured with the mode // "EnforceAfter23August2016", name matching will only fall back to using the // subject common name for certificates where the notBefore field is before 23 -// August 2016. +// August 2016. Similarly, the mode "EnforceAfter23August2015" is also +// available. This is to provide a balance between allowing preexisting +// long-lived certificates and detecting newly-issued problematic certificates. // Note that this implementation does not actually directly enforce that if the // subject common name is present, its value corresponds to a dNSName or // iPAddress entry in the subject alternative name extension. @@ -34,7 +36,8 @@ public: enum class Mode { DoNotEnforce = 0, EnforceAfter23August2016 = 1, - Enforce = 2, + EnforceAfter23August2015 = 2, + Enforce = 3, }; explicit BRNameMatchingPolicy(Mode mode) diff --git a/security/manager/.eslintrc.json b/security/manager/.eslintrc.json index 5bf8c26970..4a93f602c0 100644 --- a/security/manager/.eslintrc.json +++ b/security/manager/.eslintrc.json @@ -177,6 +177,9 @@ // ++ and -- should not need spacing "space-unary-ops": [2, { "words": true, "nonwords": false }], + // Require "use strict" to be defined globally in the script. + "strict": [2, "global"], + // No comparisons to NaN "use-isnan": 2, diff --git a/security/manager/pki/resources/content/certManager.js b/security/manager/pki/resources/content/certManager.js index 50c37ae776..59029a191f 100644 --- a/security/manager/pki/resources/content/certManager.js +++ b/security/manager/pki/resources/content/certManager.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIFilePicker = Components.interfaces.nsIFilePicker; const nsFilePicker = "@mozilla.org/filepicker;1"; diff --git a/security/manager/pki/resources/content/certpicker.js b/security/manager/pki/resources/content/certpicker.js index ce3b58d5bf..09e6f7bc3f 100644 --- a/security/manager/pki/resources/content/certpicker.js +++ b/security/manager/pki/resources/content/certpicker.js @@ -3,6 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; diff --git a/security/manager/pki/resources/content/choosetoken.js b/security/manager/pki/resources/content/choosetoken.js index 846a60040e..42e8565da2 100644 --- a/security/manager/pki/resources/content/choosetoken.js +++ b/security/manager/pki/resources/content/choosetoken.js @@ -4,6 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; diff --git a/security/manager/pki/resources/content/clientauthask.js b/security/manager/pki/resources/content/clientauthask.js index 491376c78b..3ef98adba9 100644 --- a/security/manager/pki/resources/content/clientauthask.js +++ b/security/manager/pki/resources/content/clientauthask.js @@ -4,6 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; diff --git a/security/manager/pki/resources/content/createCertInfo.js b/security/manager/pki/resources/content/createCertInfo.js index 37251b1379..60dce59b96 100644 --- a/security/manager/pki/resources/content/createCertInfo.js +++ b/security/manager/pki/resources/content/createCertInfo.js @@ -4,6 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; var keygenThread; diff --git a/security/manager/pki/resources/content/deletecert.js b/security/manager/pki/resources/content/deletecert.js index 59a0e6f73b..b2b1220ac0 100644 --- a/security/manager/pki/resources/content/deletecert.js +++ b/security/manager/pki/resources/content/deletecert.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIX509Cert = Components.interfaces.nsIX509Cert; const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; diff --git a/security/manager/pki/resources/content/device_manager.js b/security/manager/pki/resources/content/device_manager.js index e85f3e3288..a5567d58fa 100644 --- a/security/manager/pki/resources/content/device_manager.js +++ b/security/manager/pki/resources/content/device_manager.js @@ -1,6 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; const nsIFilePicker = Components.interfaces.nsIFilePicker; const nsFilePicker = "@mozilla.org/filepicker;1"; diff --git a/security/manager/pki/resources/content/downloadcert.js b/security/manager/pki/resources/content/downloadcert.js index b08f7c714a..a10e17216f 100644 --- a/security/manager/pki/resources/content/downloadcert.js +++ b/security/manager/pki/resources/content/downloadcert.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; const nsIX509Cert = Components.interfaces.nsIX509Cert; diff --git a/security/manager/pki/resources/content/editcerts.js b/security/manager/pki/resources/content/editcerts.js index 6e788ca912..5b210ee0a8 100644 --- a/security/manager/pki/resources/content/editcerts.js +++ b/security/manager/pki/resources/content/editcerts.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsIX509Cert = Components.interfaces.nsIX509Cert; const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index 622de2ae27..33b64a00de 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; var gDialog; var gBundleBrand; diff --git a/security/manager/pki/resources/content/password.js b/security/manager/pki/resources/content/password.js index f786a4d5c9..7fea935fce 100644 --- a/security/manager/pki/resources/content/password.js +++ b/security/manager/pki/resources/content/password.js @@ -1,6 +1,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1"; const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB; const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock; diff --git a/security/manager/pki/resources/content/pippki.js b/security/manager/pki/resources/content/pippki.js index 5030f5c372..a8e5eacbd1 100644 --- a/security/manager/pki/resources/content/pippki.js +++ b/security/manager/pki/resources/content/pippki.js @@ -3,6 +3,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; /* * These are helper functions to be included diff --git a/security/manager/pki/resources/content/protectedAuth.js b/security/manager/pki/resources/content/protectedAuth.js index de6ddbfe43..101511c40f 100644 --- a/security/manager/pki/resources/content/protectedAuth.js +++ b/security/manager/pki/resources/content/protectedAuth.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; function onLoad() { diff --git a/security/manager/pki/resources/content/resetpassword.js b/security/manager/pki/resources/content/resetpassword.js index 629396aab0..9d6ff921fe 100644 --- a/security/manager/pki/resources/content/resetpassword.js +++ b/security/manager/pki/resources/content/resetpassword.js @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* import-globals-from pippki.js */ +"use strict"; const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1"; const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB; diff --git a/security/manager/pki/resources/content/viewCertDetails.js b/security/manager/pki/resources/content/viewCertDetails.js index 513ee91681..a6495ea219 100644 --- a/security/manager/pki/resources/content/viewCertDetails.js +++ b/security/manager/pki/resources/content/viewCertDetails.js @@ -1,6 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; const nsIX509Cert = Components.interfaces.nsIX509Cert; const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; diff --git a/security/manager/ssl/ScopedNSSTypes.h b/security/manager/ssl/ScopedNSSTypes.h index 0b1ee1aff4..2917c8eeee 100644 --- a/security/manager/ssl/ScopedNSSTypes.h +++ b/security/manager/ssl/ScopedNSSTypes.h @@ -344,6 +344,9 @@ MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertNicknames, MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTOidSequence, CERTOidSequence, CERT_DestroyOidSequence) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTSubjectPublicKeyInfo, + CERTSubjectPublicKeyInfo, + SECKEY_DestroySubjectPublicKeyInfo) MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTUserNotice, CERTUserNotice, CERT_DestroyUserNotice) diff --git a/security/manager/ssl/nsCertPicker.cpp b/security/manager/ssl/nsCertPicker.cpp index 223d20ac6e..987e374293 100644 --- a/security/manager/ssl/nsCertPicker.cpp +++ b/security/manager/ssl/nsCertPicker.cpp @@ -4,20 +4,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsCertPicker.h" -#include "pkix/pkixtypes.h" -#include "nsMemory.h" -#include "nsCOMPtr.h" -#include "nsXPIDLString.h" -#include "nsIServiceManager.h" -#include "nsNSSComponent.h" -#include "nsNSSCertificate.h" -#include "nsReadableUtils.h" -#include "nsICertPickDialogs.h" -#include "nsNSSShutDown.h" -#include "nsNSSCertHelper.h" -#include "ScopedNSSTypes.h" +#include "ScopedNSSTypes.h" #include "cert.h" +#include "mozilla/RefPtr.h" +#include "nsCOMPtr.h" +#include "nsICertPickDialogs.h" +#include "nsIInterfaceRequestor.h" +#include "nsIServiceManager.h" +#include "nsMemory.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsNSSShutDown.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "pkix/pkixtypes.h" using namespace mozilla; @@ -163,18 +166,15 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx, } if (CertsToUse) { - nsICertPickDialogs *dialogs = nullptr; - rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsICertPickDialogs), - NS_CERTPICKDIALOGS_CONTRACTID); + nsCOMPtr dialogs; + rv = getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsICertPickDialogs), + NS_CERTPICKDIALOGS_CONTRACTID); if (NS_SUCCEEDED(rv)) { // Show the cert picker dialog and get the index of the selected cert. rv = dialogs->PickCertificate(ctx, (const char16_t**)certNicknameList, (const char16_t**)certDetailsList, CertsToUse, &selectedIndex, canceled); - - NS_RELEASE(dialogs); } } diff --git a/security/manager/ssl/nsDataSignatureVerifier.cpp b/security/manager/ssl/nsDataSignatureVerifier.cpp index c8272e72f4..8398f107c3 100644 --- a/security/manager/ssl/nsDataSignatureVerifier.cpp +++ b/security/manager/ssl/nsDataSignatureVerifier.cpp @@ -7,6 +7,7 @@ #include "cms.h" #include "cryptohi.h" #include "keyhi.h" +#include "mozilla/unused.h" #include "nsCOMPtr.h" #include "nsNSSComponent.h" #include "nssb64.h" @@ -35,75 +36,85 @@ const SEC_ASN1Template CERT_SignatureDataTemplate[] = { 0, } }; -NS_IMETHODIMP -nsDataSignatureVerifier::VerifyData(const nsACString & aData, - const nsACString & aSignature, - const nsACString & aPublicKey, - bool *_retval) +nsDataSignatureVerifier::~nsDataSignatureVerifier() { - // Allocate an arena to handle the majority of the allocations - UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); - if (!arena) { - return NS_ERROR_OUT_OF_MEMORY; - } + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return; + } - // Base 64 decode the key - SECItem keyItem; - PORT_Memset(&keyItem, 0, sizeof(SECItem)); - if (!NSSBase64_DecodeBuffer(arena.get(), &keyItem, - nsPromiseFlatCString(aPublicKey).get(), - aPublicKey.Length())) { - return NS_ERROR_FAILURE; - } + shutdown(calledFromObject); +} - // Extract the public key from the data - CERTSubjectPublicKeyInfo *pki = SECKEY_DecodeDERSubjectPublicKeyInfo(&keyItem); - if (!pki) { - return NS_ERROR_FAILURE; - } - SECKEYPublicKey *publicKey = SECKEY_ExtractPublicKey(pki); - SECKEY_DestroySubjectPublicKeyInfo(pki); - pki = nullptr; +NS_IMETHODIMP +nsDataSignatureVerifier::VerifyData(const nsACString& aData, + const nsACString& aSignature, + const nsACString& aPublicKey, + bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); - if (!publicKey) { - return NS_ERROR_FAILURE; - } + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } - // Base 64 decode the signature - SECItem signatureItem; - PORT_Memset(&signatureItem, 0, sizeof(SECItem)); - if (!NSSBase64_DecodeBuffer(arena.get(), &signatureItem, - nsPromiseFlatCString(aSignature).get(), - aSignature.Length())) { - SECKEY_DestroyPublicKey(publicKey); - return NS_ERROR_FAILURE; - } + // Allocate an arena to handle the majority of the allocations + UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + if (!arena) { + return NS_ERROR_OUT_OF_MEMORY; + } - // Decode the signature and algorithm - CERTSignedData sigData; - PORT_Memset(&sigData, 0, sizeof(CERTSignedData)); - SECStatus ss = SEC_QuickDERDecodeItem(arena.get(), &sigData, - CERT_SignatureDataTemplate, - &signatureItem); - if (ss != SECSuccess) { - SECKEY_DestroyPublicKey(publicKey); - return NS_ERROR_FAILURE; - } + // Base 64 decode the key + SECItem keyItem; + PORT_Memset(&keyItem, 0, sizeof(SECItem)); + if (!NSSBase64_DecodeBuffer(arena.get(), &keyItem, + PromiseFlatCString(aPublicKey).get(), + aPublicKey.Length())) { + return NS_ERROR_FAILURE; + } - // Perform the final verification - DER_ConvertBitString(&(sigData.signature)); - ss = VFY_VerifyDataWithAlgorithmID((const unsigned char*)nsPromiseFlatCString(aData).get(), - aData.Length(), publicKey, - &(sigData.signature), - &(sigData.signatureAlgorithm), - nullptr, nullptr); + // Extract the public key from the data + UniqueCERTSubjectPublicKeyInfo pki( + SECKEY_DecodeDERSubjectPublicKeyInfo(&keyItem)); + if (!pki) { + return NS_ERROR_FAILURE; + } - // Clean up remaining objects - SECKEY_DestroyPublicKey(publicKey); + UniqueSECKEYPublicKey publicKey(SECKEY_ExtractPublicKey(pki.get())); + if (!publicKey) { + return NS_ERROR_FAILURE; + } - *_retval = (ss == SECSuccess); + // Base 64 decode the signature + SECItem signatureItem; + PORT_Memset(&signatureItem, 0, sizeof(SECItem)); + if (!NSSBase64_DecodeBuffer(arena.get(), &signatureItem, + PromiseFlatCString(aSignature).get(), + aSignature.Length())) { + return NS_ERROR_FAILURE; + } - return NS_OK; + // Decode the signature and algorithm + CERTSignedData sigData; + PORT_Memset(&sigData, 0, sizeof(CERTSignedData)); + SECStatus srv = SEC_QuickDERDecodeItem(arena.get(), &sigData, + CERT_SignatureDataTemplate, + &signatureItem); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + + // Perform the final verification + DER_ConvertBitString(&(sigData.signature)); + srv = VFY_VerifyDataWithAlgorithmID( + reinterpret_cast(PromiseFlatCString(aData).get()), + aData.Length(), publicKey.get(), &(sigData.signature), + &(sigData.signatureAlgorithm), nullptr, nullptr); + + *_retval = (srv == SECSuccess); + + return NS_OK; } namespace mozilla { @@ -113,7 +124,8 @@ VerifyCMSDetachedSignatureIncludingCertificate( const SECItem& buffer, const SECItem& detachedDigest, nsresult (*verifyCertificate)(CERTCertificate* cert, void* context, void* pinArg), - void *verifyCertificateContext, void* pinArg) + void* verifyCertificateContext, void* pinArg, + const nsNSSShutDownPreventionLock& /*proofOfLock*/) { // XXX: missing pinArg is tolerated. if (NS_WARN_IF(!buffer.data && buffer.len > 0) || @@ -167,24 +179,26 @@ VerifyCMSDetachedSignatureIncludingCertificate( // Parse the certificates into CERTCertificate objects held in memory so // verifyCertificate will be able to find them during path building. - ScopedCERTCertList certs(CERT_NewCertList()); + UniqueCERTCertList certs(CERT_NewCertList()); if (!certs) { return NS_ERROR_OUT_OF_MEMORY; } if (signedData->rawCerts) { for (size_t i = 0; signedData->rawCerts[i]; ++i) { - ScopedCERTCertificate + UniqueCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), signedData->rawCerts[i], nullptr, false, true)); // Skip certificates that fail to parse - if (cert) { - if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) { - cert.forget(); // ownership transfered - } else { - return NS_ERROR_OUT_OF_MEMORY; - } + if (!cert) { + continue; } + + if (CERT_AddCertToListTail(certs.get(), cert.get()) != SECSuccess) { + return NS_ERROR_OUT_OF_MEMORY; + } + + Unused << cert.release(); // Ownership transferred to the cert list. } } @@ -269,18 +283,20 @@ nsDataSignatureVerifier::VerifySignature(const char* aRSABuf, int32_t* aErrorCode, nsIX509Cert** aSigningCert) { - if (!aPlaintext || !aSigningCert || !aErrorCode) { + if (!aRSABuf || !aPlaintext || !aErrorCode || !aSigningCert) { return NS_ERROR_INVALID_ARG; } + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + *aErrorCode = VERIFY_ERROR_OTHER; *aSigningCert = nullptr; - nsNSSShutDownPreventionLock locker; - Digest digest; - nsresult rv = digest.DigestBuf(SEC_OID_SHA1, - reinterpret_cast(aPlaintext), + nsresult rv = digest.DigestBuf(SEC_OID_SHA1, uint8_t_ptr_cast(aPlaintext), aPlaintextLen); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -296,7 +312,7 @@ nsDataSignatureVerifier::VerifySignature(const char* aRSABuf, // XXX: pinArg is missing rv = VerifyCMSDetachedSignatureIncludingCertificate(buffer, digest.get(), VerifyCertificate, - &context, nullptr); + &context, nullptr, locker); if (NS_SUCCEEDED(rv)) { *aErrorCode = VERIFY_OK; } else if (NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_SECURITY) { diff --git a/security/manager/ssl/nsDataSignatureVerifier.h b/security/manager/ssl/nsDataSignatureVerifier.h index db19db5eb2..485af70c8d 100644 --- a/security/manager/ssl/nsDataSignatureVerifier.h +++ b/security/manager/ssl/nsDataSignatureVerifier.h @@ -2,17 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef _NS_DATASIGNATUREVERIFIER_H_ -#define _NS_DATASIGNATUREVERIFIER_H_ +#ifndef nsDataSignatureVerifier_h +#define nsDataSignatureVerifier_h +#include "certt.h" #include "nsIDataSignatureVerifier.h" -#include "mozilla/Attributes.h" +#include "nsNSSShutDown.h" -#include "keythi.h" - -typedef struct CERTCertificateStr CERTCertificate; - -// 296d76aa-275b-4f3c-af8a-30a4026c18fc #define NS_DATASIGNATUREVERIFIER_CID \ { 0x296d76aa, 0x275b, 0x4f3c, \ { 0xaf, 0x8a, 0x30, 0xa4, 0x02, 0x6c, 0x18, 0xfc } } @@ -20,6 +16,7 @@ typedef struct CERTCertificateStr CERTCertificate; "@mozilla.org/security/datasignatureverifier;1" class nsDataSignatureVerifier final : public nsIDataSignatureVerifier + , public nsNSSShutDownObject { public: NS_DECL_ISUPPORTS @@ -30,9 +27,10 @@ public: } private: - ~nsDataSignatureVerifier() - { - } + ~nsDataSignatureVerifier(); + + // Nothing to release. + virtual void virtualDestroyNSSReference() override {} }; namespace mozilla { @@ -41,8 +39,9 @@ nsresult VerifyCMSDetachedSignatureIncludingCertificate( const SECItem& buffer, const SECItem& detachedDigest, nsresult (*verifyCertificate)(CERTCertificate* cert, void* context, void* pinArg), - void* verifyCertificateContext, void* pinArg); + void* verifyCertificateContext, void* pinArg, + const nsNSSShutDownPreventionLock& proofOfLock); } // namespace mozilla -#endif // _NS_DATASIGNATUREVERIFIER_H_ +#endif // nsDataSignatureVerifier_h diff --git a/security/manager/ssl/nsKeygenHandler.cpp b/security/manager/ssl/nsKeygenHandler.cpp index 477cc7bc07..8b17ee4d81 100644 --- a/security/manager/ssl/nsKeygenHandler.cpp +++ b/security/manager/ssl/nsKeygenHandler.cpp @@ -299,7 +299,7 @@ GetSlotWithMechanism(uint32_t aMechanism, nsIInterfaceRequestor* m_ctx, { PK11SlotList * slotList = nullptr; char16_t** tokenNameList = nullptr; - nsITokenDialogs * dialogs; + nsCOMPtr dialogs; char16_t *unicodeTokenChosen; PK11SlotListElement *slotElement, *tmpSlot; uint32_t numSlots = 0, i = 0; @@ -350,12 +350,13 @@ GetSlotWithMechanism(uint32_t aMechanism, nsIInterfaceRequestor* m_ctx, } } - /* Throw up the token list dialog and get back the token */ - rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsITokenDialogs), - NS_TOKENDIALOGS_CONTRACTID); + // Throw up the token list dialog and get back the token. + rv = getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsITokenDialogs), + NS_TOKENDIALOGS_CONTRACTID); - if (NS_FAILED(rv)) goto loser; + if (NS_FAILED(rv)) { + goto loser; + } if (!tokenNameList || !*tokenNameList) { rv = NS_ERROR_OUT_OF_MEMORY; @@ -363,7 +364,6 @@ GetSlotWithMechanism(uint32_t aMechanism, nsIInterfaceRequestor* m_ctx, rv = dialogs->ChooseToken(m_ctx, (const char16_t**)tokenNameList, numSlots, &unicodeTokenChosen, &canceled); } - NS_RELEASE(dialogs); if (NS_FAILED(rv)) goto loser; if (canceled) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; } @@ -476,7 +476,7 @@ nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue, SECItem signedItem; CERTPublicKeyAndChallenge pkac; pkac.challenge.data = nullptr; - nsIGeneratingKeypairInfoDialogs * dialogs; + nsCOMPtr dialogs; nsKeygenThread *KeygenRunnable = 0; nsCOMPtr runnable; @@ -583,7 +583,7 @@ nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue, goto loser; } - rv = getNSSDialogs((void**)&dialogs, + rv = getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsIGeneratingKeypairInfoDialogs), NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID); @@ -601,14 +601,12 @@ nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue, keyGenMechanism, params, m_ctx ); runnable = do_QueryInterface(KeygenRunnable); - if (runnable) { rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable); // We call join on the thread so we can be sure that no // simultaneous access to the passed parameters will happen. KeygenRunnable->Join(); - NS_RELEASE(dialogs); if (NS_SUCCEEDED(rv)) { PK11SlotInfo *used_slot = nullptr; rv = KeygenRunnable->ConsumeResult(&used_slot, &privateKey, &publicKey); diff --git a/security/manager/ssl/nsKeygenHandler.h b/security/manager/ssl/nsKeygenHandler.h index 5cd83d1d59..3a2fe18591 100644 --- a/security/manager/ssl/nsKeygenHandler.h +++ b/security/manager/ssl/nsKeygenHandler.h @@ -4,12 +4,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef _NSKEYGENHANDLER_H_ -#define _NSKEYGENHANDLER_H_ -// Form Processor +#ifndef nsKeygenHandler_h +#define nsKeygenHandler_h + +#include "keythi.h" +#include "nsCOMPtr.h" +#include "nsError.h" #include "nsIFormProcessor.h" -#include "nsTArray.h" +#include "nsIInterfaceRequestor.h" #include "nsNSSShutDown.h" +#include "nsTArray.h" +#include "secmodt.h" nsresult GetSlotWithMechanism(uint32_t mechanism, nsIInterfaceRequestor* ctx, @@ -73,4 +78,4 @@ private: SECKeySizeChoiceInfo mSECKeySizeChoiceList[number_of_key_size_choices]; }; -#endif //_NSKEYGENHANDLER_H_ +#endif // nsKeygenHandler_h diff --git a/security/manager/ssl/nsNSSCallbacks.cpp b/security/manager/ssl/nsNSSCallbacks.cpp index 587a6ec119..62241c1abe 100644 --- a/security/manager/ssl/nsNSSCallbacks.cpp +++ b/security/manager/ssl/nsNSSCallbacks.cpp @@ -637,9 +637,9 @@ ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIInterfaceRequestor *ir) char* protAuthRetVal = nullptr; // Get protected auth dialogs - nsITokenDialogs* dialogs = 0; - nsresult nsrv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsITokenDialogs), + nsCOMPtr dialogs; + nsresult nsrv = getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsITokenDialogs), NS_TOKENDIALOGS_CONTRACTID); if (NS_SUCCEEDED(nsrv)) { @@ -673,15 +673,12 @@ ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIInterfaceRequestor *ir) default: protAuthRetVal = nullptr; break; - } } } NS_RELEASE(protectedAuthRunnable); } - - NS_RELEASE(dialogs); } return protAuthRetVal; diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp index 972ea1084d..2874da5ca6 100644 --- a/security/manager/ssl/nsNSSComponent.cpp +++ b/security/manager/ssl/nsNSSComponent.cpp @@ -1382,6 +1382,7 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting, static_cast(BRNameMatchingPolicy::Mode::DoNotEnforce))); switch (nameMatchingMode) { case BRNameMatchingPolicy::Mode::Enforce: + case BRNameMatchingPolicy::Mode::EnforceAfter23August2015: case BRNameMatchingPolicy::Mode::EnforceAfter23August2016: case BRNameMatchingPolicy::Mode::DoNotEnforce: break; @@ -2117,28 +2118,33 @@ nsresult setPassword(PK11SlotInfo* slot, nsIInterfaceRequestor* ctx, nsNSSShutDownPreventionLock& /*proofOfLock*/) { - nsresult rv = NS_OK; + MOZ_ASSERT(slot); + MOZ_ASSERT(ctx); + NS_ENSURE_ARG_POINTER(slot); + NS_ENSURE_ARG_POINTER(ctx); if (PK11_NeedUserInit(slot)) { - nsITokenPasswordDialogs* dialogs; + nsCOMPtr dialogs; + nsresult rv = getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsITokenPasswordDialogs), + NS_TOKENPASSWORDSDIALOG_CONTRACTID); + if (NS_FAILED(rv)) { + return rv; + } + bool canceled; NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot)); - - rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsITokenPasswordDialogs), - NS_TOKENPASSWORDSDIALOG_CONTRACTID); - - if (NS_FAILED(rv)) goto loser; - rv = dialogs->SetPassword(ctx, tokenName.get(), &canceled); + if (NS_FAILED(rv)) { + return rv; + } - NS_RELEASE(dialogs); - if (NS_FAILED(rv)) goto loser; - - if (canceled) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; } + if (canceled) { + return NS_ERROR_NOT_AVAILABLE; + } } - loser: - return rv; + + return NS_OK; } namespace mozilla { diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp index eaff505e53..c11d032a54 100644 --- a/security/manager/ssl/nsNSSIOLayer.cpp +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -2217,7 +2217,7 @@ ClientAuthDataRunnable::RunOnTargetThread() if (!hasRemembered) { // user selects a cert to present - nsIClientAuthDialogs* dialogs = nullptr; + nsCOMPtr dialogs; int32_t selectedIndex = -1; char16_t** certNicknameList = nullptr; char16_t** certDetailsList = nullptr; @@ -2331,9 +2331,9 @@ ClientAuthDataRunnable::RunOnTargetThread() } // Throw up the client auth dialog and get back the index of the selected cert - nsresult rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsIClientAuthDialogs), - NS_CLIENTAUTHDIALOGS_CONTRACTID); + nsresult rv = getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); @@ -2347,7 +2347,6 @@ ClientAuthDataRunnable::RunOnTargetThread() (const char16_t**)certDetailsList, CertsToUse, &selectedIndex, &canceled); - NS_RELEASE(dialogs); NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certDetailsList); diff --git a/security/manager/ssl/nsNSSIOLayer.h b/security/manager/ssl/nsNSSIOLayer.h index 2be417653f..379385a6fe 100644 --- a/security/manager/ssl/nsNSSIOLayer.h +++ b/security/manager/ssl/nsNSSIOLayer.h @@ -4,17 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef _NSNSSIOLAYER_H -#define _NSNSSIOLAYER_H +#ifndef nsNSSIOLayer_h +#define nsNSSIOLayer_h #include "TransportSecurityInfo.h" -#include "nsISSLSocketControl.h" +#include "mozilla/TimeStamp.h" +#include "nsCOMPtr.h" +#include "nsDataHashtable.h" #include "nsIClientAuthDialogs.h" #include "nsIProxyInfo.h" +#include "nsISSLSocketControl.h" #include "nsNSSCertificate.h" -#include "nsDataHashtable.h" #include "nsTHashtable.h" -#include "mozilla/TimeStamp.h" #include "sslt.h" namespace mozilla { @@ -264,4 +265,4 @@ nsresult nsSSLIOLayerAddToSocket(int32_t family, nsresult nsSSLIOLayerFreeTLSIntolerantSites(); nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error); -#endif /* _NSNSSIOLAYER_H */ +#endif // nsNSSIOLayer_h diff --git a/security/manager/ssl/nsPK11TokenDB.cpp b/security/manager/ssl/nsPK11TokenDB.cpp index a4e72bfb7f..d8d1720bb8 100644 --- a/security/manager/ssl/nsPK11TokenDB.cpp +++ b/security/manager/ssl/nsPK11TokenDB.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsPK11TokenDB.h" +#include "mozilla/unused.h" #include "nsIMutableArray.h" #include "nsISupports.h" #include "nsNSSComponent.h" @@ -19,63 +20,64 @@ extern mozilla::LazyLogModule gPIPNSSLog; NS_IMPL_ISUPPORTS(nsPK11Token, nsIPK11Token) nsPK11Token::nsPK11Token(PK11SlotInfo *slot) + : mUIContext(new PipUIContext()) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return; - PK11_ReferenceSlot(slot); - mSlot = slot; + mSlot.reset(PK11_ReferenceSlot(slot)); mSeries = PK11_GetSlotSeries(slot); - refreshTokenInfo(); - mUIContext = new PipUIContext(); + Unused << refreshTokenInfo(locker); } -void -nsPK11Token::refreshTokenInfo() +nsresult +nsPK11Token::refreshTokenInfo(const nsNSSShutDownPreventionLock& /*proofOfLock*/) { - mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot)); + mTokenName = NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot.get())); - SECStatus srv; - - CK_TOKEN_INFO tok_info; - srv = PK11_GetTokenInfo(mSlot, &tok_info); - if (srv == SECSuccess) { - // Set the Label field - - const char *ccLabel = (const char*)tok_info.label; - const nsACString &cLabel = Substring( - ccLabel, - ccLabel+PL_strnlen(ccLabel, sizeof(tok_info.label))); - mTokenLabel = NS_ConvertUTF8toUTF16(cLabel); - mTokenLabel.Trim(" ", false, true); - - // Set the Manufacturer field - const char *ccManID = (const char*)tok_info.manufacturerID; - const nsACString &cManID = Substring( - ccManID, - ccManID+PL_strnlen(ccManID, sizeof(tok_info.manufacturerID))); - mTokenManID = NS_ConvertUTF8toUTF16(cManID); - mTokenManID.Trim(" ", false, true); - - // Set the Hardware Version field - mTokenHWVersion.AppendInt(tok_info.hardwareVersion.major); - mTokenHWVersion.Append('.'); - mTokenHWVersion.AppendInt(tok_info.hardwareVersion.minor); - // Set the Firmware Version field - mTokenFWVersion.AppendInt(tok_info.firmwareVersion.major); - mTokenFWVersion.Append('.'); - mTokenFWVersion.AppendInt(tok_info.firmwareVersion.minor); - // Set the Serial Number field - const char *ccSerial = (const char*)tok_info.serialNumber; - const nsACString &cSerial = Substring( - ccSerial, - ccSerial+PL_strnlen(ccSerial, sizeof(tok_info.serialNumber))); - mTokenSerialNum = NS_ConvertUTF8toUTF16(cSerial); - mTokenSerialNum.Trim(" ", false, true); + CK_TOKEN_INFO tokInfo; + nsresult rv = MapSECStatus(PK11_GetTokenInfo(mSlot.get(), &tokInfo)); + if (NS_FAILED(rv)) { + return rv; } + // Set the Label field + const char* ccLabel = reinterpret_cast(tokInfo.label); + const nsACString& cLabel = Substring( + ccLabel, + ccLabel + PL_strnlen(ccLabel, sizeof(tokInfo.label))); + mTokenLabel = NS_ConvertUTF8toUTF16(cLabel); + mTokenLabel.Trim(" ", false, true); + + // Set the Manufacturer field + const char* ccManID = reinterpret_cast(tokInfo.manufacturerID); + const nsACString& cManID = Substring( + ccManID, + ccManID + PL_strnlen(ccManID, sizeof(tokInfo.manufacturerID))); + mTokenManID = NS_ConvertUTF8toUTF16(cManID); + mTokenManID.Trim(" ", false, true); + + // Set the Hardware Version field + mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.major); + mTokenHWVersion.Append('.'); + mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.minor); + + // Set the Firmware Version field + mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.major); + mTokenFWVersion.Append('.'); + mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.minor); + + // Set the Serial Number field + const char* ccSerial = reinterpret_cast(tokInfo.serialNumber); + const nsACString& cSerial = Substring( + ccSerial, + ccSerial + PL_strnlen(ccSerial, sizeof(tokInfo.serialNumber))); + mTokenSerialNum = NS_ConvertUTF8toUTF16(cSerial); + mTokenSerialNum.Trim(" ", false, true); + + return NS_OK; } nsPK11Token::~nsPK11Token() @@ -95,17 +97,22 @@ void nsPK11Token::virtualDestroyNSSReference() void nsPK11Token::destructorSafeDestroyNSSReference() { - if (mSlot) { - PK11_FreeSlot(mSlot); - mSlot = nullptr; - } + mSlot = nullptr; } NS_IMETHODIMP nsPK11Token::GetTokenName(char16_t * *aTokenName) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokenName = ToNewUnicode(mTokenName); if (!*aTokenName) return NS_ERROR_OUT_OF_MEMORY; @@ -115,9 +122,17 @@ NS_IMETHODIMP nsPK11Token::GetTokenName(char16_t * *aTokenName) NS_IMETHODIMP nsPK11Token::GetTokenLabel(char16_t **aTokLabel) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokLabel = ToNewUnicode(mTokenLabel); if (!*aTokLabel) return NS_ERROR_OUT_OF_MEMORY; @@ -126,9 +141,17 @@ NS_IMETHODIMP nsPK11Token::GetTokenLabel(char16_t **aTokLabel) NS_IMETHODIMP nsPK11Token::GetTokenManID(char16_t **aTokManID) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokManID = ToNewUnicode(mTokenManID); if (!*aTokManID) return NS_ERROR_OUT_OF_MEMORY; @@ -137,9 +160,17 @@ NS_IMETHODIMP nsPK11Token::GetTokenManID(char16_t **aTokManID) NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(char16_t **aTokHWVersion) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokHWVersion = ToNewUnicode(mTokenHWVersion); if (!*aTokHWVersion) return NS_ERROR_OUT_OF_MEMORY; @@ -148,9 +179,17 @@ NS_IMETHODIMP nsPK11Token::GetTokenHWVersion(char16_t **aTokHWVersion) NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(char16_t **aTokFWVersion) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokFWVersion = ToNewUnicode(mTokenFWVersion); if (!*aTokFWVersion) return NS_ERROR_OUT_OF_MEMORY; @@ -159,9 +198,17 @@ NS_IMETHODIMP nsPK11Token::GetTokenFWVersion(char16_t **aTokFWVersion) NS_IMETHODIMP nsPK11Token::GetTokenSerialNumber(char16_t **aTokSerialNum) { + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + // handle removals/insertions - if (mSeries != PK11_GetSlotSeries(mSlot)) { - refreshTokenInfo(); + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(locker); + if (NS_FAILED(rv)) { + return rv; + } } *aTokSerialNum = ToNewUnicode(mTokenSerialNum); if (!*aTokSerialNum) return NS_ERROR_OUT_OF_MEMORY; @@ -174,14 +221,12 @@ NS_IMETHODIMP nsPK11Token::IsLoggedIn(bool *_retval) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = NS_OK; + *_retval = PK11_IsLoggedIn(mSlot.get(), 0); - *_retval = PK11_IsLoggedIn(mSlot, 0); - - return rv; + return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP nsPK11Token::Login(bool force) { nsNSSShutDownPreventionLock locker; @@ -189,7 +234,6 @@ nsPK11Token::Login(bool force) return NS_ERROR_NOT_AVAILABLE; nsresult rv; - SECStatus srv; bool test; rv = this->NeedsLogin(&test); if (NS_FAILED(rv)) return rv; @@ -197,10 +241,10 @@ nsPK11Token::Login(bool force) rv = this->LogoutSimple(); if (NS_FAILED(rv)) return rv; } - rv = setPassword(mSlot, mUIContext, locker); + rv = setPassword(mSlot.get(), mUIContext, locker); if (NS_FAILED(rv)) return rv; - srv = PK11_Authenticate(mSlot, true, mUIContext); - return (srv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE; + + return MapSECStatus(PK11_Authenticate(mSlot.get(), true, mUIContext)); } NS_IMETHODIMP nsPK11Token::LogoutSimple() @@ -209,9 +253,9 @@ NS_IMETHODIMP nsPK11Token::LogoutSimple() if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - // PK11_MapError sets CKR_USER_NOT_LOGGED_IN to SEC_ERROR_LIBRARY_FAILURE, - // so not going to learn anything here by a failure. Treat it like void. - PK11_Logout(mSlot); + // PK11_Logout() can fail if the user wasn't logged in beforehand. We want + // this method to succeed even in this case, so we ignore the return value. + Unused << PK11_Logout(mSlot.get()); return NS_OK; } @@ -237,8 +281,7 @@ NS_IMETHODIMP nsPK11Token::Reset() if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - PK11_ResetToken(mSlot, 0); - return NS_OK; + return MapSECStatus(PK11_ResetToken(mSlot.get(), nullptr)); } NS_IMETHODIMP nsPK11Token::GetMinimumPasswordLength(int32_t *aMinimumPasswordLength) @@ -247,7 +290,7 @@ NS_IMETHODIMP nsPK11Token::GetMinimumPasswordLength(int32_t *aMinimumPasswordLen if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - *aMinimumPasswordLength = PK11_GetMinimumPwdLength(mSlot); + *aMinimumPasswordLength = PK11_GetMinimumPwdLength(mSlot.get()); return NS_OK; } @@ -258,7 +301,7 @@ NS_IMETHODIMP nsPK11Token::GetNeedsUserInit(bool *aNeedsUserInit) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - *aNeedsUserInit = PK11_NeedUserInit(mSlot); + *aNeedsUserInit = PK11_NeedUserInit(mSlot.get()); return NS_OK; } @@ -268,17 +311,15 @@ NS_IMETHODIMP nsPK11Token::CheckPassword(const char16_t *password, bool *_retval if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - SECStatus srv; - int32_t prerr; - NS_ConvertUTF16toUTF8 aUtf8Password(password); - srv = PK11_CheckUserPassword(mSlot, - const_cast(aUtf8Password.get())); + NS_ConvertUTF16toUTF8 utf8Password(password); + SECStatus srv = + PK11_CheckUserPassword(mSlot.get(), const_cast(utf8Password.get())); if (srv != SECSuccess) { *_retval = false; - prerr = PR_GetError(); - if (prerr != SEC_ERROR_BAD_PASSWORD) { + PRErrorCode error = PR_GetError(); + if (error != SEC_ERROR_BAD_PASSWORD) { /* something really bad happened - throw an exception */ - return NS_ERROR_FAILURE; + return mozilla::psm::GetXPCOMFromNSSError(error); } } else { *_retval = true; @@ -292,44 +333,36 @@ NS_IMETHODIMP nsPK11Token::InitPassword(const char16_t *initialPassword) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = NS_OK; - SECStatus status; - - NS_ConvertUTF16toUTF8 aUtf8InitialPassword(initialPassword); - status = PK11_InitPin(mSlot, "", const_cast(aUtf8InitialPassword.get())); - if (status == SECFailure) { rv = NS_ERROR_FAILURE; goto done; } - -done: - return rv; + NS_ConvertUTF16toUTF8 utf8Password(initialPassword); + return MapSECStatus( + PK11_InitPin(mSlot.get(), "", const_cast(utf8Password.get()))); } -NS_IMETHODIMP -nsPK11Token::GetAskPasswordTimes(int32_t *rvAskTimes) +NS_IMETHODIMP +nsPK11Token::GetAskPasswordTimes(int32_t* askTimes) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - int askTimes, askTimeout; - PK11_GetSlotPWValues(mSlot, &askTimes, &askTimeout); - *rvAskTimes = askTimes; - return NS_OK; + int askTimeout; + PK11_GetSlotPWValues(mSlot.get(), askTimes, &askTimeout); + return NS_OK; } -NS_IMETHODIMP -nsPK11Token::GetAskPasswordTimeout(int32_t *rvAskTimeout) +NS_IMETHODIMP +nsPK11Token::GetAskPasswordTimeout(int32_t* askTimeout) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - int askTimes, askTimeout; - PK11_GetSlotPWValues(mSlot, &askTimes, &askTimeout); - *rvAskTimeout = askTimeout; - return NS_OK; + int askTimes; + PK11_GetSlotPWValues(mSlot.get(), &askTimes, askTimeout); + return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP nsPK11Token::SetAskPasswordDefaults(const int32_t askTimes, const int32_t askTimeout) { @@ -337,8 +370,8 @@ nsPK11Token::SetAskPasswordDefaults(const int32_t askTimes, if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - PK11_SetSlotPWValues(mSlot, askTimes, askTimeout); - return NS_OK; + PK11_SetSlotPWValues(mSlot.get(), askTimes, askTimeout); + return NS_OK; } NS_IMETHODIMP nsPK11Token::ChangePassword(const char16_t *oldPassword, const char16_t *newPassword) @@ -347,14 +380,17 @@ NS_IMETHODIMP nsPK11Token::ChangePassword(const char16_t *oldPassword, const cha if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - SECStatus rv; - NS_ConvertUTF16toUTF8 aUtf8OldPassword(oldPassword); - NS_ConvertUTF16toUTF8 aUtf8NewPassword(newPassword); + NS_ConvertUTF16toUTF8 utf8OldPassword(oldPassword); + NS_ConvertUTF16toUTF8 utf8NewPassword(newPassword); - rv = PK11_ChangePW(mSlot, - (oldPassword ? const_cast(aUtf8OldPassword.get()) : nullptr), - (newPassword ? const_cast(aUtf8NewPassword.get()) : nullptr)); - return (rv == SECSuccess) ? NS_OK : NS_ERROR_FAILURE; + // nsCString.get() will return an empty string instead of nullptr even if it + // was initialized with nullptr. PK11_ChangePW() has different semantics for + // the empty string and for nullptr, so we can't just use get(). + // See Bug 447589. + return MapSECStatus(PK11_ChangePW( + mSlot.get(), + (oldPassword ? const_cast(utf8OldPassword.get()) : nullptr), + (newPassword ? const_cast(utf8NewPassword.get()) : nullptr))); } NS_IMETHODIMP nsPK11Token::IsHardwareToken(bool *_retval) @@ -363,11 +399,9 @@ NS_IMETHODIMP nsPK11Token::IsHardwareToken(bool *_retval) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = NS_OK; + *_retval = PK11_IsHW(mSlot.get()); - *_retval = PK11_IsHW(mSlot); - - return rv; + return NS_OK; } NS_IMETHODIMP nsPK11Token::NeedsLogin(bool *_retval) @@ -376,11 +410,9 @@ NS_IMETHODIMP nsPK11Token::NeedsLogin(bool *_retval) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = NS_OK; + *_retval = PK11_NeedLogin(mSlot.get()); - *_retval = PK11_NeedLogin(mSlot); - - return rv; + return NS_OK; } NS_IMETHODIMP nsPK11Token::IsFriendly(bool *_retval) @@ -389,11 +421,9 @@ NS_IMETHODIMP nsPK11Token::IsFriendly(bool *_retval) if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = NS_OK; + *_retval = PK11_IsFriendly(mSlot.get()); - *_retval = PK11_IsFriendly(mSlot); - - return rv; + return NS_OK; } /*=========================================================*/ @@ -402,55 +432,65 @@ NS_IMPL_ISUPPORTS(nsPK11TokenDB, nsIPK11TokenDB) nsPK11TokenDB::nsPK11TokenDB() { - /* member initializers and constructor code */ } nsPK11TokenDB::~nsPK11TokenDB() { - /* destructor code */ + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return; + } + + shutdown(calledFromObject); } NS_IMETHODIMP nsPK11TokenDB::GetInternalKeyToken(nsIPK11Token **_retval) { nsNSSShutDownPreventionLock locker; - nsresult rv = NS_OK; - PK11SlotInfo *slot = 0; - nsCOMPtr token; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } - slot = PK11_GetInternalKeySlot(); - if (!slot) { rv = NS_ERROR_FAILURE; goto done; } + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } - token = new nsPK11Token(slot); + nsCOMPtr token = new nsPK11Token(slot.get()); token.forget(_retval); -done: - if (slot) PK11_FreeSlot(slot); - return rv; + return NS_OK; } NS_IMETHODIMP nsPK11TokenDB:: FindTokenByName(const char16_t* tokenName, nsIPK11Token **_retval) { nsNSSShutDownPreventionLock locker; - nsresult rv = NS_OK; - PK11SlotInfo *slot = 0; - nsCOMPtr token; - NS_ConvertUTF16toUTF8 aUtf8TokenName(tokenName); - slot = PK11_FindSlotByName(const_cast(aUtf8TokenName.get())); - if (!slot) { rv = NS_ERROR_FAILURE; goto done; } + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } - token = new nsPK11Token(slot); + NS_ConvertUTF16toUTF8 utf8TokenName(tokenName); + UniquePK11SlotInfo slot( + PK11_FindSlotByName(const_cast(utf8TokenName.get()))); + if (!slot) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr token = new nsPK11Token(slot.get()); token.forget(_retval); -done: - if (slot) PK11_FreeSlot(slot); - return rv; + return NS_OK; } NS_IMETHODIMP nsPK11TokenDB::ListTokens(nsISimpleEnumerator** _retval) { nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + nsCOMPtr array = do_CreateInstance(NS_ARRAY_CONTRACTID); if (!array) { return NS_ERROR_FAILURE; diff --git a/security/manager/ssl/nsPK11TokenDB.h b/security/manager/ssl/nsPK11TokenDB.h index 448a6be043..362eedf25c 100644 --- a/security/manager/ssl/nsPK11TokenDB.h +++ b/security/manager/ssl/nsPK11TokenDB.h @@ -4,17 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef __NS_PK11TOKENDB_H__ -#define __NS_PK11TOKENDB_H__ +#ifndef nsPK11TokenDB_h +#define nsPK11TokenDB_h #include "nsCOMPtr.h" -#include "nsString.h" -#include "nsISupports.h" -#include "nsIPK11TokenDB.h" #include "nsIPK11Token.h" +#include "nsIPK11TokenDB.h" +#include "nsISupports.h" #include "nsNSSHelper.h" -#include "pk11func.h" #include "nsNSSShutDown.h" +#include "nsString.h" +#include "pk11func.h" +#include "ScopedNSSTypes.h" class nsPK11Token : public nsIPK11Token, public nsNSSShutDownObject @@ -24,19 +25,18 @@ public: NS_DECL_NSIPK11TOKEN explicit nsPK11Token(PK11SlotInfo *slot); - /* additional members */ protected: virtual ~nsPK11Token(); private: friend class nsPK11TokenDB; - void refreshTokenInfo(); + nsresult refreshTokenInfo(const nsNSSShutDownPreventionLock& proofOfLock); nsString mTokenName; nsString mTokenLabel, mTokenManID, mTokenHWVersion, mTokenFWVersion; nsString mTokenSerialNum; - PK11SlotInfo *mSlot; + mozilla::UniquePK11SlotInfo mSlot; int mSeries; nsCOMPtr mUIContext; virtual void virtualDestroyNSSReference() override; @@ -44,6 +44,7 @@ private: }; class nsPK11TokenDB : public nsIPK11TokenDB + , public nsNSSShutDownObject { public: NS_DECL_ISUPPORTS @@ -53,11 +54,13 @@ public: protected: virtual ~nsPK11TokenDB(); - /* additional members */ + + // Nothing to release. + virtual void virtualDestroyNSSReference() override {} }; #define NS_PK11TOKENDB_CID \ { 0xb084a2ce, 0x1dd1, 0x11b2, \ { 0xbf, 0x10, 0x83, 0x24, 0xf8, 0xe0, 0x65, 0xcc }} -#endif +#endif // nsPK11TokenDB_h diff --git a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js index 775c3411dc..99725fafff 100644 --- a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js +++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js @@ -1,8 +1,9 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; -let FakeSSLStatus = function() { +var FakeSSLStatus = function() { }; FakeSSLStatus.prototype = { diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js index 7421ae0bd2..a627678808 100644 --- a/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js +++ b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js @@ -1,8 +1,9 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; -let gBugWindow; +var gBugWindow; function onLoad() { gBugWindow.removeEventListener("load", onLoad); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js b/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js index 3c751037ae..d1db319d09 100644 --- a/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js +++ b/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js @@ -1,8 +1,9 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; -let gBugWindow; +var gBugWindow; function onLoad() { gBugWindow.removeEventListener("load", onLoad); diff --git a/security/manager/ssl/tests/mochitest/browser/head.js b/security/manager/ssl/tests/mochitest/browser/head.js index babc1e7acd..1c042cd18b 100644 --- a/security/manager/ssl/tests/mochitest/browser/head.js +++ b/security/manager/ssl/tests/mochitest/browser/head.js @@ -1,5 +1,7 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + function whenNewWindowLoaded(aOptions, aCallback) { let win = OpenBrowserWindow(aOptions); win.addEventListener("load", function onLoad() { diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/backward.html b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html index 4993911502..825c2aa805 100644 --- a/security/manager/ssl/tests/mochitest/mixedcontent/backward.html +++ b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html @@ -2,7 +2,7 @@ diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html index 0b63569349..048ed811b3 100644 --- a/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html @@ -6,6 +6,7 @@ This is frame 2: diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js index 0aba91d107..f13595bf77 100644 --- a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js @@ -1,3 +1,5 @@ +"use strict"; + /** * Helper script for mixed content testing. It opens a new top-level window * from a secure origin and '?runtest' query. That tells us to run the test diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html index b5ba84b1b3..4bc6b81e18 100644 --- a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html @@ -8,6 +8,7 @@ - +