X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fcompat.c;h=be5d936dc42396ae0c8a18d77f80b72d04772d83;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6080b6439b968474163806d8f0bfa8a4546d4c21;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/net/compat.c b/net/compat.c index 6080b6439..be5d936dc 100644 --- a/net/compat.c +++ b/net/compat.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -123,6 +124,12 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, (struct compat_cmsghdr __user *)((msg)->msg_control) : \ (struct compat_cmsghdr __user *)NULL) +#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \ + ((ucmlen) >= sizeof(struct compat_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 +160,7 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, 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))) + @@ -264,6 +267,9 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) { int new_fd; + err = security_file_receive(fp[i]); + if (err) + break; err = get_unused_fd(); if (err < 0) break; @@ -501,7 +507,8 @@ static int do_get_sock_timeout(int fd, int level, int optname, asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) { - if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) + if (level == SOL_SOCKET && + (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) return do_get_sock_timeout(fd, level, optname, optval, optlen); return sys_getsockopt(fd, level, optname, optval, optlen); }