Bug 1284910 - Add scary boolean to mediaDeviceInfo. r=jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 29 Sep 2016 15:37:25 -0400
changeset 318489 8eeb8a55dc9ef11f6afb084d5b11e1b84b08b6a7
parent 318488 52ae05c7eea3ae613421b8727cb5fb0c8e98059e
child 318490 92a0dbf7b7074fb5a4b4519a65fd5029e501d531
push id33308
push userjbruaroey@mozilla.com
push dateWed, 19 Oct 2016 11:57:37 +0000
treeherderautoland@8eeb8a55dc9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1284910
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1284910 - Add scary boolean to mediaDeviceInfo. r=jesup MozReview-Commit-ID: 2A7QZgUQH8l
dom/media/MediaManager.cpp
dom/media/MediaManager.h
dom/media/nsIDOMNavigatorUserMedia.idl
dom/media/webrtc/MediaEngine.h
dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
dom/media/webrtc/MediaEngineRemoteVideoSource.h
dom/media/webrtc/MediaEngineTabVideoSource.h
dom/media/webrtc/MediaEngineWebRTC.cpp
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -738,17 +738,18 @@ protected:
 };
 
 /**
  * nsIMediaDevice implementation.
  */
 NS_IMPL_ISUPPORTS(MediaDevice, nsIMediaDevice)
 
 MediaDevice::MediaDevice(MediaEngineSource* aSource, bool aIsVideo)
-  : mMediaSource(aSource->GetMediaSource())
+  : mScary(aSource->GetScary())
+  , mMediaSource(aSource->GetMediaSource())
   , mSource(aSource)
   , mIsVideo(aIsVideo)
 {
   mSource->GetName(mName);
   nsCString id;
   mSource->GetUUID(id);
   CopyUTF8toUTF16(id, mID);
 }
@@ -876,16 +877,23 @@ MediaDevice::GetId(nsAString& aID)
 
 NS_IMETHODIMP
 MediaDevice::GetRawId(nsAString& aID)
 {
   aID.Assign(mRawID);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MediaDevice::GetScary(bool* aScary)
+{
+  *aScary = mScary;
+  return NS_OK;
+}
+
 void
 MediaDevice::SetId(const nsAString& aID)
 {
   mID.Assign(aID);
 }
 
 void
 MediaDevice::SetRawId(const nsAString& aID)
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -89,16 +89,17 @@ private:
   static bool StringsContain(const dom::OwningStringOrStringSequence& aStrings,
                              nsString aN);
   static uint32_t FitnessDistance(nsString aN,
       const dom::ConstrainDOMStringParameters& aParams);
 protected:
   nsString mName;
   nsString mID;
   nsString mRawID;
+  bool mScary;
   dom::MediaSourceEnum mMediaSource;
   RefPtr<MediaEngineSource> mSource;
   RefPtr<MediaEngineSource::AllocationHandle> mAllocationHandle;
 public:
   dom::MediaSourceEnum GetMediaSource() {
     return mMediaSource;
   }
   bool mIsVideo;
--- a/dom/media/nsIDOMNavigatorUserMedia.idl
+++ b/dom/media/nsIDOMNavigatorUserMedia.idl
@@ -8,16 +8,17 @@
 [scriptable, builtinclass, uuid(ba3b2e08-1c07-4cd3-8822-f4d7e35ff2ae)]
 interface nsIMediaDevice : nsISupports
 {
   readonly attribute DOMString type;
   readonly attribute DOMString name;
   readonly attribute DOMString id;
   readonly attribute DOMString mediaSource;
   readonly attribute DOMString rawId;
+  readonly attribute boolean scary;
 };
 
 [scriptable, function, uuid(24544878-d35e-4962-8c5f-fb84e97bdfee)]
 interface nsIGetUserMediaDevicesSuccessCallback : nsISupports
 {
   void onSuccess(in nsIVariant devices);
 };
 
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -209,16 +209,19 @@ public:
   };
 
   /* Populate the human readable name of this device in the nsAString */
   virtual void GetName(nsAString&) const = 0;
 
   /* Populate the UUID of this device in the nsACString */
   virtual void GetUUID(nsACString&) const = 0;
 
