diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/net/socket.c b/net/socket.c index 1ba57d888981..64601f900352 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -349,11 +349,11 @@ static struct dentry_operations sockfs_dentry_operations = { | |||
349 | * but we take care of internal coherence yet. | 349 | * but we take care of internal coherence yet. |
350 | */ | 350 | */ |
351 | 351 | ||
352 | static int sock_alloc_fd(struct file **filep) | 352 | static int sock_alloc_fd(struct file **filep, int flags) |
353 | { | 353 | { |
354 | int fd; | 354 | int fd; |
355 | 355 | ||
356 | fd = get_unused_fd(); | 356 | fd = get_unused_fd_flags(flags); |
357 | if (likely(fd >= 0)) { | 357 | if (likely(fd >= 0)) { |
358 | struct file *file = get_empty_filp(); | 358 | struct file *file = get_empty_filp(); |
359 | 359 | ||
@@ -396,10 +396,10 @@ static int sock_attach_fd(struct socket *sock, struct file *file) | |||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | int sock_map_fd(struct socket *sock) | 399 | int sock_map_fd(struct socket *sock, int flags) |
400 | { | 400 | { |
401 | struct file *newfile; | 401 | struct file *newfile; |
402 | int fd = sock_alloc_fd(&newfile); | 402 | int fd = sock_alloc_fd(&newfile, flags); |
403 | 403 | ||
404 | if (likely(fd >= 0)) { | 404 | if (likely(fd >= 0)) { |
405 | int err = sock_attach_fd(sock, newfile); | 405 | int err = sock_attach_fd(sock, newfile); |
@@ -1218,12 +1218,18 @@ asmlinkage long sys_socket(int family, int type, int protocol) | |||
1218 | { | 1218 | { |
1219 | int retval; | 1219 | int retval; |
1220 | struct socket *sock; | 1220 | struct socket *sock; |
1221 | int flags; | ||
1222 | |||
1223 | flags = type & ~SOCK_TYPE_MASK; | ||
1224 | if (flags & ~SOCK_CLOEXEC) | ||
1225 | return -EINVAL; | ||
1226 | type &= SOCK_TYPE_MASK; | ||
1221 | 1227 | ||
1222 | retval = sock_create(family, type, protocol, &sock); | 1228 | retval = sock_create(family, type, protocol, &sock); |
1223 | if (retval < 0) | 1229 | if (retval < 0) |
1224 | goto out; | 1230 | goto out; |
1225 | 1231 | ||
1226 | retval = sock_map_fd(sock); | 1232 | retval = sock_map_fd(sock, flags & O_CLOEXEC); |
1227 | if (retval < 0) | 1233 | if (retval < 0) |
1228 | goto out_release; | 1234 | goto out_release; |
1229 | 1235 | ||
@@ -1246,6 +1252,12 @@ asmlinkage long sys_socketpair(int family, int type, int protocol, | |||
1246 | struct socket *sock1, *sock2; | 1252 | struct socket *sock1, *sock2; |
1247 | int fd1, fd2, err; | 1253 | int fd1, fd2, err; |
1248 | struct file *newfile1, *newfile2; | 1254 | struct file *newfile1, *newfile2; |
1255 | int flags; | ||
1256 | |||
1257 | flags = type & ~SOCK_TYPE_MASK; | ||
1258 | if (flags & ~SOCK_CLOEXEC) | ||
1259 | return -EINVAL; | ||
1260 | type &= SOCK_TYPE_MASK; | ||
1249 | 1261 | ||
1250 | /* | 1262 | /* |
1251 | * Obtain the first socket and check if the underlying protocol | 1263 | * Obtain the first socket and check if the underlying protocol |
@@ -1264,13 +1276,13 @@ asmlinkage long sys_socketpair(int family, int type, int protocol, | |||
1264 | if (err < 0) | 1276 | if (err < 0) |
1265 | goto out_release_both; | 1277 | goto out_release_both; |
1266 | 1278 | ||
1267 | fd1 = sock_alloc_fd(&newfile1); | 1279 | fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC); |
1268 | if (unlikely(fd1 < 0)) { | 1280 | if (unlikely(fd1 < 0)) { |
1269 | err = fd1; | 1281 | err = fd1; |
1270 | goto out_release_both; | 1282 | goto out_release_both; |
1271 | } | 1283 | } |
1272 | 1284 | ||
1273 | fd2 = sock_alloc_fd(&newfile2); | 1285 | fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC); |
1274 | if (unlikely(fd2 < 0)) { | 1286 | if (unlikely(fd2 < 0)) { |
1275 | err = fd2; | 1287 | err = fd2; |
1276 | put_filp(newfile1); | 1288 | put_filp(newfile1); |
@@ -1426,7 +1438,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, | |||
1426 | */ | 1438 | */ |
1427 | __module_get(newsock->ops->owner); | 1439 | __module_get(newsock->ops->owner); |
1428 | 1440 | ||
1429 | newfd = sock_alloc_fd(&newfile); | 1441 | newfd = sock_alloc_fd(&newfile, 0); |
1430 | if (unlikely(newfd < 0)) { | 1442 | if (unlikely(newfd < 0)) { |
1431 | err = newfd; | 1443 | err = newfd; |
1432 | sock_release(newsock); | 1444 | sock_release(newsock); |