~ubuntu-branches/ubuntu/precise/rpcbind/precise-updates

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2015-7236.patch

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-09-25 08:18:39 UTC
  • mfrom: (22.2.1 precise-security)
  • Revision ID: package-import@ubuntu.com-20150925081839-amlmjo6koxww0ash
Tags: 0.2.0-7ubuntu1.3
* SECURITY UPDATE: denial of service and possible code execution via
  use-after-free
  - debian/patches/CVE-2015-7236.patch: fix memory corruption in
    PMAP_CALLIT code in src/rpcb_svc_com.c.
  - CVE-2015-7236

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
commit 06f7ebb1dade2f0dbf872ea2bedf17cff4734bdd
 
2
Author: Olaf Kirch <okir () suse de>
 
3
Date:   Thu Aug 6 16:27:20 2015 +0200
 
4
 
 
5
    Fix memory corruption in PMAP_CALLIT code
 
6
    
 
7
     - A PMAP_CALLIT call comes in on IPv4 UDP
 
8
     - rpcbind duplicates the caller's address to a netbuf and stores it in
 
9
       FINFO[0].caller_addr. caller_addr->buf now points to a memory region A
 
10
       with a size of 16 bytes
 
11
     - rpcbind forwards the call to the local service, receives a reply
 
12
     - when processing the reply, it does this in xprt_set_caller:
 
13
         xprt->xp_rtaddr = *FINFO[0].caller_addr
 
14
       It sends out the reply, and then frees the netbuf caller_addr and
 
15
       caller_addr.buf.
 
16
       However, it does not clear xp_rtaddr, so xp_rtaddr.buf now refers
 
17
       to memory region A, which is free.
 
18
     - When the next call comes in on the UDP/IPv4 socket, svc_dg_recv will
 
19
       be called, which will set xp_rtaddr to the client's address.
 
20
       It will reuse the buffer inside xp_rtaddr, ie it will write a
 
21
       sockaddr_in to region A
 
22
    
 
23
    Some time down the road, an incoming TCP connection is accepted,
 
24
    allocating a fresh SVCXPRT. The memory region A is inside the
 
25
    new SVCXPRT
 
26
    
 
27
     - While processing the TCP call, another UDP call comes in, again
 
28
       overwriting region A with the client's address
 
29
     - TCP client closes connection. In svc_destroy, we now trip over
 
30
       the garbage left in region A
 
31
    
 
32
    We ran into the case where a commercial scanner was triggering
 
33
    occasional rpcbind segfaults. The core file that was captured showed
 
34
    a corrupted xprt->xp_netid pointer that was really a sockaddr_in.
 
35
    
 
36
    Signed-off-by: Olaf Kirch <okir () suse de>
 
37
 
 
38
---
 
39
 src/rpcb_svc_com.c |   23 ++++++++++++++++++++++-
 
40
 1 file changed, 22 insertions(+), 1 deletion(-)
 
41
 
 
42
--- a/src/rpcb_svc_com.c
 
43
+++ b/src/rpcb_svc_com.c
 
44
@@ -1204,12 +1204,33 @@ check_rmtcalls(struct pollfd *pfds, int
 
45
        return (ncallbacks_found);
 
46
 }
 
47
 
 
48
+/*
 
49
+ * This is really a helper function defined in libtirpc, but unfortunately, it hasn't
 
50
+ * been exported yet.
 
51
+ */
 
52
+static struct netbuf *
 
53
+__rpc_set_netbuf(struct netbuf *nb, const void *ptr, size_t len)
 
54
+{
 
55
+       if (nb->len != len) {
 
56
+               if (nb->len)
 
57
+                       mem_free(nb->buf, nb->len);
 
58
+               nb->buf = mem_alloc(len);
 
59
+               if (nb->buf == NULL)
 
60
+                       return NULL;
 
61
+
 
62
+               nb->maxlen = nb->len = len;
 
63
+       }
 
64
+       memcpy(nb->buf, ptr, len);
 
65
+       return nb;
 
66
+}
 
67
+
 
68
 static void
 
69
 xprt_set_caller(SVCXPRT *xprt, struct finfo *fi)
 
70
 {
 
71
+       const struct netbuf *caller = fi->caller_addr;
 
72
        u_int32_t *xidp;
 
73
 
 
74
-       *(svc_getrpccaller(xprt)) = *(fi->caller_addr);
 
75
+       __rpc_set_netbuf(svc_getrpccaller(xprt), caller->buf, caller->len);
 
76
        xidp = __rpcb_get_dg_xidp(xprt);
 
77
        *xidp = fi->caller_xid;
 
78
 }