Bug 1204099 - RTP payload type validation. r=docfaraday
authorPaul Ellenbogen <pe5@cs.princeton.edu>
Tue, 19 Jul 2016 13:56:29 -0700
changeset 346373 e461c427a87edfb768b315d8a0ac4e4036c9d4a9
parent 346372 21d15da870e8f74b933429f4b3efd651747b8b31
child 346374 09f55c9ebc75c0454a7cc12df4212c1ae8d4bfe6
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdocfaraday
bugs1204099
milestone50.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 1204099 - RTP payload type validation. r=docfaraday MozReview-Commit-ID: LYNcxKqKwiC
media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
media/webrtc/signaling/test/jsep_session_unittest.cpp
--- a/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
+++ b/media/webrtc/signaling/src/jsep/JsepSessionImpl.cpp
@@ -2,16 +2,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/. */
 
 #include "logging.h"
 
 #include "signaling/src/jsep/JsepSessionImpl.h"
 #include <string>
 #include <set>
+#include <bitset>
 #include <stdlib.h>
 
 #include "nspr.h"
 #include "nss.h"
 #include "pk11pub.h"
 #include "nsDebug.h"
 
 #include <mozilla/Move.h>
@@ -32,16 +33,27 @@ MOZ_MTLOG_MODULE("jsep")
 #define JSEP_SET_ERROR(error)                                                  \
   do {                                                                         \
     std::ostringstream os;                                                     \
     os << error;                                                               \
     mLastError = os.str();                                                     \
     MOZ_MTLOG(ML_ERROR, mLastError);                                           \
   } while (0);
 
+static std::bitset<128> GetForbiddenSdpPayloadTypes() {
+  std::bitset<128> forbidden(0);
+  forbidden[1] = true;
+  forbidden[2] = true;
+  forbidden[19] = true;
+  for (uint16_t i = 64; i < 96; ++i) {
+    forbidden[i] = true;
+  }
+  return forbidden;
+}
+
 nsresult
 JsepSessionImpl::Init()
 {
   mLastError.clear();
 
   MOZ_ASSERT(!mSessionId, "Init called more than once");
 
   nsresult rv = SetupIds();
@@ -1653,26 +1665,31 @@ JsepSessionImpl::ParseSdp(const std::str
       }
 
       trackIds.insert(trackId);
     } else if (rv != NS_ERROR_NOT_AVAILABLE) {
       // Error has already been set
       return rv;
     }
 
+    static const std::bitset<128> forbidden = GetForbiddenSdpPayloadTypes();
     if (msection.GetMediaType() == SdpMediaSection::kAudio ||
         msection.GetMediaType() == SdpMediaSection::kVideo) {
       // Sanity-check that payload type can work with RTP
       for (const std::string& fmt : msection.GetFormats()) {
         uint16_t payloadType;
         // TODO (bug 1204099): Make this check for reserved ranges.
         if (!SdpHelper::GetPtAsInt(fmt, &payloadType) || payloadType > 127) {
           JSEP_SET_ERROR("audio/video payload type is too large: " << fmt);
           return NS_ERROR_INVALID_ARG;
         }
+	if (forbidden.test(payloadType)) {
+	  JSEP_SET_ERROR("Illegal audio/video payload type: " << fmt);
+          return NS_ERROR_INVALID_ARG;
+	}
       }
     }
   }
 
   *parsedp = Move(parsed);
   return NS_OK;
 }
 
--- a/media/webrtc/signaling/test/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp
@@ -2115,16 +2115,31 @@ TEST_P(JsepSessionTest, RenegotiationAns
   }
 
   ASSERT_NE(newOffererPairs[0].mRtpTransport.get(),
             offererPairs[0].mRtpTransport.get());
   ASSERT_NE(newAnswererPairs[0].mRtpTransport.get(),
             answererPairs[0].mRtpTransport.get());
 }
 
+TEST_P(JsepSessionTest, ParseRejectsBadMediaFormat)
+{
+  if (GetParam() == "datachannel") {
+    return;
+  }
+  AddTracks(mSessionOff);
+  std::string offer = CreateOffer();
+  UniquePtr<Sdp> munge(Parse(offer));
+  SdpMediaSection& mediaSection = munge->GetMediaSection(0);
+  mediaSection.AddCodec("75", "DummyFormatVal", 8000, 1);
+  std::string sdpString = munge->ToString();
+  nsresult rv = mSessionOff.SetLocalDescription(kJsepSdpOffer, sdpString);
+  ASSERT_EQ(NS_ERROR_INVALID_ARG, rv);
+}
+
 TEST_P(JsepSessionTest, FullCallWithCandidates)
 {
   AddTracks(mSessionOff);
   std::string offer = CreateOffer();
   SetLocalOffer(offer);
   mOffCandidates.Gather(mSessionOff, types);
 
   UniquePtr<Sdp> localOffer(Parse(mSessionOff.GetLocalDescription()));