]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
pptp nat helper fixes from Patrick McHardy
authorChris Wright <chrisw@sous-sol.org>
Wed, 11 Jan 2006 07:01:54 +0000 (23:01 -0800)
committerChris Wright <chrisw@sous-sol.org>
Wed, 11 Jan 2006 07:01:54 +0000 (23:01 -0800)
queue/netfilter-fix-another-crash-in-ip_nat_pptp.patch [new file with mode: 0644]
queue/netfilter-fix-crash-in-ip_nat_pptp.patch [new file with mode: 0644]
queue/series

diff --git a/queue/netfilter-fix-another-crash-in-ip_nat_pptp.patch b/queue/netfilter-fix-another-crash-in-ip_nat_pptp.patch
new file mode 100644 (file)
index 0000000..1420c53
--- /dev/null
@@ -0,0 +1,152 @@
+From stable-bounces@linux.kernel.org  Mon Jan  9 17:04:42 2006
+Message-ID: <43C30717.8030205@trash.net>
+Date: Tue, 10 Jan 2006 02:00:07 +0100
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Cc: 
+Subject: [NETFILTER]: Fix another crash in ip_nat_pptp
+
+The PPTP NAT helper calculates the offset at which the packet needs
+to be mangled as difference between two pointers to the header. With
+non-linear skbs however the pointers may point to two seperate buffers
+on the stack and the calculation results in a wrong offset beeing
+used.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/ipv4/netfilter/ip_nat_helper_pptp.c |   57 +++++++++++++++-----------------
+ 1 file changed, 27 insertions(+), 30 deletions(-)
+
+--- linux-2.6.15.y.orig/net/ipv4/netfilter/ip_nat_helper_pptp.c
++++ linux-2.6.15.y/net/ipv4/netfilter/ip_nat_helper_pptp.c
+@@ -148,14 +148,14 @@ pptp_outbound_pkt(struct sk_buff **pskb,
+ {
+       struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
+       struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+-
+-      u_int16_t msg, *cid = NULL, new_callid;
++      u_int16_t msg, new_callid;
++      unsigned int cid_off;
+       new_callid = htons(ct_pptp_info->pns_call_id);
+       
+       switch (msg = ntohs(ctlh->messageType)) {
+               case PPTP_OUT_CALL_REQUEST:
+-                      cid = &pptpReq->ocreq.callID;
++                      cid_off = offsetof(union pptp_ctrl_union, ocreq.callID);
+                       /* FIXME: ideally we would want to reserve a call ID
+                        * here.  current netfilter NAT core is not able to do
+                        * this :( For now we use TCP source port. This breaks
+@@ -172,10 +172,10 @@ pptp_outbound_pkt(struct sk_buff **pskb,
+                       ct_pptp_info->pns_call_id = ntohs(new_callid);
+                       break;
+               case PPTP_IN_CALL_REPLY:
+-                      cid = &pptpReq->icreq.callID;
++                      cid_off = offsetof(union pptp_ctrl_union, icreq.callID);
+                       break;
+               case PPTP_CALL_CLEAR_REQUEST:
+-                      cid = &pptpReq->clrreq.callID;
++                      cid_off = offsetof(union pptp_ctrl_union, clrreq.callID);
+                       break;
+               default:
+                       DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
+@@ -197,18 +197,15 @@ pptp_outbound_pkt(struct sk_buff **pskb,
+       /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
+        * down to here */
+-
+-      IP_NF_ASSERT(cid);
+-
+       DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+-              ntohs(*cid), ntohs(new_callid));
++              ntohs(*(u_int16_t *)pptpReq + cid_off), ntohs(new_callid));
+       /* mangle packet */
+       if (ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+-              (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
+-                                      sizeof(new_callid), 
+-                                      (char *)&new_callid,
+-                                      sizeof(new_callid)) == 0)
++                                   cid_off + sizeof(struct pptp_pkt_hdr) +
++                                   sizeof(struct PptpControlHeader),
++                                   sizeof(new_callid), (char *)&new_callid,
++                                   sizeof(new_callid)) == 0)
+               return NF_DROP;
+       return NF_ACCEPT;
+@@ -299,7 +296,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
+                union pptp_ctrl_union *pptpReq)
+ {
+       struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;
+-      u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;
++      u_int16_t msg, new_cid = 0, new_pcid;
++      unsigned int pcid_off, cid_off = 0;
+       int ret = NF_ACCEPT, rv;
+@@ -307,23 +305,23 @@ pptp_inbound_pkt(struct sk_buff **pskb,
+       switch (msg = ntohs(ctlh->messageType)) {
+       case PPTP_OUT_CALL_REPLY:
+-              pcid = &pptpReq->ocack.peersCallID;     
+-              cid = &pptpReq->ocack.callID;
++              pcid_off = offsetof(union pptp_ctrl_union, ocack.peersCallID);
++              cid_off = offsetof(union pptp_ctrl_union, ocack.callID);
+               break;
+       case PPTP_IN_CALL_CONNECT:
+-              pcid = &pptpReq->iccon.peersCallID;
++              pcid_off = offsetof(union pptp_ctrl_union, iccon.peersCallID);
+               break;
+       case PPTP_IN_CALL_REQUEST:
+               /* only need to nat in case PAC is behind NAT box */
+               return NF_ACCEPT;
+       case PPTP_WAN_ERROR_NOTIFY:
+-              pcid = &pptpReq->wanerr.peersCallID;
++              pcid_off = offsetof(union pptp_ctrl_union, wanerr.peersCallID);
+               break;
+       case PPTP_CALL_DISCONNECT_NOTIFY:
+-              pcid = &pptpReq->disc.callID;
++              pcid_off = offsetof(union pptp_ctrl_union, disc.callID);
+               break;
+       case PPTP_SET_LINK_INFO:
+-              pcid = &pptpReq->setlink.peersCallID;
++              pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
+               break;
+       default:
+@@ -345,25 +343,24 @@ pptp_inbound_pkt(struct sk_buff **pskb,
+        * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
+       /* mangle packet */
+-      IP_NF_ASSERT(pcid);
+       DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
+-              ntohs(*pcid), ntohs(new_pcid));
++              ntohs(*(u_int16_t *)pptpReq + pcid_off), ntohs(new_pcid));
+       
+-      rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 
+-                                    (void *)pcid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),
++      rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
++                                    pcid_off + sizeof(struct pptp_pkt_hdr) +
++                                    sizeof(struct PptpControlHeader),
+                                     sizeof(new_pcid), (char *)&new_pcid, 
+                                     sizeof(new_pcid));
+       if (rv != NF_ACCEPT) 
+               return rv;
+       if (new_cid) {
+-              IP_NF_ASSERT(cid);
+               DEBUGP("altering call id from 0x%04x to 0x%04x\n",
+-                      ntohs(*cid), ntohs(new_cid));
+-              rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 
+-                                            (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)), 
+-                                            sizeof(new_cid),
+-                                            (char *)&new_cid, 
++                      ntohs(*(u_int16_t *)pptpReq + cid_off), ntohs(new_cid));
++              rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,
++                                            cid_off + sizeof(struct pptp_pkt_hdr) +
++                                            sizeof(struct PptpControlHeader),
++                                            sizeof(new_cid), (char *)&new_cid, 
+                                             sizeof(new_cid));
+               if (rv != NF_ACCEPT)
+                       return rv;
diff --git a/queue/netfilter-fix-crash-in-ip_nat_pptp.patch b/queue/netfilter-fix-crash-in-ip_nat_pptp.patch
new file mode 100644 (file)
index 0000000..682e1d9
--- /dev/null
@@ -0,0 +1,30 @@
+From stable-bounces@linux.kernel.org  Mon Jan  9 17:04:42 2006
+Message-ID: <43C30717.8030205@trash.net>
+Date: Tue, 10 Jan 2006 02:00:07 +0100
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Cc: 
+Subject: [NETFILTER]: Fix crash in ip_nat_pptp
+
+When an inbound PPTP_IN_CALL_REQUEST packet is received the
+PPTP NAT helper uses a NULL pointer in pointer arithmentic to
+calculate the offset in the packet which needs to be mangled
+and corrupts random memory or crashes.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/ipv4/netfilter/ip_nat_helper_pptp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.15.y.orig/net/ipv4/netfilter/ip_nat_helper_pptp.c
++++ linux-2.6.15.y/net/ipv4/netfilter/ip_nat_helper_pptp.c
+@@ -315,7 +315,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
+               break;
+       case PPTP_IN_CALL_REQUEST:
+               /* only need to nat in case PAC is behind NAT box */
+-              break;
++              return NF_ACCEPT;
+       case PPTP_WAN_ERROR_NOTIFY:
+               pcid = &pptpReq->wanerr.peersCallID;
+               break;
index ac7f2baee4fc452319f18c66b71f7e73707bfe5f..2779d42c44028e3815f0663b0b7331a01e150ea5 100644 (file)
@@ -6,3 +6,5 @@ ppc32-re-add-embed_configc-to-ml300-ep405.patch
 vgacon-fix-doublescan-mode.patch
 fix-workqueue-oops-during-cpu-offline.patch
 netlink-oops-fix-due-to-incorrect-error-code.patch
+netfilter-fix-crash-in-ip_nat_pptp.patch
+netfilter-fix-another-crash-in-ip_nat_pptp.patch