+  /* Override w/true if source does end-run around cross origin restrictions. */
+  virtual bool GetScary() const { return false; };
+
   class AllocationHandle
   {
   public:
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AllocationHandle);
   protected:
     ~AllocationHandle() {}
   public:
     AllocationHandle(const dom::MediaTrackConstraints& aConstraints,
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -24,20 +24,21 @@ const unsigned int MediaEngineSource::kM
 const unsigned int MediaEngineSource::kMaxUniqueIdLength;;
 
 using dom::ConstrainLongRange;
 
 NS_IMPL_ISUPPORTS0(MediaEngineRemoteVideoSource)
 
 MediaEngineRemoteVideoSource::MediaEngineRemoteVideoSource(
   int aIndex, mozilla::camera::CaptureEngine aCapEngine,
-  dom::MediaSourceEnum aMediaSource, const char* aMonitorName)
+  dom::MediaSourceEnum aMediaSource, bool aScary, const char* aMonitorName)
   : MediaEngineCameraVideoSource(aIndex, aMonitorName),
     mMediaSource(aMediaSource),
-    mCapEngine(aCapEngine)
+    mCapEngine(aCapEngine),
+    mScary(aScary)
 {
   MOZ_ASSERT(aMediaSource != dom::MediaSourceEnum::Other);
   mSettings.mWidth.Construct(0);
   mSettings.mHeight.Construct(0);
   mSettings.mFrameRate.Construct(0);
   Init();
 }
 
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.h
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h
@@ -65,16 +65,17 @@ public:
                    void *handle) override;
   // XXX!!!! FIX THIS
   int DeliverI420Frame(const webrtc::I420VideoFrame& webrtc_frame) override { return 0; };
   bool IsTextureSupported() override { return false; };
 
   // MediaEngineCameraVideoSource
   MediaEngineRemoteVideoSource(int aIndex, mozilla::camera::CaptureEngine aCapEngine,
                                dom::MediaSourceEnum aMediaSource,
+                               bool aScary = false,
                                const char* aMonitorName = "RemoteVideo.Monitor");
 
   nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
                     const MediaEnginePrefs& aPrefs,
                     const nsString& aDeviceId,
                     const nsACString& aOrigin,
                     AllocationHandle** aOutHandle,
                     const char** aOutBadConstraint) override;
@@ -98,16 +99,18 @@ public:
   bool ChooseCapability(const NormalizedConstraints &aConstraints,
                         const MediaEnginePrefs &aPrefs,
                         const nsString& aDeviceId) override;
 
   void Refresh(int aIndex);
 
   void Shutdown() override;
 
+  bool GetScary() const override { return mScary; }
+
 protected:
   ~MediaEngineRemoteVideoSource() { }
 
 private:
   // Initialize the needed Video engine interfaces.
   void Init();
   size_t NumCapabilities() const override;
   void GetCapability(size_t aIndex, webrtc::CaptureCapability& aOut) const override;
@@ -120,13 +123,14 @@ private:
                      const nsString& aDeviceId,
                      const char** aOutBadConstraint) override;
 
   dom::MediaSourceEnum mMediaSource; // source of media (camera | application | screen)
   mozilla::camera::CaptureEngine mCapEngine;
 
   // To only restart camera when needed, we keep track previous settings.
   webrtc::CaptureCapability mLastCapability;
+  bool mScary;
 };
 
 }
 
 #endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -16,16 +16,21 @@ class MediaEngineTabVideoSource : public
   public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIDOMEVENTLISTENER
     NS_DECL_NSITIMERCALLBACK
     MediaEngineTabVideoSource();
 
     void GetName(nsAString_internal&) const override;
     void GetUUID(nsACString_internal&) const override;
