Commit 8f7aeaf6b38fc0d4c8c3eb9292ae250579437724
1 parent
8fea3602
linux-user: return EINVAL on incorrect sockaddr
From: Lauro Ramos Venancio <lauro.venancio@gmail.com> Fixes ltp test accept01 Signed-off-by: Riku Voipio <riku.voipio@iki.fi> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6479 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
2 deletions
linux-user/syscall.c
... | ... | @@ -1140,11 +1140,19 @@ static abi_long do_socket(int domain, int type, int protocol) |
1140 | 1140 | return get_errno(socket(domain, type, protocol)); |
1141 | 1141 | } |
1142 | 1142 | |
1143 | +/* MAX_SOCK_ADDR from linux/net/socket.c */ | |
1144 | +#define MAX_SOCK_ADDR 128 | |
1145 | + | |
1143 | 1146 | /* do_bind() Must return target values and target errnos. */ |
1144 | 1147 | static abi_long do_bind(int sockfd, abi_ulong target_addr, |
1145 | 1148 | socklen_t addrlen) |
1146 | 1149 | { |
1147 | - void *addr = alloca(addrlen); | |
1150 | + void *addr; | |
1151 | + | |
1152 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1153 | + return -TARGET_EINVAL; | |
1154 | + | |
1155 | + addr = alloca(addrlen); | |
1148 | 1156 | |
1149 | 1157 | target_to_host_sockaddr(addr, target_addr, addrlen); |
1150 | 1158 | return get_errno(bind(sockfd, addr, addrlen)); |
... | ... | @@ -1154,7 +1162,12 @@ static abi_long do_bind(int sockfd, abi_ulong target_addr, |
1154 | 1162 | static abi_long do_connect(int sockfd, abi_ulong target_addr, |
1155 | 1163 | socklen_t addrlen) |
1156 | 1164 | { |
1157 | - void *addr = alloca(addrlen); | |
1165 | + void *addr; | |
1166 | + | |
1167 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1168 | + return -TARGET_EINVAL; | |
1169 | + | |
1170 | + addr = alloca(addrlen); | |
1158 | 1171 | |
1159 | 1172 | target_to_host_sockaddr(addr, target_addr, addrlen); |
1160 | 1173 | return get_errno(connect(sockfd, addr, addrlen)); |
... | ... | @@ -1226,6 +1239,9 @@ static abi_long do_accept(int fd, abi_ulong target_addr, |
1226 | 1239 | if (get_user_u32(addrlen, target_addrlen_addr)) |
1227 | 1240 | return -TARGET_EFAULT; |
1228 | 1241 | |
1242 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1243 | + return -TARGET_EINVAL; | |
1244 | + | |
1229 | 1245 | addr = alloca(addrlen); |
1230 | 1246 | |
1231 | 1247 | ret = get_errno(accept(fd, addr, &addrlen)); |
... | ... | @@ -1248,6 +1264,9 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr, |
1248 | 1264 | if (get_user_u32(addrlen, target_addrlen_addr)) |
1249 | 1265 | return -TARGET_EFAULT; |
1250 | 1266 | |
1267 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1268 | + return -TARGET_EINVAL; | |
1269 | + | |
1251 | 1270 | addr = alloca(addrlen); |
1252 | 1271 | |
1253 | 1272 | ret = get_errno(getpeername(fd, addr, &addrlen)); |
... | ... | @@ -1273,6 +1292,9 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr, |
1273 | 1292 | if (get_user_u32(addrlen, target_addrlen_addr)) |
1274 | 1293 | return -TARGET_EFAULT; |
1275 | 1294 | |
1295 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1296 | + return -TARGET_EINVAL; | |
1297 | + | |
1276 | 1298 | addr = alloca(addrlen); |
1277 | 1299 | |
1278 | 1300 | ret = get_errno(getsockname(fd, addr, &addrlen)); |
... | ... | @@ -1308,6 +1330,9 @@ static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, |
1308 | 1330 | void *host_msg; |
1309 | 1331 | abi_long ret; |
1310 | 1332 | |
1333 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) | |
1334 | + return -TARGET_EINVAL; | |
1335 | + | |
1311 | 1336 | host_msg = lock_user(VERIFY_READ, msg, len, 1); |
1312 | 1337 | if (!host_msg) |
1313 | 1338 | return -TARGET_EFAULT; |
... | ... | @@ -1340,6 +1365,10 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, |
1340 | 1365 | ret = -TARGET_EFAULT; |
1341 | 1366 | goto fail; |
1342 | 1367 | } |
1368 | + if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) { | |
1369 | + ret = -TARGET_EINVAL; | |
1370 | + goto fail; | |
1371 | + } | |
1343 | 1372 | addr = alloca(addrlen); |
1344 | 1373 | ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen)); |
1345 | 1374 | } else { | ... | ... |