--- zzzz-none-000/linux-2.6.32.61/net/unix/af_unix.c 2013-06-10 09:43:48.000000000 +0000 +++ ar10-7272-687/linux-2.6.32.61/net/unix/af_unix.c 2016-12-02 11:44:51.000000000 +0000 @@ -204,15 +204,16 @@ if (!sunaddr || sunaddr->sun_family != AF_UNIX) return -EINVAL; if (sunaddr->sun_path[0]) { - /* - * This may look like an off by one error but it is a bit more - * subtle. 108 is the longest valid AF_UNIX path for a binding. - * sun_path[108] doesnt as such exist. However in kernel space - * we are guaranteed that it is a valid memory location in our - * kernel address buffer. - */ + unsigned char value; + if(len == sizeof(*sunaddr)) len--; /*--- mbahr@avm: don't write over struct-boundary ! ---*/ + value = ((unsigned char *)sunaddr)[len]; ((char *)sunaddr)[len] = 0; len = strlen(sunaddr->sun_path)+1+sizeof(short); + if(value && (len == sizeof(*sunaddr))) { + /*--- mbahr@avm: check - UNIX_MAX_PATH include zero-termination! ---*/ + printk(KERN_ERR"%s: error sun_path exceeded '%s%c'\n", __func__, sunaddr->sun_path, value); + return -EINVAL; + } return len; } @@ -1530,7 +1531,7 @@ struct sock_iocb *siocb = kiocb_to_siocb(kiocb); struct sock *sk = sock->sk; struct sock *other = NULL; - struct sockaddr_un *sunaddr = msg->msg_name; + /*--- struct sockaddr_un *sunaddr = msg->msg_name; ---*/ int err, size; struct sk_buff *skb; int sent = 0; @@ -1553,7 +1554,7 @@ err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP; goto out_err; } else { - sunaddr = NULL; + /*--- sunaddr = NULL; ---*/ err = -ENOTCONN; other = unix_peer(sk); if (!other)