+
+    bool GetScary() const override {
+      return true;
+    }
+
     nsresult Allocate(const dom::MediaTrackConstraints &,
                       const mozilla::MediaEnginePrefs&,
                       const nsString& aDeviceId,
                       const nsACString& aOrigin,
                       AllocationHandle** aOutHandle,
                       const char** aOutBadConstraint) override;
     nsresult Deallocate(AllocationHandle* aHandle) override;
     nsresult Start(mozilla::SourceMediaStream*, mozilla::TrackID, const mozilla::PrincipalHandle&) override;
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -152,29 +152,32 @@ MediaEngineWebRTC::EnumerateVideoDevices
   JNIEnv* const env = jni::GetEnvForThread();
   MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm));
 
   if (webrtc::VideoEngine::SetAndroidObjects(jvm) != 0) {
     LOG(("VieCapture:SetAndroidObjects Failed"));
     return;
   }
 #endif
+  bool scaryKind = false; // flag sources with cross-origin exploit potential
 
   switch (aMediaSource) {
     case dom::MediaSourceEnum::Window:
       capEngine = mozilla::camera::WinEngine;
       break;
     case dom::MediaSourceEnum::Application:
       capEngine = mozilla::camera::AppEngine;
       break;
     case dom::MediaSourceEnum::Screen:
       capEngine = mozilla::camera::ScreenEngine;
+      scaryKind = true;
       break;
     case dom::MediaSourceEnum::Browser:
       capEngine = mozilla::camera::BrowserEngine;
+      scaryKind = true;
       break;
     case dom::MediaSourceEnum::Camera:
       capEngine = mozilla::camera::CameraEngine;
       break;
     default:
       // BOOM
       MOZ_CRASH("No valid video engine");
       break;
@@ -191,16 +194,17 @@ MediaEngineWebRTC::EnumerateVideoDevices
   int num;
   num = mozilla::camera::GetChildAndCall(
     &mozilla::camera::CamerasChild::NumberOfCaptureDevices,
     capEngine);
 
   for (int i = 0; i < num; i++) {
     char deviceName[MediaEngineSource::kMaxDeviceNameLength];
     char uniqueId[MediaEngineSource::kMaxUniqueIdLength];
+    bool scaryWindow = false;
 
     // paranoia
     deviceName[0] = '\0';
     uniqueId[0] = '\0';
     int error;
 
     error =  mozilla::camera::GetChildAndCall(
       &mozilla::camera::CamerasChild::GetCaptureDevice,
@@ -210,16 +214,26 @@ MediaEngineWebRTC::EnumerateVideoDevices
       sizeof(uniqueId));
     if (error) {
       LOG(("camera:GetCaptureDevice: Failed %d", error ));
       continue;
     }
 #ifdef DEBUG
     LOG(("  Capture Device Index %d, Name %s", i, deviceName));
 
+    if (aMediaSource == dom::MediaSourceEnum::Window) {
+      // TODO: Detect firefox windows
+      //scaryWindow = true;
+    }
+
+    if (aMediaSource == dom::MediaSourceEnum::Application) {
+      // TODO: Detect firefox application windows
+      //scaryWindow = true;
+    }
+
     webrtc::CaptureCapability cap;
     int numCaps = mozilla::camera::GetChildAndCall(
       &mozilla::camera::CamerasChild::NumberOfCapabilities,
       capEngine,
       uniqueId);
     LOG(("Number of Capabilities %d", numCaps));
     for (int j = 0; j < numCaps; j++) {
       if (mozilla::camera::GetChildAndCall(
@@ -242,17 +256,18 @@ MediaEngineWebRTC::EnumerateVideoDevices
 
     RefPtr<MediaEngineVideoSource> vSource;
     NS_ConvertUTF8toUTF16 uuid(uniqueId);
     if (mVideoSources.Get(uuid, getter_AddRefs(vSource))) {
       // We've already seen this device, just refresh and append.
       static_cast<MediaEngineRemoteVideoSource*>(vSource.get())->Refresh(i);
       aVSources->AppendElement(vSource.get());
     } else {
-      vSource = new MediaEngineRemoteVideoSource(i, capEngine, aMediaSource);
+      vSource = new MediaEngineRemoteVideoSource(i, capEngine, aMediaSource,
+                                                 scaryKind || scaryWindow);
       mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
       aVSources->AppendElement(vSource);
     }
   }
 
   if (mHasTabVideoSource || dom::MediaSourceEnum::Browser == aMediaSource) {
     aVSources->AppendElement(new MediaEngineTabVideoSource());
   }