Skip to content

Commit 230b183

Browse files
yoshfujidavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 53b7997 commit 230b183

File tree

5 files changed

+52
-42
lines changed

5 files changed

+52
-42
lines changed

include/linux/socket.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,10 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
306306
int offset,
307307
unsigned int len, __wsum *csump);
308308

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);
310310
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);
313313
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
314314

315315
#endif

include/net/compat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
3232
#endif /* defined(CONFIG_COMPAT) */
3333

3434
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);
3636
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsigned);
3737
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned);
3838
extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);

net/compat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
7575

7676
/* I've named the args so it is easy to tell whose space the pointers are in. */
7777
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)
7979
{
8080
int tot_len;
8181

net/core/iovec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* in any case.
3737
*/
3838

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)
4040
{
4141
int size, err, ct;
4242

net/socket.c

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ static DEFINE_PER_CPU(int, sockets_in_use) = 0;
180180
* invalid addresses -EFAULT is returned. On a success 0 is returned.
181181
*/
182182

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)
184184
{
185-
if (ulen < 0 || ulen > MAX_SOCK_ADDR)
185+
if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
186186
return -EINVAL;
187187
if (ulen == 0)
188188
return 0;
@@ -208,7 +208,7 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr)
208208
* specified. Zero is returned for a success.
209209
*/
210210

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,
212212
int __user *ulen)
213213
{
214214
int err;
@@ -219,7 +219,7 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
219219
return err;
220220
if (len > klen)
221221
len = klen;
222-
if (len < 0 || len > MAX_SOCK_ADDR)
222+
if (len < 0 || len > sizeof(struct sockaddr_storage))
223223
return -EINVAL;
224224
if (len) {
225225
if (audit_sockaddr(klen, kaddr))
@@ -1342,20 +1342,20 @@ asmlinkage long sys_socketpair(int family, int type, int protocol,
13421342
asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
13431343
{
13441344
struct socket *sock;
1345-
char address[MAX_SOCK_ADDR];
1345+
struct sockaddr_storage address;
13461346
int err, fput_needed;
13471347

13481348
sock = sockfd_lookup_light(fd, &err, &fput_needed);
13491349
if (sock) {
1350-
err = move_addr_to_kernel(umyaddr, addrlen, address);
1350+
err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
13511351
if (err >= 0) {
13521352
err = security_socket_bind(sock,
1353-
(struct sockaddr *)address,
1353+
(struct sockaddr *)&address,
13541354
addrlen);
13551355
if (!err)
13561356
err = sock->ops->bind(sock,
13571357
(struct sockaddr *)
1358-
address, addrlen);
1358+
&address, addrlen);
13591359
}
13601360
fput_light(sock->file, fput_needed);
13611361
}
@@ -1407,7 +1407,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
14071407
struct socket *sock, *newsock;
14081408
struct file *newfile;
14091409
int err, len, newfd, fput_needed;
1410-
char address[MAX_SOCK_ADDR];
1410+
struct sockaddr_storage address;
14111411

14121412
sock = sockfd_lookup_light(fd, &err, &fput_needed);
14131413
if (!sock)
@@ -1446,13 +1446,13 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
14461446
goto out_fd;
14471447

14481448
if (upeer_sockaddr) {
1449-
if (newsock->ops->getname(newsock, (struct sockaddr *)address,
1449+
if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
14501450
&len, 2) < 0) {
14511451
err = -ECONNABORTED;
14521452
goto out_fd;
14531453
}
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);
14561456
if (err < 0)
14571457
goto out_fd;
14581458
}
@@ -1495,22 +1495,22 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr,
14951495
int addrlen)
14961496
{
14971497
struct socket *sock;
1498-
char address[MAX_SOCK_ADDR];
1498+
struct sockaddr_storage address;
14991499
int err, fput_needed;
15001500

15011501
sock = sockfd_lookup_light(fd, &err, &fput_needed);
15021502
if (!sock)
15031503
goto out;
1504-
err = move_addr_to_kernel(uservaddr, addrlen, address);
1504+
err = move_addr_to_kernel(uservaddr, addrlen, (struct sockaddr *)&address);
15051505
if (err < 0)
15061506
goto out_put;
15071507

15081508
err =
1509-
security_socket_connect(sock, (struct sockaddr *)address, addrlen);
1509+
security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
15101510
if (err)
15111511
goto out_put;
15121512

1513-
err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
1513+
err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
15141514
sock->file->f_flags);
15151515
out_put:
15161516
fput_light(sock->file, fput_needed);
@@ -1527,7 +1527,7 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr,
15271527
int __user *usockaddr_len)
15281528
{
15291529
struct socket *sock;
1530-
char address[MAX_SOCK_ADDR];
1530+
struct sockaddr_storage address;
15311531
int len, err, fput_needed;
15321532

15331533
sock = sockfd_lookup_light(fd, &err, &fput_needed);
@@ -1538,10 +1538,10 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr,
15381538
if (err)
15391539
goto out_put;
15401540

1541-
err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
1541+
err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
15421542
if (err)
15431543
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);
15451545

