Skip to content

Commit a9c1462

Browse files
kcp-gitjfvogel
authored andcommitted
rds: Calling getsockname() on unbounded socket generates seg fault
If a socket is not yet bound, calling getsockname() should return an unspecified address with family AF_UNSPEC as an RDS socket can be bound to either an IPv4 or an IPv6 address. Hence returning either family is incorrect. Currently, the returned address is set to an unspecified address with family AF_INET6. If the passed in buffer is smaller than sizeof(struct sockaddr_in6), the app may get a segmentation fault error. This is similar to passing a buffer smaller than sizeof(struct sockaddr_in) before the IPv6 changes. Orabug: 27454280 Signed-off-by: Ka-Cheong Poon <[email protected]> Reviewed-by: Håkon Bugge <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]> Orabug: 33590097 UEK6 => UEK7 (cherry picked from commit f3a7321) cherry-pick-repo=UEK/production/linux-uek.git Signed-off-by: Gerd Rausch <[email protected]> Reviewed-by: William Kucharski <[email protected]>
1 parent ba4efa8 commit a9c1462

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

net/rds/af_rds.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006, 2017 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This software is available to you under a choice of one of two
55
* licenses. You may choose to be licensed under the terms of the GNU
@@ -173,6 +173,17 @@ static int rds_getname(struct socket *sock, struct sockaddr *uaddr,
173173
*uaddr_len = sizeof(*sin6);
174174
}
175175
} else {
176+
/* If socket is not yet bound, set the return address family
177+
* to be AF_UNSPEC (value 0) and the address size to be that
178+
* of an IPv4 address.
179+
*/
180+
if (ipv6_addr_any(&rs->rs_bound_addr)) {
181+
sin = (struct sockaddr_in *)uaddr;
182+
memset(sin, 0, sizeof(*sin));
183+
sin->sin_family = AF_UNSPEC;
184+
*uaddr_len = sizeof(*sin);
185+
return 0;
186+
}
176187
if (ipv6_addr_v4mapped(&rs->rs_bound_addr)) {
177188
sin = (struct sockaddr_in *)uaddr;
178189
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));

0 commit comments

Comments
 (0)