Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: Use standard structures for generic socket address structures.

Use sockaddr_storage{} for generic socket address storage
and ensures proper alignment.
Use sockaddr{} for pointers to omit several casts.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

YOSHIFUJI Hideaki and committed by
David S. Miller
230b1839 53b7997f

+52 -42
+3 -3
include/linux/socket.h
··· 306 306 int offset, 307 307 unsigned int len, __wsum *csump); 308 308 309 - extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode); 309 + extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); 310 310 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); 311 - extern int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ulen); 312 - extern int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr); 311 + extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen); 312 + extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr); 313 313 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); 314 314 315 315 #endif
+1 -1
include/net/compat.h
··· 32 32 #endif /* defined(CONFIG_COMPAT) */ 33 33 34 34 extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *); 35 - extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int); 35 + extern int verify_compat_iovec(struct msghdr *, struct iovec *, struct sockaddr *, int); 36 36 extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned); 37 37 extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); 38 38 extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
+1 -1
net/compat.c
··· 75 75 76 76 /* I've named the args so it is easy to tell whose space the pointers are in. */ 77 77 int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, 78 - char *kern_address, int mode) 78 + struct sockaddr *kern_address, int mode) 79 79 { 80 80 int tot_len; 81 81
+1 -1
net/core/iovec.c
··· 36 36 * in any case. 37 37 */ 38 38 39 - int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode) 39 + int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) 40 40 { 41 41 int size, err, ct; 42 42
+46 -36
net/socket.c
··· 180 180 * invalid addresses -EFAULT is returned. On a success 0 is returned. 181 181 */ 182 182 183 - int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr) 183 + int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr) 184 184 { 185 - if (ulen < 0 || ulen > MAX_SOCK_ADDR) 185 + if (ulen < 0 || ulen > sizeof(struct sockaddr_storage)) 186 186 return -EINVAL; 187 187 if (ulen == 0) 188 188 return 0; ··· 208 208 * specified. Zero is returned for a success. 209 209 */ 210 210 211 - int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, 211 + int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, 212 212 int __user *ulen) 213 213 { 214 214 int err; ··· 219 219 return err; 220 220 if (len > klen) 221 221 len = klen; 222 - if (len < 0 || len > MAX_SOCK_ADDR) 222 + if (len < 0 || len > sizeof(struct sockaddr_storage)) 223 223 return -EINVAL; 224 224 if (len) { 225 225 if (audit_sockaddr(klen, kaddr)) ··· 1342 1342 asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) 1343 1343 { 1344 1344 struct socket *sock; 1345 - char address[MAX_SOCK_ADDR]; 1345 + struct sockaddr_storage address; 1346 1346 int err, fput_needed; 1347 1347 1348 1348 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1349 1349 if (sock) { 1350 - err = move_addr_to_kernel(umyaddr, addrlen, address); 1350 + err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address); 1351 1351 if (err >= 0) { 1352 1352 err = security_socket_bind(sock, 1353 - (struct sockaddr *)address, 1353 + (struct sockaddr *)&address, 1354 1354 addrlen); 1355 1355 if (!err) 1356 1356 err = sock->ops->bind(sock, 1357 1357 (struct sockaddr *) 1358 - address, addrlen); 1358 + &address, addrlen); 1359 1359 } 1360 1360 fput_light(sock->file, fput_needed); 1361 1361 } ··· 1407 1407 struct socket *sock, *newsock; 1408 1408 struct file *newfile; 1409 1409 int err, len, newfd, fput_needed; 1410 - char address[MAX_SOCK_ADDR]; 1410 + struct sockaddr_storage address; 1411 1411 1412 1412 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1413 1413 if (!sock) ··· 1446 1446 goto out_fd; 1447 1447 1448 1448 if (upeer_sockaddr) { 1449 - if (newsock->ops->getname(newsock, (struct sockaddr *)address, 1449 + if (newsock->ops->getname(newsock, (struct sockaddr *)&address, 1450 1450 &len, 2) < 0) { 1451 1451 err = -ECONNABORTED; 1452 1452 goto out_fd; 1453 1453 } 1454 - err = move_addr_to_user(address, len, upeer_sockaddr, 1455 - upeer_addrlen); 1454 + err = move_addr_to_user((struct sockaddr *)&address, 1455 + len, upeer_sockaddr, upeer_addrlen); 1456 1456 if (err < 0) 1457 1457 goto out_fd; 1458 1458 } ··· 1495 1495 int addrlen) 1496 1496 { 1497 1497 struct socket *sock; 1498 - char address[MAX_SOCK_ADDR]; 1498 + struct sockaddr_storage address; 1499 1499 int err, fput_needed; 1500 1500 1501 1501 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1502 1502 if (!sock) 1503 1503 goto out; 1504 - err = move_addr_to_kernel(uservaddr, addrlen, address); 1504 + err = move_addr_to_kernel(uservaddr, addrlen, (struct sockaddr *)&address); 1505 1505 if (err < 0) 1506 1506 goto out_put; 1507 1507 1508 1508 err = 1509 - security_socket_connect(sock, (struct sockaddr *)address, addrlen); 1509 + security_socket_connect(sock, (struct sockaddr *)&address, addrlen); 1510 1510 if (err) 1511 1511 goto out_put; 1512 1512 1513 - err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen, 1513 + err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, 1514 1514 sock->file->f_flags); 1515 1515 out_put: 1516 1516 fput_light(sock->file, fput_needed); ··· 1527 1527 int __user *usockaddr_len) 1528 1528 { 1529 1529 struct socket *sock; 1530 - char address[MAX_SOCK_ADDR]; 1530 + struct sockaddr_storage address; 1531 1531 int len, err, fput_needed; 1532 1532 1533 1533 sock = sockfd_lookup_light(fd, &err, &fput_needed); ··· 1538 1538 if (err) 1539 1539 goto out_put; 1540 1540 1541 - err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0); 1541 + err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0); 1542 1542 if (err) 1543 1543 goto out_put; 1544 - err = move_addr_to_user(address, len, usockaddr, usockaddr_len); 1544 + err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, usockaddr_len); 1545 1545 1546 1546 out_put: 1547 1547 fput_light(sock->file, fput_needed); ··· 1558 1558 int __user *usockaddr_len) 1559 1559 { 1560 1560 struct socket *sock; 1561 - char address[MAX_SOCK_ADDR]; 1561 + struct sockaddr_storage address; 1562 1562 int len, err, fput_needed; 1563 1563 1564 1564 sock = sockfd_lookup_light(fd, &err, &fput_needed); ··· 1570 1570 } 1571 1571 1572 1572 err = 1573 - sock->ops->getname(sock, (struct sockaddr *)address, &len, 1573 + sock->ops->getname(sock, (struct sockaddr *)&address, &len, 1574 1574 1); 1575 1575 if (!err) 1576 - err = move_addr_to_user(address, len, usockaddr, 1576 + err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, 1577 1577 usockaddr_len); 1578 1578 fput_light(sock->file, fput_needed); 1579 1579 } ··· 1591 1591 int addr_len) 1592 1592 { 1593 1593 struct socket *sock; 1594 - char address[MAX_SOCK_ADDR]; 1594 + struct sockaddr_storage address; 1595 1595 int err; 1596 1596 struct msghdr msg; 1597 1597 struct iovec iov; ··· 1610 1610 msg.msg_controllen = 0; 1611 1611 msg.msg_namelen = 0; 1612 1612 if (addr) { 1613 - err = move_addr_to_kernel(addr, addr_len, address); 1613 + err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address); 1614 1614 if (err < 0) 1615 1615 goto out_put; 1616 - msg.msg_name = address; 1616 + msg.msg_name = (struct sockaddr *)&address; 1617 1617 msg.msg_namelen = addr_len; 1618 1618 } 1619 1619 if (sock->file->f_flags & O_NONBLOCK) ··· 1649 1649 struct socket *sock; 1650 1650 struct iovec iov; 1651 1651 struct msghdr msg; 1652 - char address[MAX_SOCK_ADDR]; 1652 + struct sockaddr_storage address; 1653 1653 int err, err2; 1654 1654 int fput_needed; 1655 1655 ··· 1663 1663 msg.msg_iov = &iov; 1664 1664 iov.iov_len = size; 1665 1665 iov.iov_base = ubuf; 1666 - msg.msg_name = address; 1667 - msg.msg_namelen = MAX_SOCK_ADDR; 1666 + msg.msg_name = (struct sockaddr *)&address; 1667 + msg.msg_namelen = sizeof(address); 1668 1668 if (sock->file->f_flags & O_NONBLOCK) 1669 1669 flags |= MSG_DONTWAIT; 1670 1670 err = sock_recvmsg(sock, &msg, size, flags); 1671 1671 1672 1672 if (err >= 0 && addr != NULL) { 1673 - err2 = move_addr_to_user(address, msg.msg_namelen, addr, addr_len); 1673 + err2 = move_addr_to_user((struct sockaddr *)&address, 1674 + msg.msg_namelen, addr, addr_len); 1674 1675 if (err2 < 0) 1675 1676 err = err2; 1676 1677 } ··· 1791 1790 struct compat_msghdr __user *msg_compat = 1792 1791 (struct compat_msghdr __user *)msg; 1793 1792 struct socket *sock; 1794 - char address[MAX_SOCK_ADDR]; 1793 + struct sockaddr_storage address; 1795 1794 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; 1796 1795 unsigned char ctl[sizeof(struct cmsghdr) + 20] 1797 1796 __attribute__ ((aligned(sizeof(__kernel_size_t)))); ··· 1829 1828 1830 1829 /* This will also move the address data into kernel space */ 1831 1830 if (MSG_CMSG_COMPAT & flags) { 1832 - err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ); 1831 + err = verify_compat_iovec(&msg_sys, iov, 1832 + (struct sockaddr *)&address, 1833 + VERIFY_READ); 1833 1834 } else 1834 - err = verify_iovec(&msg_sys, iov, address, VERIFY_READ); 1835 + err = verify_iovec(&msg_sys, iov, 1836 + (struct sockaddr *)&address, 1837 + VERIFY_READ); 1835 1838 if (err < 0) 1836 1839 goto out_freeiov; 1837 1840 total_len = err; ··· 1906 1901 int fput_needed; 1907 1902 1908 1903 /* kernel mode address */ 1909 - char addr[MAX_SOCK_ADDR]; 1904 + struct sockaddr_storage addr; 1910 1905 1911 1906 /* user mode address pointers */ 1912 1907 struct sockaddr __user *uaddr; ··· 1944 1939 uaddr = (__force void __user *)msg_sys.msg_name; 1945 1940 uaddr_len = COMPAT_NAMELEN(msg); 1946 1941 if (MSG_CMSG_COMPAT & flags) { 1947 - err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE); 1942 + err = verify_compat_iovec(&msg_sys, iov, 1943 + (struct sockaddr *)&addr, 1944 + VERIFY_WRITE); 1948 1945 } else 1949 - err = verify_iovec(&msg_sys, iov, addr, VERIFY_WRITE); 1946 + err = verify_iovec(&msg_sys, iov, 1947 + (struct sockaddr *)&addr, 1948 + VERIFY_WRITE); 1950 1949 if (err < 0) 1951 1950 goto out_freeiov; 1952 1951 total_len = err; ··· 1966 1957 len = err; 1967 1958 1968 1959 if (uaddr != NULL) { 1969 - err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, 1960 + err = move_addr_to_user((struct sockaddr *)&addr, 1961 + msg_sys.msg_namelen, uaddr, 1970 1962 uaddr_len); 1971 1963 if (err < 0) 1972 1964 goto out_freeiov;