Messages in this thread Patch in this message | | | Date | Fri, 27 Mar 1998 12:53:42 -0500 | From | Bill Hawes <> | Subject | possible memory leak in net/socket.c? |
| |
In looking over the handling of control buffers in net/socket.c, it seems that there may be a problem with the allocated buffer not being freed, or the memory credited back to the socket. The msg.controllen field is used to decide when to allocate a control buffer, and then used again when the buffer is freed. Buf this field may be decremented when the message is processed, possibly leading to the memory not being freed.
The attached patch keeps the allocated size in a local variable so that it can be freed properly after use.
Regards, Bill--- linux-2.1.91/net/socket.c.old Thu Mar 26 23:17:44 1998 +++ linux-2.1.91/net/socket.c Thu Mar 26 23:53:56 1998 @@ -1144,7 +1144,7 @@ unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */ unsigned char *ctl_buf = ctl; struct msghdr msg_sys; - int err, total_len; + int err, ctl_len, total_len; lock_kernel(); @@ -1161,16 +1161,16 @@ err = verify_iovec(&msg_sys, iov, address, VERIFY_READ); if (err < 0) goto out; - total_len=err; sock = sockfd_lookup(fd, &err); if (!sock) goto out_freeiov; - if (msg_sys.msg_controllen) + ctl_len = msg_sys.msg_controllen; + if (ctl_len) { - if (msg_sys.msg_controllen > sizeof(ctl)) + if (ctl_len > sizeof(ctl)) { /* Suggested by the Advanced Sockets API for IPv6 draft: * Limit the msg_controllen size by the SO_SNDBUF size. @@ -1179,15 +1179,13 @@ * SMP machines you have a race to fix here. */ err = -ENOBUFS; - ctl_buf = sock_kmalloc(sock->sk, msg_sys.msg_controllen, - GFP_KERNEL); + ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); if (ctl_buf == NULL) - goto failed2; + goto out_put; } err = -EFAULT; - if (copy_from_user(ctl_buf, msg_sys.msg_control, - msg_sys.msg_controllen)) - goto failed; + if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len)) + goto out_freectl; msg_sys.msg_control = ctl_buf; } msg_sys.msg_flags = flags; @@ -1196,10 +1194,10 @@ msg_sys.msg_flags |= MSG_DONTWAIT; err = sock_sendmsg(sock, &msg_sys, total_len); -failed: +out_freectl: if (ctl_buf != ctl) - sock_kfree_s(sock->sk, ctl_buf, msg_sys.msg_controllen); -failed2: + sock_kfree_s(sock->sk, ctl_buf, ctl_len); +out_put: sockfd_put(sock); out_freeiov: if (msg_sys.msg_iov != iov) | |