Bug 1355274 - Polyfill SOCK_DGRAM socketpairs with SOCK_SEQPACKET, for libasyncns. r?gcp draft
authorJed Davis <jld@mozilla.com>
Tue, 11 Apr 2017 20:55:34 -0600
changeset 580597 53ed01a3a138e1ed20567244f2ba559f2a36bb3e
parent 579879 2c783a7b6d05b4b2b417bc5f21b7e40cbf3df077
child 629348 5390d94541aa200f6ac14025d8a34814eedde99f
push id59624
push userbmo:jld@mozilla.com
push dateThu, 18 May 2017 19:21:16 +0000
reviewersgcp
bugs1355274
milestone55.0a1
Bug 1355274 - Polyfill SOCK_DGRAM socketpairs with SOCK_SEQPACKET, for libasyncns. r?gcp MozReview-Commit-ID: 2DeklSGsjUV
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -495,43 +495,57 @@ private:
 
   static intptr_t GetPPidTrap(ArgsRef aArgs, void* aux) {
     // In a pid namespace, getppid() will return 0. We will return 0 instead
     // of the real parent pid to see what breaks when we introduce the
     // pid namespace (Bug 1151624).
     return 0;
   }
 
+  static intptr_t SocketpairDatagramTrap(ArgsRef aArgs, void* aux) {
+    auto fds = reinterpret_cast<int*>(aArgs.args[3]);
+    // Return sequential packet sockets instead of the expected
+    // datagram sockets; see bug 1355274 for details.
+    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds) != 0) {
+      return -errno;
+    }
+    return 0;
+  }
+
 public:
   explicit ContentSandboxPolicy(SandboxBrokerClient* aBroker,
                                 const std::vector<int>& aSyscallWhitelist)
     : mBroker(aBroker),
       mSyscallWhitelist(aSyscallWhitelist) {}
   virtual ~ContentSandboxPolicy() { }
   virtual ResultExpr PrctlPolicy() const override {
     // Ideally this should be restricted to a whitelist, but content
     // uses enough things that it's not trivial to determine it.
     return Allow();
   }
   virtual Maybe<ResultExpr> EvaluateSocketCall(int aCall) const override {
     switch(aCall) {
     case SYS_RECVFROM:
     case SYS_SENDTO:
+    case SYS_SENDMMSG: // libresolv via libasyncns; see bug 1355274
       return Some(Allow());
 
     case SYS_SOCKETPAIR: {
       // See bug 1066750.
       if (!kSocketCallHasArgs) {
         // We can't filter the args if the platform passes them by pointer.
         return Some(Allow());
       }
       Arg<int> domain(0), type(1);
-      return Some(If(AllOf(domain == AF_UNIX,
-                           AnyOf(type == SOCK_STREAM, type == SOCK_SEQPACKET)),
-                     Allow())
+      return Some(If(domain == AF_UNIX,
+                     Switch(type)
+                     .Case(SOCK_STREAM, Allow())
+                     .Case(SOCK_SEQPACKET, Allow())
+                     .Case(SOCK_DGRAM, Trap(SocketpairDatagramTrap, nullptr))
+                     .Default(InvalidSyscall()))
                   .Else(InvalidSyscall()));
     }
 
 #ifdef ANDROID
     case SYS_SOCKET:
       return Some(Error(EACCES));
 #else // #ifdef DESKTOP
     case SYS_RECV: