diff options
-rw-r--r-- | include/asm-mips/socket.h | 7 | ||||
-rw-r--r-- | include/linux/net.h | 9 | ||||
-rw-r--r-- | net/9p/trans_fd.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 2 | ||||
-rw-r--r-- | net/socket.c | 28 |
5 files changed, 37 insertions, 11 deletions
diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h index 63f60254d308..facc2d7a87ca 100644 --- a/include/asm-mips/socket.h +++ b/include/asm-mips/socket.h | |||
@@ -102,6 +102,13 @@ enum sock_type { | |||
102 | }; | 102 | }; |
103 | 103 | ||
104 | #define SOCK_MAX (SOCK_PACKET + 1) | 104 | #define SOCK_MAX (SOCK_PACKET + 1) |
105 | /* Mask which covers at least up to SOCK_MASK-1. The | ||
106 | * * remaining bits are used as flags. */ | ||
107 | #define SOCK_TYPE_MASK 0xf | ||
108 | |||
109 | /* Flags for socket, socketpair, paccept */ | ||
110 | #define SOCK_CLOEXEC O_CLOEXEC | ||
111 | #define SOCK_NONBLOCK O_NONBLOCK | ||
105 | 112 | ||
106 | #define ARCH_HAS_SOCKET_TYPES 1 | 113 | #define ARCH_HAS_SOCKET_TYPES 1 |
107 | 114 | ||
diff --git a/include/linux/net.h b/include/linux/net.h index 150a48c68d52..8b5383c45b45 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
22 | #include <linux/socket.h> | 22 | #include <linux/socket.h> |
23 | #include <linux/fcntl.h> /* For O_CLOEXEC */ | ||
23 | #include <asm/socket.h> | 24 | #include <asm/socket.h> |
24 | 25 | ||
25 | struct poll_table_struct; | 26 | struct poll_table_struct; |
@@ -94,6 +95,12 @@ enum sock_type { | |||
94 | }; | 95 | }; |
95 | 96 | ||
96 | #define SOCK_MAX (SOCK_PACKET + 1) | 97 | #define SOCK_MAX (SOCK_PACKET + 1) |
98 | /* Mask which covers at least up to SOCK_MASK-1. The | ||
99 | * remaining bits are used as flags. */ | ||
100 | #define SOCK_TYPE_MASK 0xf | ||
101 | |||
102 | /* Flags for socket, socketpair, paccept */ | ||
103 | #define SOCK_CLOEXEC O_CLOEXEC | ||
97 | 104 | ||
98 | #endif /* ARCH_HAS_SOCKET_TYPES */ | 105 | #endif /* ARCH_HAS_SOCKET_TYPES */ |
99 | 106 | ||
@@ -208,7 +215,7 @@ extern int sock_sendmsg(struct socket *sock, struct msghdr *msg, | |||
208 | size_t len); | 215 | size_t len); |
209 | extern int sock_recvmsg(struct socket *sock, struct msghdr *msg, | 216 | extern int sock_recvmsg(struct socket *sock, struct msghdr *msg, |
210 | size_t size, int flags); | 217 | size_t size, int flags); |
211 | extern int sock_map_fd(struct socket *sock); | 218 | extern int sock_map_fd(struct socket *sock, int flags); |
212 | extern struct socket *sockfd_lookup(int fd, int *err); | 219 | extern struct socket *sockfd_lookup(int fd, int *err); |
213 | #define sockfd_put(sock) fput(sock->file) | 220 | #define sockfd_put(sock) fput(sock->file) |
214 | extern int net_ratelimit(void); | 221 | extern int net_ratelimit(void); |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 4507f744f44e..cdf137af7adc 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -1285,7 +1285,7 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) | |||
1285 | int fd, ret; | 1285 | int fd, ret; |
1286 | 1286 | ||
1287 | csocket->sk->sk_allocation = GFP_NOIO; | 1287 | csocket->sk->sk_allocation = GFP_NOIO; |
1288 | fd = sock_map_fd(csocket); | 1288 | fd = sock_map_fd(csocket, 0); |
1289 | if (fd < 0) { | 1289 | if (fd < 0) { |
1290 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); | 1290 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); |
1291 | return fd; | 1291 | return fd; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 79bece16aede..dbb79adf8f3c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3910,7 +3910,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
3910 | goto out; | 3910 | goto out; |
3911 | 3911 | ||
3912 | /* Map the socket to an unused fd that can be returned to the user. */ | 3912 | /* Map the socket to an unused fd that can be returned to the user. */ |
3913 | retval = sock_map_fd(newsock); | 3913 | retval = sock_map_fd(newsock, 0); |
3914 | if (retval < 0) { | 3914 | if (retval < 0) { |
3915 | sock_release(newsock); | 3915 | sock_release(newsock); |
3916 | goto out; | 3916 | goto out; |
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); |