
|
 |
Коментар от: euphoria |
Дата: 16-12-2004 |
[ Други коментари] |
+diff -urN x/include/linux/socket.h y/include/linux/socket.h
+--- x/include/linux/socket.h 2004-08-24 17:18:39.000000000 +1000
++++ y/include/linux/socket.h 2004-12-10 21:29:17.000000000 +1100
+@@ -90,6 +90,10 @@
+ (struct cmsghdr *)(ctl) : \
+ (struct cmsghdr *)NULL)
+ #define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
++#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
++ (cmsg)->cmsg_len <= (unsigned long) \
++ ((mhdr)->msg_controllen - \
++ ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
+
+ /*
+ * This mess will go away with glibc
+diff -urN x/net/compat.c y/net/compat.c
+--- x/net/compat.c 2004-08-24 17:17:55.000000000 +1000
++++ y/net/compat.c 2004-12-10 21:24:13.000000000 +1100
+@@ -123,6 +123,12 @@
+ (struct compat_cmsghdr __user *)((msg)->msg_control) : \
+ (struct compat_cmsghdr __user *)NULL)
+
++#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
++ ((ucmlen) >= sizeof(struct cmsghdr) && \
++ (ucmlen) <= (unsigned long) \
++ ((mhdr)->msg_controllen - \
++ ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
++
+ static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
+ struct compat_cmsghdr __user *cmsg, int cmsg_len)
+ {
+@@ -153,11 +159,7 @@
+ return -EFAULT;
+
+ /* Catch bogons. */
+- if(CMSG_COMPAT_ALIGN(ucmlen) <
+- CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)))
+- return -EINVAL;
+- if((unsigned long)(((char __user *)ucmsg - (char __user *)kmsg->msg_control)
+- + ucmlen) > kmsg->msg_controllen)
++ if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
+ return -EINVAL;
+
+ tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
+diff -urN x/net/core/scm.c y/net/core/scm.c
+--- x/net/core/scm.c 2004-08-24 17:16:55.000000000 +1000
++++ y/net/core/scm.c 2004-12-10 21:29:17.000000000 +1100
+@@ -127,9 +127,7 @@
+ for too short ancillary data object at all! Oops.
+ OK, let's add it...
+ */
+- if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+- (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+- + cmsg->cmsg_len) > msg->msg_controllen)
++ if (!CMSG_OK(msg, cmsg))
+ goto error;
+
+ if (cmsg->cmsg_level != SOL_SOCKET)
+diff -urN x/net/ipv4/ip_sockglue.c y/net/ipv4/ip_sockglue.c
+--- x/net/ipv4/ip_sockglue.c 2004-08-24 17:16:28.000000000 +1000
++++ y/net/ipv4/ip_sockglue.c 2004-12-10 21:29:17.000000000 +1100
+@@ -146,11 +146,8 @@
+ struct cmsghdr *cmsg;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+- if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+- (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+- + cmsg->cmsg_len) > msg->msg_controllen) {
++ if (!CMSG_OK(msg, cmsg))
+ return -EINVAL;
+- }
+ if (cmsg->cmsg_level != SOL_IP)
+ continue;
+ switch (cmsg->cmsg_type) {
+diff -urN x/net/ipv6/datagram.c y/net/ipv6/datagram.c
+--- x/net/ipv6/datagram.c 2004-08-24 17:15:40.000000000 +1000
++++ y/net/ipv6/datagram.c 2004-12-10 21:29:17.000000000 +1100
+@@ -416,9 +416,7 @@
+ int addr_type;
+ struct net_device *dev = NULL;
+
+- if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+- (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+- + cmsg->cmsg_len) > msg->msg_controllen) {
++ if (!CMSG_OK(msg, cmsg)) {
+ err = -EINVAL;
+ goto exit_f;
+ }
+diff -urN x/net/sctp/socket.c y/net/sctp/socket.c
+--- x/net/sctp/socket.c 2004-08-24 17:20:00.000000000 +1000
++++ y/net/sctp/socket.c 2004-12-10 21:29:17.000000000 +1100
+@@ -4052,12 +4052,8 @@
+ for (cmsg = CMSG_FIRSTHDR(msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) {
+- /* Check for minimum length. The SCM code has this check. */
+- if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+- (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+- + cmsg->cmsg_len) > msg->msg_controllen) {
++ if (!CMSG_OK(msg, cmsg))
+ return -EINVAL;
+- }
+
+ /* Should we parse this header or ignore? */
+ if (cmsg->cmsg_level != IPPROTO_SCTP)
|
<< Fix за igmp бъга | |
|
 |
|
|
|
|
|
|