Thread (15 messages) 15 messages, 6 authors, 2014-07-29

Re: net: socket: NULL ptr deref in sendmsg

From: Hannes Frederic Sowa <hidden>
Date: 2014-07-26 15:54:45
Also in: lkml

On Sa, 2014-07-26 at 19:48 +0400, Andrey Ryabinin wrote:
quoted hunk ↗ jump to hunk
2014-07-26 2:15 GMT+04:00 Hannes Frederic Sowa [off-list ref]:
quoted
Otherwise I would just set msg_namelen = 0, too, and just not handle
passed in NULL pointers to sockaddrs.
I like that, how about such chage:
diff --git a/net/compat.c b/net/compat.c
index 9a76eaf..bc8aeef 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -85,7 +85,7 @@ int verify_compat_iovec(struct msghdr *kern_msg,
struct iovec *kern_iov,
 {
        int tot_len;

-       if (kern_msg->msg_namelen) {
+       if (kern_msg->msg_name && kern_msg->msg_namelen) {
                if (mode == VERIFY_READ) {
                        int err = move_addr_to_kernel(kern_msg->msg_name,
                                                      kern_msg->msg_namelen,
@@ -93,10 +93,11 @@ int verify_compat_iovec(struct msghdr *kern_msg,
struct iovec *kern_iov,
                        if (err < 0)
                                return err;
                }
-               if (kern_msg->msg_name)
-                       kern_msg->msg_name = kern_address;
-       } else
+               kern_msg->msg_name = kern_address;
+       } else {
                kern_msg->msg_name = NULL;
+               kern_msg->msg_namelen = 0;
+       }

        tot_len = iov_from_user_compat_to_kern(kern_iov,
                                          (struct compat_iovec __user
*)kern_msg->msg_iov,
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 827dd6b..e1ec45a 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -39,7 +39,7 @@ int verify_iovec(struct msghdr *m, struct iovec
*iov, struct sockaddr_storage *a
 {
        int size, ct, err;

-       if (m->msg_namelen) {
+       if (m->msg_name && m->msg_namelen) {
                if (mode == VERIFY_READ) {
                        void __user *namep;
                        namep = (void __user __force *) m->msg_name;
@@ -48,10 +48,10 @@ int verify_iovec(struct msghdr *m, struct iovec
*iov, struct sockaddr_storage *a
                        if (err < 0)
                                return err;
                }
-               if (m->msg_name)
-                       m->msg_name = address;
+               m->msg_name = address;
        } else {
                m->msg_name = NULL;
+               m->msg_namelen = 0;
        }

        size = m->msg_iovlen * sizeof(struct iovec);
LGTM! Can you send a patch?

Thanks,
Hannes
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help