15461546
out_put:
15471547
fput_light(sock->file, fput_needed);
@@ -1558,7 +1558,7 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr,
15581558
int __user *usockaddr_len)
15591559
{
15601560
struct socket *sock;
1561-
char address[MAX_SOCK_ADDR];
1561+
struct sockaddr_storage address;
15621562
int len, err, fput_needed;
15631563

15641564
sock = sockfd_lookup_light(fd, &err, &fput_needed);
@@ -1570,10 +1570,10 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr,
15701570
}
15711571

15721572
err =
1573-
sock->ops->getname(sock, (struct sockaddr *)address, &len,
1573+
sock->ops->getname(sock, (struct sockaddr *)&address, &len,
15741574
1);
15751575
if (!err)
1576-
err = move_addr_to_user(address, len, usockaddr,
1576+
err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr,
15771577
usockaddr_len);
15781578
fput_light(sock->file, fput_needed);
15791579
}
@@ -1591,7 +1591,7 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
15911591
int addr_len)
15921592
{
15931593
struct socket *sock;
1594-
char address[MAX_SOCK_ADDR];
1594+
struct sockaddr_storage address;
15951595
int err;
15961596
struct msghdr msg;
15971597
struct iovec iov;
@@ -1610,10 +1610,10 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
16101610
msg.msg_controllen = 0;
16111611
msg.msg_namelen = 0;
16121612
if (addr) {
1613-
err = move_addr_to_kernel(addr, addr_len, address);
1613+
err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address);
16141614
if (err < 0)
16151615
goto out_put;
1616-
msg.msg_name = address;
1616+
msg.msg_name = (struct sockaddr *)&address;
16171617
msg.msg_namelen = addr_len;
16181618
}
16191619
if (sock->file->f_flags & O_NONBLOCK)
@@ -1649,7 +1649,7 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
16491649
struct socket *sock;
16501650
struct iovec iov;
16511651
struct msghdr msg;
1652-
char address[MAX_SOCK_ADDR];
1652+
struct sockaddr_storage address;
16531653
int err, err2;
16541654
int fput_needed;
16551655

@@ -1663,14 +1663,15 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
16631663
msg.msg_iov = &iov;
16641664
iov.iov_len = size;
16651665
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);
16681668
if (sock->file->f_flags & O_NONBLOCK)
16691669
flags |= MSG_DONTWAIT;
16701670
err = sock_recvmsg(sock, &msg, size, flags);
16711671

16721672
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);
16741675
if (err2 < 0)
16751676
err = err2;
16761677
}
@@ -1790,7 +1791,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
17901791
struct compat_msghdr __user *msg_compat =
17911792
(struct compat_msghdr __user *)msg;
17921793
struct socket *sock;
1793-
char address[MAX_SOCK_ADDR];
1794+
struct sockaddr_storage address;
17941795
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
17951796
unsigned char ctl[sizeof(struct cmsghdr) + 20]
17961797
__attribute__ ((aligned(sizeof(__kernel_size_t))));
@@ -1828,9 +1829,13 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
18281829

18291830
/* This will also move the address data into kernel space */
18301831
if (MSG_CMSG_COMPAT & flags) {
1831-
err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
1832+
err = verify_compat_iovec(&msg_sys, iov,
1833+
(struct sockaddr *)&address,
1834+
VERIFY_READ);
18321835
} else
1833-
err = verify_iovec(&msg_sys, iov, address, VERIFY_READ);
1836+
err = verify_iovec(&msg_sys, iov,
1837+
(struct sockaddr *)&address,
1838+
VERIFY_READ);
18341839
if (err < 0)
18351840
goto out_freeiov;
18361841
total_len = err;
@@ -1901,7 +1906,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
19011906
int fput_needed;
19021907

19031908
/* kernel mode address */
1904-
char addr[MAX_SOCK_ADDR];
1909+
struct sockaddr_storage addr;
19051910

19061911
/* user mode address pointers */
19071912
struct sockaddr __user *uaddr;
@@ -1939,9 +1944,13 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
19391944
uaddr = (__force void __user *)msg_sys.msg_name;
19401945
uaddr_len = COMPAT_NAMELEN(msg);
19411946
if (MSG_CMSG_COMPAT & flags) {
1942-
err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
1947+
err = verify_compat_iovec(&msg_sys, iov,
1948+
(struct sockaddr *)&addr,
1949+
VERIFY_WRITE);
19431950
} else
1944-
err = verify_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
1951+
err = verify_iovec(&msg_sys, iov,
1952+
(struct sockaddr *)&addr,
1953+
VERIFY_WRITE);
19451954
if (err < 0)
19461955
goto out_freeiov;
19471956
total_len = err;
@@ -1957,7 +1966,8 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
19571966
len = err;
19581967

19591968
if (uaddr != NULL) {
1960-
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr,
1969+
err = move_addr_to_user((struct sockaddr *)&addr,
1970+
msg_sys.msg_namelen, uaddr,
19611971
uaddr_len);
19621972
if (err < 0)
19631973
goto out_freeiov;

0 commit comments

Comments
 (0)