Blame view

net/socket.c 84.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   * NET		An implementation of the SOCKET network access protocol.
   *
   * Version:	@(#)socket.c	1.1.93	18/02/95
   *
   * Authors:	Orest Zborowski, <obz@Kodak.COM>
02c30a84e   Jesper Juhl   [PATCH] update Ro...
7
   *		Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
   *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   *
   * Fixes:
   *		Anonymous	:	NOTSOCK/BADF cleanup. Error fix in
   *					shutdown()
   *		Alan Cox	:	verify_area() fixes
   *		Alan Cox	:	Removed DDI
   *		Jonathan Kamens	:	SOCK_DGRAM reconnect bug
   *		Alan Cox	:	Moved a load of checks to the very
   *					top level.
   *		Alan Cox	:	Move address structures to/from user
   *					mode above the protocol layers.
   *		Rob Janssen	:	Allow 0 length sends.
   *		Alan Cox	:	Asynchronous I/O support (cribbed from the
   *					tty drivers).
   *		Niibe Yutaka	:	Asynchronous I/O for writes (4.4BSD style)
   *		Jeff Uphoff	:	Made max number of sockets command-line
   *					configurable.
   *		Matti Aarnio	:	Made the number of sockets dynamic,
   *					to be allocated when needed, and mr.
   *					Uphoff's max is used as max to be
   *					allowed to allocate.
   *		Linus		:	Argh. removed all the socket allocation
   *					altogether: it's in the inode now.
   *		Alan Cox	:	Made sock_alloc()/sock_release() public
   *					for NetROM and future kernel nfsd type
   *					stuff.
   *		Alan Cox	:	sendmsg/recvmsg basics.
   *		Tom Dyas	:	Export net symbols.
   *		Marcin Dalecki	:	Fixed problems with CONFIG_NET="n".
   *		Alan Cox	:	Added thread locking to sys_* calls
   *					for sockets. May have errors at the
   *					moment.
   *		Kevin Buhr	:	Fixed the dumb errors in the above.
   *		Andi Kleen	:	Some small cleanups, optimizations,
   *					and fixed a copy_from_user() bug.
   *		Tigran Aivazian	:	sys_send(args) calls sys_sendto(args, NULL, 0)
89bddce58   Stephen Hemminger   [NET] socket: cod...
45
   *		Tigran Aivazian	:	Made listen(2) backlog sanity checks
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
55
   *					protocol-independent
   *
   *
   *		This program is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   *
   *
   *	This module is effectively the top level interface to the BSD socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
56
   *	paradigm.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
   *
   *	Based upon Swansea University Computer Society NET3.039
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
  #include <linux/socket.h>
  #include <linux/file.h>
  #include <linux/net.h>
  #include <linux/interrupt.h>
aaca0bdca   Ulrich Drepper   flag parameters: ...
65
  #include <linux/thread_info.h>
55737fda0   Stephen Hemminger   [NET]: socket fam...
66
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
  #include <linux/netdevice.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
70
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  #include <linux/if_bridge.h>
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
72
73
  #include <linux/if_frad.h>
  #include <linux/if_vlan.h>
408eccce3   Daniel Borkmann   net: ptp: move PT...
74
  #include <linux/ptp_classify.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
  #include <linux/init.h>
  #include <linux/poll.h>
  #include <linux/cache.h>
  #include <linux/module.h>
  #include <linux/highmem.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
83
84
  #include <linux/mount.h>
  #include <linux/security.h>
  #include <linux/syscalls.h>
  #include <linux/compat.h>
  #include <linux/kmod.h>
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
85
  #include <linux/audit.h>
d86b5e0e6   Adrian Bunk   [PATCH] net/: fix...
86
  #include <linux/wireless.h>
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
87
  #include <linux/nsproxy.h>
1fd7317d0   Nick Black   Move magic number...
88
  #include <linux/magic.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
89
  #include <linux/slab.h>
600e17792   Masatake YAMATO   net: Providing pr...
90
  #include <linux/xattr.h>
c8e8cd579   Jeremy Cline   net: socket: fix ...
91
  #include <linux/nospec.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92

7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
93
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
  #include <asm/unistd.h>
  
  #include <net/compat.h>
87de87d5e   David S. Miller   wext: Dispatch an...
97
  #include <net/wext.h>
f84517253   Herbert Xu   cls_cgroup: Store...
98
  #include <net/cls_cgroup.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
  
  #include <net/sock.h>
  #include <linux/netfilter.h>
6b96018b2   Arnd Bergmann   compat: move sock...
102
103
104
  #include <linux/if_tun.h>
  #include <linux/ipv6_route.h>
  #include <linux/route.h>
6b96018b2   Arnd Bergmann   compat: move sock...
105
  #include <linux/sockios.h>
076bb0c82   Eliezer Tamir   net: rename inclu...
106
  #include <net/busy_poll.h>
f24b9be59   Willem de Bruijn   net-timestamp: ex...
107
  #include <linux/errqueue.h>
060212928   Eliezer Tamir   net: add low late...
108

e0d1095ae   Cong Wang   net: rename CONFI...
109
  #ifdef CONFIG_NET_RX_BUSY_POLL
64b0dc517   Eliezer Tamir   net: rename busy ...
110
111
  unsigned int sysctl_net_busy_read __read_mostly;
  unsigned int sysctl_net_busy_poll __read_mostly;
060212928   Eliezer Tamir   net: add low late...
112
  #endif
6b96018b2   Arnd Bergmann   compat: move sock...
113

8ae5e030f   Al Viro   net: switch socke...
114
115
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
89bddce58   Stephen Hemminger   [NET] socket: cod...
116
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
  
  static int sock_close(struct inode *inode, struct file *file);
a11e1d432   Linus Torvalds   Revert changes to...
119
120
  static __poll_t sock_poll(struct file *file,
  			      struct poll_table_struct *wait);
89bddce58   Stephen Hemminger   [NET] socket: cod...
121
  static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
122
123
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file,
89bddce58   Stephen Hemminger   [NET] socket: cod...
124
  			      unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
125
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
  static int sock_fasync(int fd, struct file *filp, int on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
  static ssize_t sock_sendpage(struct file *file, struct page *page,
  			     int offset, size_t size, loff_t *ppos, int more);
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
129
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
130
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
131
  				unsigned int flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
  /*
   *	Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
   *	in the operation structures but are done directly via the socketcall() multiplexor.
   */
da7071d7e   Arjan van de Ven   [PATCH] mark stru...
137
  static const struct file_operations socket_file_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  	.owner =	THIS_MODULE,
  	.llseek =	no_llseek,
8ae5e030f   Al Viro   net: switch socke...
140
141
  	.read_iter =	sock_read_iter,
  	.write_iter =	sock_write_iter,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
  	.poll =		sock_poll,
  	.unlocked_ioctl = sock_ioctl,
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
144
145
146
  #ifdef CONFIG_COMPAT
  	.compat_ioctl = compat_sock_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  	.mmap =		sock_mmap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
  	.release =	sock_close,
  	.fasync =	sock_fasync,
5274f052e   Jens Axboe   [PATCH] Introduce...
150
151
  	.sendpage =	sock_sendpage,
  	.splice_write = generic_splice_sendpage,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
152
  	.splice_read =	sock_splice_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
155
156
157
  };
  
  /*
   *	The protocol list. Each protocol is registered in here.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  static DEFINE_SPINLOCK(net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
159
  static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
162
163
164
   * Support routines.
   * Move socket addresses back and forth across the kernel/user
   * divide and look after the messy bits.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
168
169
170
171
172
173
174
175
  /**
   *	move_addr_to_kernel	-	copy a socket address into kernel space
   *	@uaddr: Address in user space
   *	@kaddr: Address in kernel space
   *	@ulen: Length in user space
   *
   *	The address is copied into kernel space. If the provided address is
   *	too long an error code of -EINVAL is returned. If the copy gives
   *	invalid addresses -EFAULT is returned. On a success 0 is returned.
   */
43db362d3   Maciej Żenczykowski   net: get rid of s...
176
  int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
178
  	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
180
  	if (ulen == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  		return 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
182
  	if (copy_from_user(kaddr, uaddr, ulen))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
184
  	return audit_sockaddr(ulen, kaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  }
  
  /**
   *	move_addr_to_user	-	copy an address to user space
   *	@kaddr: kernel space address
   *	@klen: length of address in kernel
   *	@uaddr: user space address
   *	@ulen: pointer to user length field
   *
   *	The value pointed to by ulen on entry is the buffer length available.
   *	This is overwritten with the buffer space used. -EINVAL is returned
   *	if an overlong buffer is specified or a negative buffer size. -EFAULT
   *	is returned if either the buffer or the length field are not
   *	accessible.
   *	After copying the data up to the limit the user specifies, the true
   *	length of the data is written over the length limit the user
   *	specified. Zero is returned for a success.
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
203

43db362d3   Maciej Żenczykowski   net: get rid of s...
204
  static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
11165f145   stephen hemminger   socket: localize ...
205
  			     void __user *uaddr, int __user *ulen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
208
  {
  	int err;
  	int len;
68c6beb37   Hannes Frederic Sowa   net: add BUG_ON i...
209
  	BUG_ON(klen > sizeof(struct sockaddr_storage));
89bddce58   Stephen Hemminger   [NET] socket: cod...
210
211
  	err = get_user(len, ulen);
  	if (err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
213
214
  	if (len > klen)
  		len = klen;
68c6beb37   Hannes Frederic Sowa   net: add BUG_ON i...
215
  	if (len < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
217
  	if (len) {
d6fe3945b   Steve Grubb   [PATCH] sockaddr ...
218
219
  		if (audit_sockaddr(klen, kaddr))
  			return -ENOMEM;
89bddce58   Stephen Hemminger   [NET] socket: cod...
220
  		if (copy_to_user(uaddr, kaddr, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
  			return -EFAULT;
  	}
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
224
225
  	 *      "fromlen shall refer to the value before truncation.."
  	 *                      1003.1g
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
228
  	 */
  	return __put_user(klen, ulen);
  }
08009a760   Alexey Dobriyan   net: make kmem ca...
229
  static struct kmem_cache *sock_inode_cachep __ro_after_init;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
  
  static struct inode *sock_alloc_inode(struct super_block *sb)
  {
  	struct socket_alloc *ei;
eaefd1105   Eric Dumazet   net: add __rcu an...
234
  	struct socket_wq *wq;
89bddce58   Stephen Hemminger   [NET] socket: cod...
235

e94b17660   Christoph Lameter   [PATCH] slab: rem...
236
  	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
  	if (!ei)
  		return NULL;
eaefd1105   Eric Dumazet   net: add __rcu an...
239
240
  	wq = kmalloc(sizeof(*wq), GFP_KERNEL);
  	if (!wq) {
438154823   Eric Dumazet   net: sock_def_rea...
241
242
243
  		kmem_cache_free(sock_inode_cachep, ei);
  		return NULL;
  	}
eaefd1105   Eric Dumazet   net: add __rcu an...
244
245
  	init_waitqueue_head(&wq->wait);
  	wq->fasync_list = NULL;
574aab1e0   Nicolai Stange   net, socket, sock...
246
  	wq->flags = 0;
e6476c214   Christoph Hellwig   net: remove bogus...
247
  	ei->socket.wq = wq;
89bddce58   Stephen Hemminger   [NET] socket: cod...
248

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
251
252
253
  	ei->socket.state = SS_UNCONNECTED;
  	ei->socket.flags = 0;
  	ei->socket.ops = NULL;
  	ei->socket.sk = NULL;
  	ei->socket.file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
257
258
259
  
  	return &ei->vfs_inode;
  }
  
  static void sock_destroy_inode(struct inode *inode)
  {
438154823   Eric Dumazet   net: sock_def_rea...
260
261
262
  	struct socket_alloc *ei;
  
  	ei = container_of(inode, struct socket_alloc, vfs_inode);
e6476c214   Christoph Hellwig   net: remove bogus...
263
  	kfree_rcu(ei->socket.wq, rcu);
438154823   Eric Dumazet   net: sock_def_rea...
264
  	kmem_cache_free(sock_inode_cachep, ei);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
266
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
268
  	struct socket_alloc *ei = (struct socket_alloc *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269

a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
270
  	inode_init_once(&ei->vfs_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
272

1e9116327   yuan linyu   net: change init_...
273
  static void init_inodecache(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
275
  {
  	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
89bddce58   Stephen Hemminger   [NET] socket: cod...
276
277
278
279
  					      sizeof(struct socket_alloc),
  					      0,
  					      (SLAB_HWCACHE_ALIGN |
  					       SLAB_RECLAIM_ACCOUNT |
5d097056c   Vladimir Davydov   kmemcg: account c...
280
  					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),
20c2df83d   Paul Mundt   mm: Remove slab d...
281
  					      init_once);
1e9116327   yuan linyu   net: change init_...
282
  	BUG_ON(sock_inode_cachep == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
  }
b87221de6   Alexey Dobriyan   const: mark remai...
284
  static const struct super_operations sockfs_ops = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
285
286
287
  	.alloc_inode	= sock_alloc_inode,
  	.destroy_inode	= sock_destroy_inode,
  	.statfs		= simple_statfs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  };
c23fbb6bc   Eric Dumazet   VFS: delay the de...
289
290
291
292
293
294
  /*
   * sockfs_dname() is called from d_path().
   */
  static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
  {
  	return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
c5ef60352   David Howells   VFS: net/: d_inod...
295
  				d_inode(dentry)->i_ino);
c23fbb6bc   Eric Dumazet   VFS: delay the de...
296
  }
3ba13d179   Al Viro   constify dentry_o...
297
  static const struct dentry_operations sockfs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
298
  	.d_dname  = sockfs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  };
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
  static int sockfs_xattr_get(const struct xattr_handler *handler,
  			    struct dentry *dentry, struct inode *inode,
  			    const char *suffix, void *value, size_t size)
  {
  	if (value) {
  		if (dentry->d_name.len + 1 > size)
  			return -ERANGE;
  		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
  	}
  	return dentry->d_name.len + 1;
  }
  
  #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
  #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
  #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
  
  static const struct xattr_handler sockfs_xattr_handler = {
  	.name = XATTR_NAME_SOCKPROTONAME,
  	.get = sockfs_xattr_get,
  };
4a5901537   Andreas Gruenbacher   xattr: Fix settin...
320
321
322
323
324
325
326
327
328
329
330
331
332
  static int sockfs_security_xattr_set(const struct xattr_handler *handler,
  				     struct dentry *dentry, struct inode *inode,
  				     const char *suffix, const void *value,
  				     size_t size, int flags)
  {
  	/* Handled by LSM. */
  	return -EAGAIN;
  }
  
  static const struct xattr_handler sockfs_security_xattr_handler = {
  	.prefix = XATTR_SECURITY_PREFIX,
  	.set = sockfs_security_xattr_set,
  };
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
333
334
  static const struct xattr_handler *sockfs_xattr_handlers[] = {
  	&sockfs_xattr_handler,
4a5901537   Andreas Gruenbacher   xattr: Fix settin...
335
  	&sockfs_security_xattr_handler,
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
336
337
  	NULL
  };
c74a1cbb3   Al Viro   pass default dent...
338
339
340
  static struct dentry *sockfs_mount(struct file_system_type *fs_type,
  			 int flags, const char *dev_name, void *data)
  {
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
341
342
343
  	return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops,
  				  sockfs_xattr_handlers,
  				  &sockfs_dentry_operations, SOCKFS_MAGIC);
c74a1cbb3   Al Viro   pass default dent...
344
345
346
347
348
349
350
351
352
  }
  
  static struct vfsmount *sock_mnt __read_mostly;
  
  static struct file_system_type sock_fs_type = {
  	.name =		"sockfs",
  	.mount =	sockfs_mount,
  	.kill_sb =	kill_anon_super,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
  /*
   *	Obtains the first available file descriptor and sets it up for use.
   *
39d8c1b6f   David S. Miller   [NET]: Do not los...
356
357
   *	These functions create file structures and maps them to fd space
   *	of the current process. On success it returns file descriptor
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
361
362
363
364
365
366
367
368
   *	and file struct implicitly stored in sock->file.
   *	Note that another thread may close file descriptor before we return
   *	from this function. We use the fact that now we do not refer
   *	to socket after mapping. If one day we will need it, this
   *	function will increment ref. count on file by 1.
   *
   *	In any case returned fd MAY BE not valid!
   *	This race condition is unavoidable
   *	with shared fd spaces, we cannot solve it inside kernel,
   *	but we take care of internal coherence yet.
   */
aab174f0d   Linus Torvalds   Merge branch 'for...
369
  struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
  {
7cbe66b6b   Al Viro   merge sock_alloc_...
371
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372

d93aa9d82   Al Viro   new wrapper: allo...
373
374
  	if (!dname)
  		dname = sock->sk ? sock->sk->sk_prot_creator->name : "";
39d8c1b6f   David S. Miller   [NET]: Do not los...
375

d93aa9d82   Al Viro   new wrapper: allo...
376
377
378
  	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
  				O_RDWR | (flags & O_NONBLOCK),
  				&socket_file_ops);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
379
  	if (IS_ERR(file)) {
8e1611e23   Al Viro   make sock_alloc_f...
380
  		sock_release(sock);
39b652527   Anatol Pomozov   fs: Preserve erro...
381
  		return file;
cc3808f8c   Al Viro   switch sock_alloc...
382
383
384
  	}
  
  	sock->file = file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
385
  	file->private_data = sock;
284076305   Al Viro   take descriptor h...
386
  	return file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
387
  }
56b31d1c9   Al Viro   unexport sock_map...
388
  EXPORT_SYMBOL(sock_alloc_file);
39d8c1b6f   David S. Miller   [NET]: Do not los...
389

56b31d1c9   Al Viro   unexport sock_map...
390
  static int sock_map_fd(struct socket *sock, int flags)
39d8c1b6f   David S. Miller   [NET]: Do not los...
391
392
  {
  	struct file *newfile;
284076305   Al Viro   take descriptor h...
393
  	int fd = get_unused_fd_flags(flags);
ce4bb04ca   Al Viro   Fix a leak in soc...
394
395
  	if (unlikely(fd < 0)) {
  		sock_release(sock);
284076305   Al Viro   take descriptor h...
396
  		return fd;
ce4bb04ca   Al Viro   Fix a leak in soc...
397
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
398

aab174f0d   Linus Torvalds   Merge branch 'for...
399
  	newfile = sock_alloc_file(sock, flags, NULL);
284076305   Al Viro   take descriptor h...
400
  	if (likely(!IS_ERR(newfile))) {
39d8c1b6f   David S. Miller   [NET]: Do not los...
401
  		fd_install(fd, newfile);
284076305   Al Viro   take descriptor h...
402
403
  		return fd;
  	}
7cbe66b6b   Al Viro   merge sock_alloc_...
404

284076305   Al Viro   take descriptor h...
405
406
  	put_unused_fd(fd);
  	return PTR_ERR(newfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
  }
406a3c638   John Fastabend   net: netprio_cgro...
408
  struct socket *sock_from_file(struct file *file, int *err)
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
409
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
410
411
  	if (file->f_op == &socket_file_ops)
  		return file->private_data;	/* set in sock_map_fd */
23bb80d21   Eric Dumazet   [NET]: cleanup so...
412
413
  	*err = -ENOTSOCK;
  	return NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
414
  }
406a3c638   John Fastabend   net: netprio_cgro...
415
  EXPORT_SYMBOL(sock_from_file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
416

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
  /**
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
418
   *	sockfd_lookup - Go from a file number to its socket slot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
420
421
422
   *	@fd: file handle
   *	@err: pointer to an error code return
   *
   *	The file handle passed in is locked and the socket it is bound
241c4667f   Rosen, Rami   net: socket: fix ...
423
   *	to is returned. If an error occurs the err pointer is overwritten
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
426
427
428
429
430
431
432
   *	with a negative errno code and NULL is returned. The function checks
   *	for both invalid handles and passing a handle which is not a socket.
   *
   *	On a success the socket object pointer is returned.
   */
  
  struct socket *sockfd_lookup(int fd, int *err)
  {
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
434
435
  	file = fget(fd);
  	if (!file) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
  		*err = -EBADF;
  		return NULL;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
439

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
440
441
  	sock = sock_from_file(file, err);
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  		fput(file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
443
444
  	return sock;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
445
  EXPORT_SYMBOL(sockfd_lookup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
447
448
  static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
  {
00e188ef6   Al Viro   sockfd_lookup_lig...
449
  	struct fd f = fdget(fd);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
450
  	struct socket *sock;
3672558c6   Hua Zhong   [NET]: sockfd_loo...
451
  	*err = -EBADF;
00e188ef6   Al Viro   sockfd_lookup_lig...
452
453
454
455
  	if (f.file) {
  		sock = sock_from_file(f.file, err);
  		if (likely(sock)) {
  			*fput_needed = f.flags;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
456
  			return sock;
00e188ef6   Al Viro   sockfd_lookup_lig...
457
458
  		}
  		fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
460
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
  }
600e17792   Masatake YAMATO   net: Providing pr...
462
463
464
465
466
  static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
  				size_t size)
  {
  	ssize_t len;
  	ssize_t used = 0;
c5ef60352   David Howells   VFS: net/: d_inod...
467
  	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
600e17792   Masatake YAMATO   net: Providing pr...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
  	if (len < 0)
  		return len;
  	used += len;
  	if (buffer) {
  		if (size < used)
  			return -ERANGE;
  		buffer += len;
  	}
  
  	len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
  	used += len;
  	if (buffer) {
  		if (size < used)
  			return -ERANGE;
  		memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
  		buffer += len;
  	}
  
  	return used;
  }
dc647ec88   Tobias Klauser   net: socket: Make...
488
  static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
86741ec25   Lorenzo Colitti   net: core: Add a ...
489
490
  {
  	int err = simple_setattr(dentry, iattr);
e1a3a60a2   Eric Biggers   net: socket: don'...
491
  	if (!err && (iattr->ia_valid & ATTR_UID)) {
86741ec25   Lorenzo Colitti   net: core: Add a ...
492
  		struct socket *sock = SOCKET_I(d_inode(dentry));
6d8c50dcb   Cong Wang   socket: close rac...
493
494
495
496
  		if (sock->sk)
  			sock->sk->sk_uid = iattr->ia_uid;
  		else
  			err = -ENOENT;
86741ec25   Lorenzo Colitti   net: core: Add a ...
497
498
499
500
  	}
  
  	return err;
  }
600e17792   Masatake YAMATO   net: Providing pr...
501
  static const struct inode_operations sockfs_inode_ops = {
600e17792   Masatake YAMATO   net: Providing pr...
502
  	.listxattr = sockfs_listxattr,
86741ec25   Lorenzo Colitti   net: core: Add a ...
503
  	.setattr = sockfs_setattr,
600e17792   Masatake YAMATO   net: Providing pr...
504
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505
506
  /**
   *	sock_alloc	-	allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
507
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
509
510
511
   *	Allocate a new inode and socket object. The two are bound together
   *	and initialised. The socket is then returned. If we are out of inodes
   *	NULL is returned.
   */
f4a00aacd   Tom Herbert   net: Make sock_al...
512
  struct socket *sock_alloc(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
514
515
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516

a209dfc7b   Eric Dumazet   vfs: dont chain p...
517
  	inode = new_inode_pseudo(sock_mnt->mnt_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
520
521
  	if (!inode)
  		return NULL;
  
  	sock = SOCKET_I(inode);
85fe4025c   Christoph Hellwig   fs: do not assign...
522
  	inode->i_ino = get_next_ino();
89bddce58   Stephen Hemminger   [NET] socket: cod...
523
  	inode->i_mode = S_IFSOCK | S_IRWXUGO;
8192b0c48   David Howells   CRED: Wrap task c...
524
525
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
600e17792   Masatake YAMATO   net: Providing pr...
526
  	inode->i_op = &sockfs_inode_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
  	return sock;
  }
f4a00aacd   Tom Herbert   net: Make sock_al...
530
  EXPORT_SYMBOL(sock_alloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
534
535
536
537
  /**
   *	sock_release	-	close a socket
   *	@sock: socket to close
   *
   *	The socket is released from the protocol stack if it has a release
   *	callback, and the inode is then released if the socket is bound to
89bddce58   Stephen Hemminger   [NET] socket: cod...
538
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
540

6d8c50dcb   Cong Wang   socket: close rac...
541
  static void __sock_release(struct socket *sock, struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
543
544
  {
  	if (sock->ops) {
  		struct module *owner = sock->ops->owner;
6d8c50dcb   Cong Wang   socket: close rac...
545
546
  		if (inode)
  			inode_lock(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  		sock->ops->release(sock);
5fdb551fd   Eric Biggers   net: socket: set ...
548
  		sock->sk = NULL;
6d8c50dcb   Cong Wang   socket: close rac...
549
550
  		if (inode)
  			inode_unlock(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
553
  		sock->ops = NULL;
  		module_put(owner);
  	}
e6476c214   Christoph Hellwig   net: remove bogus...
554
  	if (sock->wq->fasync_list)
3410f22ea   Yang Yingliang   socket: replace s...
555
556
  		pr_err("%s: fasync list not empty!
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
562
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  }
6d8c50dcb   Cong Wang   socket: close rac...
564
565
566
567
568
  
  void sock_release(struct socket *sock)
  {
  	__sock_release(sock, NULL);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
569
  EXPORT_SYMBOL(sock_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570

c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
571
  void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)
20d494735   Patrick Ohly   net: socket infra...
572
  {
140c55d4b   Eric Dumazet   net-timestamp: so...
573
  	u8 flags = *tx_flags;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
574
  	if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
140c55d4b   Eric Dumazet   net-timestamp: so...
575
  		flags |= SKBTX_HW_TSTAMP;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
576
  	if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
140c55d4b   Eric Dumazet   net-timestamp: so...
577
  		flags |= SKBTX_SW_TSTAMP;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
578
  	if (tsflags & SOF_TIMESTAMPING_TX_SCHED)
140c55d4b   Eric Dumazet   net-timestamp: so...
579
  		flags |= SKBTX_SCHED_TSTAMP;
140c55d4b   Eric Dumazet   net-timestamp: so...
580
  	*tx_flags = flags;
20d494735   Patrick Ohly   net: socket infra...
581
  }
67cc0d407   Willem de Bruijn   net-timestamp: op...
582
  EXPORT_SYMBOL(__sock_tx_timestamp);
20d494735   Patrick Ohly   net: socket infra...
583

d8725c86a   Al Viro   get rid of the si...
584
  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  {
01e97e651   Al Viro   new helper: msg_d...
586
  	int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
d8725c86a   Al Viro   get rid of the si...
587
588
  	BUG_ON(ret == -EIOCBQUEUED);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  }
d8725c86a   Al Viro   get rid of the si...
590
  int sock_sendmsg(struct socket *sock, struct msghdr *msg)
228e548e6   Anton Blanchard   net: Add sendmmsg...
591
  {
d8725c86a   Al Viro   get rid of the si...
592
  	int err = security_socket_sendmsg(sock, msg,
01e97e651   Al Viro   new helper: msg_d...
593
  					  msg_data_left(msg));
228e548e6   Anton Blanchard   net: Add sendmmsg...
594

d8725c86a   Al Viro   get rid of the si...
595
  	return err ?: sock_sendmsg_nosec(sock, msg);
0cf00c6f3   Gu Zheng   net/socket.c : in...
596
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
597
  EXPORT_SYMBOL(sock_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
600
601
  
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size)
  {
6aa248145   Al Viro   switch kernel_sen...
602
  	iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size);
d8725c86a   Al Viro   get rid of the si...
603
  	return sock_sendmsg(sock, msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
605
  EXPORT_SYMBOL(kernel_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606

306b13eb3   Tom Herbert   proto_ops: Add lo...
607
608
609
610
611
612
  int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
  			  struct kvec *vec, size_t num, size_t size)
  {
  	struct socket *sock = sk->sk_socket;
  
  	if (!sock->ops->sendmsg_locked)
db5980d80   John Fastabend   net: fixes for sk...
613
  		return sock_no_sendmsg_locked(sk, msg, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
614
615
616
617
618
619
  
  	iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size);
  
  	return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
  }
  EXPORT_SYMBOL(kernel_sendmsg_locked);
8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
620
621
622
623
624
625
626
627
628
  static bool skb_is_err_queue(const struct sk_buff *skb)
  {
  	/* pkt_type of skbs enqueued on the error queue are set to
  	 * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
  	 * in recvmsg, since skbs received on a local socket will never
  	 * have a pkt_type of PACKET_OUTGOING.
  	 */
  	return skb->pkt_type == PACKET_OUTGOING;
  }
b50a5c70f   Miroslav Lichvar   net: allow simult...
629
630
631
632
633
634
635
636
637
638
639
640
  /* On transmit, software and hardware timestamps are returned independently.
   * As the two skb clones share the hardware timestamp, which may be updated
   * before the software timestamp is received, a hardware TX timestamp may be
   * returned only if there is no software TX timestamp. Ignore false software
   * timestamps, which may be made in the __sock_recv_timestamp() call when the
   * option SO_TIMESTAMP(NS) is enabled on the socket, even when the skb has a
   * hardware timestamp.
   */
  static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
  {
  	return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
  }
aad9c8c47   Miroslav Lichvar   net: add new cont...
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
  static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
  {
  	struct scm_ts_pktinfo ts_pktinfo;
  	struct net_device *orig_dev;
  
  	if (!skb_mac_header_was_set(skb))
  		return;
  
  	memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
  
  	rcu_read_lock();
  	orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
  	if (orig_dev)
  		ts_pktinfo.if_index = orig_dev->ifindex;
  	rcu_read_unlock();
  
  	ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
  	put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
  		 sizeof(ts_pktinfo), &ts_pktinfo);
  }
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
661
662
663
664
665
666
  /*
   * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
   */
  void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
  	struct sk_buff *skb)
  {
20d494735   Patrick Ohly   net: socket infra...
667
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
f24b9be59   Willem de Bruijn   net-timestamp: ex...
668
  	struct scm_timestamping tss;
b50a5c70f   Miroslav Lichvar   net: allow simult...
669
  	int empty = 1, false_tstamp = 0;
20d494735   Patrick Ohly   net: socket infra...
670
671
672
673
674
  	struct skb_shared_hwtstamps *shhwtstamps =
  		skb_hwtstamps(skb);
  
  	/* Race occurred between timestamp enabling and packet
  	   receiving.  Fill in the current time for now. */
b50a5c70f   Miroslav Lichvar   net: allow simult...
675
  	if (need_software_tstamp && skb->tstamp == 0) {
20d494735   Patrick Ohly   net: socket infra...
676
  		__net_timestamp(skb);
b50a5c70f   Miroslav Lichvar   net: allow simult...
677
678
  		false_tstamp = 1;
  	}
20d494735   Patrick Ohly   net: socket infra...
679
680
681
682
683
684
685
686
  
  	if (need_software_tstamp) {
  		if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
  			struct timeval tv;
  			skb_get_timestamp(skb, &tv);
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
  				 sizeof(tv), &tv);
  		} else {
f24b9be59   Willem de Bruijn   net-timestamp: ex...
687
688
  			struct timespec ts;
  			skb_get_timestampns(skb, &ts);
20d494735   Patrick Ohly   net: socket infra...
689
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
690
  				 sizeof(ts), &ts);
20d494735   Patrick Ohly   net: socket infra...
691
692
  		}
  	}
f24b9be59   Willem de Bruijn   net-timestamp: ex...
693
  	memset(&tss, 0, sizeof(tss));
c199105d1   Willem de Bruijn   net-timestamp: on...
694
  	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
f24b9be59   Willem de Bruijn   net-timestamp: ex...
695
  	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
20d494735   Patrick Ohly   net: socket infra...
696
  		empty = 0;
4d276eb6a   Willem de Bruijn   net: remove depre...
697
  	if (shhwtstamps &&
b9f40e21e   Willem de Bruijn   net-timestamp: mo...
698
  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
b50a5c70f   Miroslav Lichvar   net: allow simult...
699
  	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
aad9c8c47   Miroslav Lichvar   net: add new cont...
700
  	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
4d276eb6a   Willem de Bruijn   net: remove depre...
701
  		empty = 0;
aad9c8c47   Miroslav Lichvar   net: add new cont...
702
703
704
705
  		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
  		    !skb_is_err_queue(skb))
  			put_ts_pktinfo(msg, skb);
  	}
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
706
  	if (!empty) {
20d494735   Patrick Ohly   net: socket infra...
707
  		put_cmsg(msg, SOL_SOCKET,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
708
  			 SCM_TIMESTAMPING, sizeof(tss), &tss);
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
709

8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
710
  		if (skb_is_err_queue(skb) && skb->len &&
4ef1b2869   Soheil Hassas Yeganeh   tcp: mark skbs wi...
711
  		    SKB_EXT_ERR(skb)->opt_stats)
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
712
713
714
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
  				 skb->len, skb->data);
  	}
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
715
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
716
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
6e3e939f3   Johannes Berg   net: add wireless...
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
  void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
  	struct sk_buff *skb)
  {
  	int ack;
  
  	if (!sock_flag(sk, SOCK_WIFI_STATUS))
  		return;
  	if (!skb->wifi_acked_valid)
  		return;
  
  	ack = skb->wifi_acked;
  
  	put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
  }
  EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
11165f145   stephen hemminger   socket: localize ...
732
733
  static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
  				   struct sk_buff *skb)
3b885787e   Neil Horman   net: Generalize s...
734
  {
744d5a3e9   Eyal Birger   net: move skb->dr...
735
  	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
3b885787e   Neil Horman   net: Generalize s...
736
  		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
744d5a3e9   Eyal Birger   net: move skb->dr...
737
  			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
3b885787e   Neil Horman   net: Generalize s...
738
  }
767dd0336   Eric Dumazet   net: speedup sock...
739
  void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
3b885787e   Neil Horman   net: Generalize s...
740
741
742
743
744
  	struct sk_buff *skb)
  {
  	sock_recv_timestamp(msg, sk, skb);
  	sock_recv_drops(msg, sk, skb);
  }
767dd0336   Eric Dumazet   net: speedup sock...
745
  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
3b885787e   Neil Horman   net: Generalize s...
746

1b7841404   Ying Xue   net: Remove iocb ...
747
  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
2da62906b   Al Viro   [net] drop 'size'...
748
  				     int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
  {
2da62906b   Al Viro   [net] drop 'size'...
750
  	return sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
  }
2da62906b   Al Viro   [net] drop 'size'...
752
  int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
753
  {
2da62906b   Al Viro   [net] drop 'size'...
754
  	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
755

2da62906b   Al Viro   [net] drop 'size'...
756
  	return err ?: sock_recvmsg_nosec(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
758
  EXPORT_SYMBOL(sock_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759

c1249c0aa   Martin Lucina   net: Document the...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
  /**
   * kernel_recvmsg - Receive a message from a socket (kernel space)
   * @sock:       The socket to receive the message from
   * @msg:        Received message
   * @vec:        Input s/g array for message data
   * @num:        Size of input s/g array
   * @size:       Number of bytes to read
   * @flags:      Message flags (MSG_DONTWAIT, etc...)
   *
   * On return the msg structure contains the scatter/gather array passed in the
   * vec argument. The array is modified so that it consists of the unfilled
   * portion of the original array.
   *
   * The returned value is the total number of bytes received, or an error.
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
775
776
  int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
778
779
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
6aa248145   Al Viro   switch kernel_sen...
780
  	iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
  	set_fs(KERNEL_DS);
2da62906b   Al Viro   [net] drop 'size'...
782
  	result = sock_recvmsg(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
784
785
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
786
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
788
789
  static ssize_t sock_sendpage(struct file *file, struct page *page,
  			     int offset, size_t size, loff_t *ppos, int more)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
792
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
793
  	sock = file->private_data;
35f9c09fe   Eric Dumazet   tcp: tcp_sendpage...
794
795
796
  	flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
  	/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
  	flags |= more;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
797

e69495838   Linus Torvalds   Make sock_sendpag...
798
  	return kernel_sendpage(sock, page, offset, size, flags);
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
799
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
801
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
802
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
803
804
805
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
806
807
  	if (unlikely(!sock->ops->splice_read))
  		return -EINVAL;
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
808
809
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
8ae5e030f   Al Viro   net: switch socke...
810
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
811
  {
6d6523302   Al Viro   net/socket.c: fol...
812
813
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
814
815
  	struct msghdr msg = {.msg_iter = *to,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
816
  	ssize_t res;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
817

8ae5e030f   Al Viro   net: switch socke...
818
819
820
821
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
  
  	if (iocb->ki_pos != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
823

66ee59af6   Christoph Hellwig   fs: remove ki_nbytes
824
  	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
  		return 0;
2da62906b   Al Viro   [net] drop 'size'...
826
  	res = sock_recvmsg(sock, &msg, msg.msg_flags);
8ae5e030f   Al Viro   net: switch socke...
827
828
  	*to = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
  }
8ae5e030f   Al Viro   net: switch socke...
830
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
831
  {
6d6523302   Al Viro   net/socket.c: fol...
832
833
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
834
835
  	struct msghdr msg = {.msg_iter = *from,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
836
  	ssize_t res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837

8ae5e030f   Al Viro   net: switch socke...
838
  	if (iocb->ki_pos != 0)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
839
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
840

8ae5e030f   Al Viro   net: switch socke...
841
842
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
6d6523302   Al Viro   net/socket.c: fol...
843
844
  	if (sock->type == SOCK_SEQPACKET)
  		msg.msg_flags |= MSG_EOR;
d8725c86a   Al Viro   get rid of the si...
845
  	res = sock_sendmsg(sock, &msg);
8ae5e030f   Al Viro   net: switch socke...
846
847
  	*from = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
850
851
852
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
853
  static DEFINE_MUTEX(br_ioctl_mutex);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
854
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855

881d966b4   Eric W. Biederman   [NET]: Make the d...
856
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
858
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
860
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
862
  }
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
863
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
864
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865

881d966b4   Eric W. Biederman   [NET]: Make the d...
866
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
868
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
870
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
872
  }
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
873
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
874
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875

89bddce58   Stephen Hemminger   [NET] socket: cod...
876
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
878
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
880
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
882
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
883
  static long sock_do_ioctl(struct net *net, struct socket *sock,
99f3c8966   Johannes Berg   Revert "socket: f...
884
  			  unsigned int cmd, unsigned long arg)
6b96018b2   Arnd Bergmann   compat: move sock...
885
886
887
888
889
890
891
892
893
894
  {
  	int err;
  	void __user *argp = (void __user *)arg;
  
  	err = sock->ops->ioctl(sock, cmd, arg);
  
  	/*
  	 * If this ioctl is unknown try to hand it down
  	 * to the NIC driver.
  	 */
36fd633ec   Al Viro   net: separate SIO...
895
896
  	if (err != -ENOIOCTLCMD)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
897

36fd633ec   Al Viro   net: separate SIO...
898
899
900
901
902
903
904
905
906
  	if (cmd == SIOCGIFCONF) {
  		struct ifconf ifc;
  		if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
  			return -EFAULT;
  		rtnl_lock();
  		err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
  		rtnl_unlock();
  		if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
  			err = -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
907
908
909
  	} else {
  		struct ifreq ifr;
  		bool need_copyout;
99f3c8966   Johannes Berg   Revert "socket: f...
910
  		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
911
912
913
  			return -EFAULT;
  		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
  		if (!err && need_copyout)
99f3c8966   Johannes Berg   Revert "socket: f...
914
  			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
915
  				return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
916
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
917
918
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
920
921
922
  /*
   *	With an ioctl, arg may well be a user mode pointer, but we don't know
   *	what to do with it - that's up to the protocol still.
   */
d8d211a2a   Kirill Tkhai   net: Make extern ...
923
  struct ns_common *get_net_ns(struct ns_common *ns)
c62cce2ca   Andrey Vagin   net: add an ioctl...
924
925
926
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
d8d211a2a   Kirill Tkhai   net: Make extern ...
927
  EXPORT_SYMBOL_GPL(get_net_ns);
c62cce2ca   Andrey Vagin   net: add an ioctl...
928

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
930
931
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
  	struct socket *sock;
881d966b4   Eric W. Biederman   [NET]: Make the d...
932
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
933
934
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
935
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936

b69aee04f   Eric Dumazet   [NET]: Use file->...
937
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
938
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
939
  	net = sock_net(sk);
44c02a2c3   Al Viro   dev_ioctl(): move...
940
941
942
943
944
945
946
947
948
  	if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
  		struct ifreq ifr;
  		bool need_copyout;
  		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
  			return -EFAULT;
  		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
  		if (!err && need_copyout)
  			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
  				return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
  	} else
3d23e349d   Johannes Berg   wext: refactor
950
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
b1b0c2450   Al Viro   lift handling of ...
952
  		err = wext_handle_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
953
  	} else
3d23e349d   Johannes Berg   wext: refactor
954
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
955
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
957
958
959
960
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
393cc3f51   Jiri Slaby   fs/fcntl: f_setow...
961
  			err = f_setown(sock->file, pid, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
964
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
965
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
966
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
968
969
970
971
972
973
974
  			break;
  		case SIOCGIFBR:
  		case SIOCSIFBR:
  		case SIOCBRADDBR:
  		case SIOCBRDELBR:
  			err = -ENOPKG;
  			if (!br_ioctl_hook)
  				request_module("bridge");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
975
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
976
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
977
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
978
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
981
982
983
984
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
985
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
986
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
987
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
988
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
992
993
994
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
995
996
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
998
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
  			break;
c62cce2ca   Andrey Vagin   net: add an ioctl...
1000
1001
1002
1003
1004
1005
1006
  		case SIOCGSKNS:
  			err = -EPERM;
  			if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
  				break;
  
  			err = open_related_ns(&net->ns, get_net_ns);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
  		default:
99f3c8966   Johannes Berg   Revert "socket: f...
1008
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1010
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
1012
1013
1014
1015
1016
1017
  	return err;
  }
  
  int sock_create_lite(int family, int type, int protocol, struct socket **res)
  {
  	int err;
  	struct socket *sock = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1018

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
1020
1021
1022
1023
1024
1025
1026
1027
  	err = security_socket_create(family, type, protocol, 1);
  	if (err)
  		goto out;
  
  	sock = sock_alloc();
  	if (!sock) {
  		err = -ENOMEM;
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1028
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1029
1030
1031
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1032
1033
1034
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1035
1036
1037
1038
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1040
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
  
  /* No kernel lock held - perfect */
ade994f4f   Al Viro   net: annotate ->p...
1043
  static __poll_t sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
  {
3cafb3763   Christoph Hellwig   net: refactor soc...
1045
  	struct socket *sock = file->private_data;
a331de3bf   Christoph Hellwig   net: remove sock_...
1046
  	__poll_t events = poll_requested_events(wait), flag = 0;
2d48d67fa   Eliezer Tamir   net: poll/select ...
1047

e88958e63   Christoph Hellwig   net: handle NULL ...
1048
1049
  	if (!sock->ops->poll)
  		return 0;
f641f13b9   Christoph Hellwig   net: remove sock_...
1050

a331de3bf   Christoph Hellwig   net: remove sock_...
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
  	if (sk_can_busy_loop(sock->sk)) {
  		/* poll once if requested by the syscall */
  		if (events & POLL_BUSY_LOOP)
  			sk_busy_loop(sock->sk, 1);
  
  		/* if this socket can poll_ll, tell the system call */
  		flag = POLL_BUSY_LOOP;
  	}
  
  	return sock->ops->poll(file, sock, wait) | flag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1062
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1063
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
1064
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
1066
1067
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1068
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1069
  {
6d8c50dcb   Cong Wang   socket: close rac...
1070
  	__sock_release(SOCKET_I(inode), inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
  	return 0;
  }
  
  /*
   *	Update the socket async list
   *
   *	Fasync_list locking strategy.
   *
   *	1. fasync_list is modified only under process context socket lock
   *	   i.e. under semaphore.
   *	2. fasync_list is used under read_lock(&sk->sk_callback_lock)
989a29792   Eric Dumazet   fasync: RCU and f...
1082
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083
1084
1085
1086
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1087
1088
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
eaefd1105   Eric Dumazet   net: add __rcu an...
1089
  	struct socket_wq *wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090

989a29792   Eric Dumazet   fasync: RCU and f...
1091
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
1094
  
  	lock_sock(sk);
e6476c214   Christoph Hellwig   net: remove bogus...
1095
  	wq = sock->wq;
eaefd1105   Eric Dumazet   net: add __rcu an...
1096
  	fasync_helper(fd, filp, on, &wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1097

eaefd1105   Eric Dumazet   net: add __rcu an...
1098
  	if (!wq->fasync_list)
989a29792   Eric Dumazet   fasync: RCU and f...
1099
1100
  		sock_reset_flag(sk, SOCK_FASYNC);
  	else
bcdce7195   Eric Dumazet   net: speedup sk_w...
1101
  		sock_set_flag(sk, SOCK_FASYNC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1102

989a29792   Eric Dumazet   fasync: RCU and f...
1103
  	release_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
1105
  	return 0;
  }
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1106
  /* This function may be called only under rcu_lock */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1108
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1110
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1111
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1112

89bddce58   Stephen Hemminger   [NET] socket: cod...
1113
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1114
  	case SOCK_WAKE_WAITD:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1115
  		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
1117
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1118
  	case SOCK_WAKE_SPACE:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1119
  		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1120
1121
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1122
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1123
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1124
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1126
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1127
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
  	}
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1129

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1132
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133

721db93a5   Pavel Emelyanov   net: Export __soc...
1134
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1135
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1139
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1140
1141
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1142
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
  	 */
  	if (family < 0 || family >= NPROTO)
  		return -EAFNOSUPPORT;
  	if (type < 0 || type >= SOCK_MAX)
  		return -EINVAL;
  
  	/* Compatibility.
  
  	   This uglymoron is moved from INET layer to here to avoid
  	   deadlock in module load.
  	 */
  	if (family == PF_INET && type == SOCK_PACKET) {
f3c986908   liping.zhang   net: socket: use ...
1155
1156
1157
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1158
1159
1160
1161
1162
1163
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1164

55737fda0   Stephen Hemminger   [NET]: socket fam...
1165
1166
1167
1168
1169
1170
1171
  	/*
  	 *	Allocate the socket and allow the family to set things up. if
  	 *	the protocol is 0, the family is instructed to select an appropriate
  	 *	default.
  	 */
  	sock = sock_alloc();
  	if (!sock) {
e87cc4728   Joe Perches   net: Convert net_...
1172
1173
  		net_warn_ratelimited("socket: no more sockets
  ");
55737fda0   Stephen Hemminger   [NET]: socket fam...
1174
1175
1176
1177
1178
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1179
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1180
1181
1182
  	/* Attempt to load a protocol module if the find failed.
  	 *
  	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
1184
1185
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
190683a9d   Eric Dumazet   net: net_families...
1186
  	if (rcu_access_pointer(net_families[family]) == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1187
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1189
1190
1191
1192
1193
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1194
1195
1196
1197
1198
  
  	/*
  	 * We will call the ->create function, that possibly is in a loadable
  	 * module, so we have to bump that loadable module refcnt first.
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1199
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1201
1202
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1203
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1204
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1205
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1206

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1207
1208
1209
1210
  	/*
  	 * Now to bump the refcnt of the [loadable] module that owns this
  	 * socket at sock_release time we decrement its refcnt.
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1211
1212
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
1214
1215
1216
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1217
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1218
1219
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1220
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1221
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1222

55737fda0   Stephen Hemminger   [NET]: socket fam...
1223
1224
1225
1226
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1227
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1228
1229
1230
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1232
1233
1234
1235
1236
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
  }
721db93a5   Pavel Emelyanov   net: Export __soc...
1238
  EXPORT_SYMBOL(__sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1239
1240
1241
  
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1242
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1244
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245

eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1246
  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1247
  {
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1248
  	return __sock_create(net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1250
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251

9d6a15c3f   Dominik Brodowski   net: socket: add ...
1252
  int __sys_socket(int family, int type, int protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253
1254
1255
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1256
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1257
1258
1259
1260
1261
  	/* Check the SOCK_* constants for consistency.  */
  	BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC);
  	BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK);
  	BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK);
  	BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK);
a677a039b   Ulrich Drepper   flag parameters: ...
1262
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1263
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1264
1265
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266

aaca0bdca   Ulrich Drepper   flag parameters: ...
1267
1268
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1269
1270
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
8e1611e23   Al Viro   make sock_alloc_f...
1271
  		return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1272

8e1611e23   Al Viro   make sock_alloc_f...
1273
  	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
  }
9d6a15c3f   Dominik Brodowski   net: socket: add ...
1275
1276
1277
1278
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
  {
  	return __sys_socket(family, type, protocol);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
1280
1281
  /*
   *	Create a pair of connected sockets.
   */
6debc8d83   Dominik Brodowski   net: socket: add ...
1282
  int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
1284
1285
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1286
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1287
1288
1289
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1290
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1291
1292
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293

aaca0bdca   Ulrich Drepper   flag parameters: ...
1294
1295
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
  	/*
016a266bd   Al Viro   socketpair(): all...
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
  	 * reserve descriptors and make sure we won't fail
  	 * to return them to userland.
  	 */
  	fd1 = get_unused_fd_flags(flags);
  	if (unlikely(fd1 < 0))
  		return fd1;
  
  	fd2 = get_unused_fd_flags(flags);
  	if (unlikely(fd2 < 0)) {
  		put_unused_fd(fd1);
  		return fd2;
  	}
  
  	err = put_user(fd1, &usockvec[0]);
  	if (err)
  		goto out;
  
  	err = put_user(fd2, &usockvec[1]);
  	if (err)
  		goto out;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1319
1320
1321
1322
1323
  	 * Obtain the first socket and check if the underlying protocol
  	 * supports the socketpair call.
  	 */
  
  	err = sock_create(family, type, protocol, &sock1);
016a266bd   Al Viro   socketpair(): all...
1324
  	if (unlikely(err < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1325
1326
1327
  		goto out;
  
  	err = sock_create(family, type, protocol, &sock2);
016a266bd   Al Viro   socketpair(): all...
1328
1329
1330
  	if (unlikely(err < 0)) {
  		sock_release(sock1);
  		goto out;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1331
  	}
d73aa2867   Yann Droneaud   net: handle error...
1332

d47cd9450   David Herrmann   net: hook socketp...
1333
1334
1335
1336
1337
1338
  	err = security_socket_socketpair(sock1, sock2);
  	if (unlikely(err)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
  	}
016a266bd   Al Viro   socketpair(): all...
1339
1340
1341
1342
1343
  	err = sock1->ops->socketpair(sock1, sock2);
  	if (unlikely(err < 0)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
284076305   Al Viro   take descriptor h...
1344
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1345
  	newfile1 = sock_alloc_file(sock1, flags, NULL);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1346
  	if (IS_ERR(newfile1)) {
284076305   Al Viro   take descriptor h...
1347
  		err = PTR_ERR(newfile1);
016a266bd   Al Viro   socketpair(): all...
1348
1349
  		sock_release(sock2);
  		goto out;
284076305   Al Viro   take descriptor h...
1350
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1351
  	newfile2 = sock_alloc_file(sock2, flags, NULL);
284076305   Al Viro   take descriptor h...
1352
1353
  	if (IS_ERR(newfile2)) {
  		err = PTR_ERR(newfile2);
016a266bd   Al Viro   socketpair(): all...
1354
1355
  		fput(newfile1);
  		goto out;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1356
  	}
157cf649a   Al Viro   sanitize audit_fd...
1357
  	audit_fd_pair(fd1, fd2);
d73aa2867   Yann Droneaud   net: handle error...
1358

db3495099   Al Viro   [PATCH] AUDIT_FD_...
1359
1360
  	fd_install(fd1, newfile1);
  	fd_install(fd2, newfile2);
d73aa2867   Yann Droneaud   net: handle error...
1361
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362

016a266bd   Al Viro   socketpair(): all...
1363
  out:
d73aa2867   Yann Droneaud   net: handle error...
1364
  	put_unused_fd(fd2);
d73aa2867   Yann Droneaud   net: handle error...
1365
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1366
1367
  	return err;
  }
6debc8d83   Dominik Brodowski   net: socket: add ...
1368
1369
1370
1371
1372
  SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
  		int __user *, usockvec)
  {
  	return __sys_socketpair(family, type, protocol, usockvec);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1373
1374
1375
1376
1377
1378
1379
  /*
   *	Bind a name to a socket. Nothing much to do here since it's
   *	the protocol's responsibility to handle the local address.
   *
   *	We move the socket address to kernel space before we call
   *	the protocol layer (having also checked the address is ok).
   */
a87d35d87   Dominik Brodowski   net: socket: add ...
1380
  int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381
1382
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1383
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1384
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1385

89bddce58   Stephen Hemminger   [NET] socket: cod...
1386
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1387
  	if (sock) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1388
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1389
1390
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1391
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1392
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1393
1394
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1395
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1396
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1398
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1399
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400
1401
  	return err;
  }
a87d35d87   Dominik Brodowski   net: socket: add ...
1402
1403
1404
1405
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
  {
  	return __sys_bind(fd, umyaddr, addrlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1406
1407
1408
1409
1410
  /*
   *	Perform a listen. Basically, we allow the protocol to do anything
   *	necessary for a listen, and if that works, we mark the socket as
   *	ready for listening.
   */
25e290eed   Dominik Brodowski   net: socket: add ...
1411
  int __sys_listen(int fd, int backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412
1413
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1414
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1415
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1416
1417
1418
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1419
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1420
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1421
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
1423
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1424
1425
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1426

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1427
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
1429
1430
  	}
  	return err;
  }
25e290eed   Dominik Brodowski   net: socket: add ...
1431
1432
1433
1434
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  {
  	return __sys_listen(fd, backlog);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
1437
1438
1439
1440
1441
1442
1443
  /*
   *	For accept, we attempt to create a new socket, set up the link
   *	with the client, wake up the client, then return the new
   *	connected fd. We collect the address of the connector in kernel
   *	space and move it to user at the very end. This is unclean because
   *	we open the socket then return an error.
   *
   *	1003.1g adds the ability to recvmsg() to query connection pending
   *	status to recvmsg. We need to add that support in a way thats
b903036aa   Geert Uytterhoeven   net: Spelling s/s...
1444
   *	clean when we restructure accept also.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1445
   */
4541e8056   Dominik Brodowski   net: socket: add ...
1446
1447
  int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
  		  int __user *upeer_addrlen, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
1449
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1450
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1451
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1452
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1453

77d272005   Ulrich Drepper   flag parameters: ...
1454
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1455
1456
1457
1458
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1459
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
1461
1462
1463
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1464
1465
  	newsock = sock_alloc();
  	if (!newsock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
1467
1468
1469
  		goto out_put;
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
1471
1472
1473
1474
  	/*
  	 * We don't need try_module_get here, as the listening socket (sock)
  	 * has the protocol module (sock->ops->owner) held.
  	 */
  	__module_get(newsock->ops->owner);
284076305   Al Viro   take descriptor h...
1475
  	newfd = get_unused_fd_flags(flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1476
1477
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1478
1479
  		sock_release(newsock);
  		goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1480
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1481
  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1482
  	if (IS_ERR(newfile)) {
284076305   Al Viro   take descriptor h...
1483
1484
  		err = PTR_ERR(newfile);
  		put_unused_fd(newfd);
284076305   Al Viro   take descriptor h...
1485
1486
  		goto out_put;
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
1487

a79af59ef   Frank Filz   [NET]: Fix module...
1488
1489
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1490
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1491

cdfbabfb2   David Howells   net: Work around ...
1492
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags, false);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1493
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1494
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495
1496
  
  	if (upeer_sockaddr) {
9b2c45d47   Denys Vlasenko   net: make getname...
1497
1498
1499
  		len = newsock->ops->getname(newsock,
  					(struct sockaddr *)&address, 2);
  		if (len < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1501
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502
  		}
43db362d3   Maciej Żenczykowski   net: get rid of s...
1503
  		err = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1504
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1506
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
1508
1509
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1510
1511
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1512

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1514
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1517
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1518
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1519
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520
1521
  	goto out_put;
  }
4541e8056   Dominik Brodowski   net: socket: add ...
1522
1523
1524
1525
1526
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
  {
  	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1527
1528
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1529
  {
4541e8056   Dominik Brodowski   net: socket: add ...
1530
  	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1531
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
  /*
   *	Attempt to connect to a socket with the server address.  The address
   *	is in user space so we verify it is OK and move it to kernel space.
   *
   *	For 1003.1g we need to add clean support for a bind to AF_UNSPEC to
   *	break bindings
   *
   *	NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and
   *	other SEQPACKET protocols that take time to connect() as it doesn't
   *	include the -EINPROGRESS status for such sockets.
   */
1387c2c2f   Dominik Brodowski   net: socket: add ...
1543
  int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
1545
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1546
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1547
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1548

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1549
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
1551
  	if (!sock)
  		goto out;
43db362d3   Maciej Żenczykowski   net: get rid of s...
1552
  	err = move_addr_to_kernel(uservaddr, addrlen, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1553
1554
  	if (err < 0)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1555
  	err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1556
  	    security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1557
1558
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1559
  	err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1560
1561
  				 sock->file->f_flags);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1562
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1563
1564
1565
  out:
  	return err;
  }
1387c2c2f   Dominik Brodowski   net: socket: add ...
1566
1567
1568
1569
1570
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
  {
  	return __sys_connect(fd, uservaddr, addrlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
1572
1573
1574
  /*
   *	Get the local address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
8882a107b   Dominik Brodowski   net: socket: add ...
1575
1576
  int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
1578
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1579
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1580
  	int err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1581

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1582
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
1584
1585
1586
1587
1588
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1589
1590
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1592
1593
          /* "err" is actually length in this case */
  	err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594
1595
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1596
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1597
1598
1599
  out:
  	return err;
  }
8882a107b   Dominik Brodowski   net: socket: add ...
1600
1601
1602
1603
1604
  SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
  {
  	return __sys_getsockname(fd, usockaddr, usockaddr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1605
1606
1607
1608
  /*
   *	Get the remote address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
b21c8f838   Dominik Brodowski   net: socket: add ...
1609
1610
  int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
1612
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1613
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1614
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615

89bddce58   Stephen Hemminger   [NET] socket: cod...
1616
1617
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1618
1619
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1620
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
1622
  			return err;
  		}
9b2c45d47   Denys Vlasenko   net: make getname...
1623
1624
1625
1626
  		err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
  		if (err >= 0)
  			/* "err" is actually length in this case */
  			err = move_addr_to_user(&address, err, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1627
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1628
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1629
1630
1631
  	}
  	return err;
  }
b21c8f838   Dominik Brodowski   net: socket: add ...
1632
1633
1634
1635
1636
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
  {
  	return __sys_getpeername(fd, usockaddr, usockaddr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637
1638
1639
1640
1641
  /*
   *	Send a datagram to a given address. We move the address into kernel
   *	space and check the user space data area is readable before invoking
   *	the protocol.
   */
211b634b7   Dominik Brodowski   net: socket: add ...
1642
1643
  int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
  		 struct sockaddr __user *addr,  int addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1644
1645
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1646
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
1648
1649
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1650
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1651

602bd0e90   Al Viro   net: switch sendt...
1652
1653
1654
  	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1655
1656
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1657
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1658

89bddce58   Stephen Hemminger   [NET] socket: cod...
1659
  	msg.msg_name = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1660
1661
1662
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1663
  	if (addr) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1664
  		err = move_addr_to_kernel(addr, addr_len, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665
1666
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1667
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1668
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1669
1670
1671
1672
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
d8725c86a   Al Viro   get rid of the si...
1673
  	err = sock_sendmsg(sock, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674

89bddce58   Stephen Hemminger   [NET] socket: cod...
1675
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1676
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1677
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
1679
  	return err;
  }
211b634b7   Dominik Brodowski   net: socket: add ...
1680
1681
1682
1683
1684
1685
  SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
  		unsigned int, flags, struct sockaddr __user *, addr,
  		int, addr_len)
  {
  	return __sys_sendto(fd, buff, len, flags, addr, addr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1686
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1687
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1688
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1689
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1690
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
  {
211b634b7   Dominik Brodowski   net: socket: add ...
1692
  	return __sys_sendto(fd, buff, len, flags, NULL, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1693
1694
1695
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1696
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697
1698
1699
   *	sender. We verify the buffers are writable and if needed move the
   *	sender address from kernel to user space.
   */
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1700
1701
  int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
  		   struct sockaddr __user *addr, int __user *addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702
1703
1704
1705
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1706
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1707
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1708
  	int fput_needed;
602bd0e90   Al Viro   net: switch sendt...
1709
1710
1711
  	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1712
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1714
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715

89bddce58   Stephen Hemminger   [NET] socket: cod...
1716
1717
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1718
1719
1720
1721
  	/* Save some cycles and don't copy the address if not needed */
  	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg.msg_namelen = 0;
130ed5d10   tadeusz.struk@intel.com   net: fix uninitia...
1722
  	msg.msg_iocb = NULL;
9f138fa60   Alexander Potapenko   net: initialize m...
1723
  	msg.msg_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1724
1725
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1726
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1727

89bddce58   Stephen Hemminger   [NET] socket: cod...
1728
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1729
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1730
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1731
1732
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1734
1735
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1736
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
1738
  	return err;
  }
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1739
1740
1741
1742
1743
1744
  SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags, struct sockaddr __user *, addr,
  		int __user *, addr_len)
  {
  	return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1745
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1746
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1747
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1748
1749
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1750
  {
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1751
  	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1752
1753
1754
1755
1756
1757
  }
  
  /*
   *	Set a socket option. Because we don't know the option lengths we have
   *	to pass the user mode parameter for the protocols to sort out.
   */
cc36dca0d   Dominik Brodowski   net: socket: add ...
1758
1759
  static int __sys_setsockopt(int fd, int level, int optname,
  			    char __user *optval, int optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1760
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1761
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1762
1763
1764
1765
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1766
1767
1768
1769
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
  		err = security_socket_setsockopt(sock, level, optname);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1770
1771
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1772
1773
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1774
1775
1776
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1778
1779
1780
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1781
1782
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
1785
  	}
  	return err;
  }
cc36dca0d   Dominik Brodowski   net: socket: add ...
1786
1787
1788
1789
1790
  SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int, optlen)
  {
  	return __sys_setsockopt(fd, level, optname, optval, optlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791
1792
1793
1794
  /*
   *	Get a socket option. Because we don't know the option lengths we have
   *	to pass a user mode parameter for the protocols to sort out.
   */
13a2d70e2   Dominik Brodowski   net: socket: add ...
1795
1796
  static int __sys_getsockopt(int fd, int level, int optname,
  			    char __user *optval, int __user *optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1797
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1798
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1800
1801
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1802
1803
1804
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1805
1806
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1807
1808
1809
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1811
1812
1813
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1814
1815
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
1817
1818
  	}
  	return err;
  }
13a2d70e2   Dominik Brodowski   net: socket: add ...
1819
1820
1821
1822
1823
  SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int __user *, optlen)
  {
  	return __sys_getsockopt(fd, level, optname, optval, optlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1824
1825
1826
  /*
   *	Shutdown a socket.
   */
005a1aeac   Dominik Brodowski   net: socket: add ...
1827
  int __sys_shutdown(int fd, int how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1828
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1829
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1830
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1831
1832
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1833
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1834
1835
1836
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1837
1838
1839
  	}
  	return err;
  }
005a1aeac   Dominik Brodowski   net: socket: add ...
1840
1841
1842
1843
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
  {
  	return __sys_shutdown(fd, how);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1844
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
1846
1847
1848
1849
   * fields which are the same type (int / unsigned) on our platforms.
   */
  #define COMPAT_MSG(msg, member)	((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
  #define COMPAT_NAMELEN(msg)	COMPAT_MSG(msg, msg_namelen)
  #define COMPAT_FLAGS(msg)	COMPAT_MSG(msg, msg_flags)
c71d8ebe7   Tetsuo Handa   net: Fix security...
1850
1851
1852
1853
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
da1842849   Al Viro   net: switch impor...
1854
1855
1856
1857
  static int copy_msghdr_from_user(struct msghdr *kmsg,
  				 struct user_msghdr __user *umsg,
  				 struct sockaddr __user **save_addr,
  				 struct iovec **iov)
1661bf364   Dan Carpenter   net: heap overflo...
1858
  {
ffb07550c   Al Viro   copy_msghdr_from_...
1859
  	struct user_msghdr msg;
08adb7dab   Al Viro   fold verify_iovec...
1860
  	ssize_t err;
ffb07550c   Al Viro   copy_msghdr_from_...
1861
  	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
1661bf364   Dan Carpenter   net: heap overflo...
1862
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
1863

864d96642   Paolo Abeni   net/socket: fix t...
1864
  	kmsg->msg_control = (void __force *)msg.msg_control;
ffb07550c   Al Viro   copy_msghdr_from_...
1865
1866
1867
1868
1869
  	kmsg->msg_controllen = msg.msg_controllen;
  	kmsg->msg_flags = msg.msg_flags;
  
  	kmsg->msg_namelen = msg.msg_namelen;
  	if (!msg.msg_name)
6a2a2b3ae   Ani Sinha   net:socket: set m...
1870
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
1871
1872
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
1873
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
1874
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
1875
1876
  
  	if (save_addr)
ffb07550c   Al Viro   copy_msghdr_from_...
1877
  		*save_addr = msg.msg_name;
08adb7dab   Al Viro   fold verify_iovec...
1878

ffb07550c   Al Viro   copy_msghdr_from_...
1879
  	if (msg.msg_name && kmsg->msg_namelen) {
08adb7dab   Al Viro   fold verify_iovec...
1880
  		if (!save_addr) {
864d96642   Paolo Abeni   net/socket: fix t...
1881
1882
  			err = move_addr_to_kernel(msg.msg_name,
  						  kmsg->msg_namelen,
08adb7dab   Al Viro   fold verify_iovec...
1883
1884
1885
1886
1887
1888
1889
1890
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
ffb07550c   Al Viro   copy_msghdr_from_...
1891
  	if (msg.msg_iovlen > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
1892
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
1893
  	kmsg->msg_iocb = NULL;
ffb07550c   Al Viro   copy_msghdr_from_...
1894
1895
  	return import_iovec(save_addr ? READ : WRITE,
  			    msg.msg_iov, msg.msg_iovlen,
da1842849   Al Viro   net: switch impor...
1896
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
1661bf364   Dan Carpenter   net: heap overflo...
1897
  }
666547ff5   Al Viro   separate kernel- ...
1898
  static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
1899
  			 struct msghdr *msg_sys, unsigned int flags,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1900
1901
  			 struct used_address *used_address,
  			 unsigned int allowed_msghdr_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1902
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1903
1904
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1905
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1906
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
b9d717a7b   Alex Williamson   [NET]: Make sure ...
1907
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
846cc1231   Amit Kushwaha   net: socket: pref...
1908
  				__aligned(sizeof(__kernel_size_t));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1909
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1910
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
1911
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
1912
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1913

08adb7dab   Al Viro   fold verify_iovec...
1914
  	msg_sys->msg_name = &address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915

084493200   Al Viro   {compat_,}verify_...
1916
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
1917
  		err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
084493200   Al Viro   {compat_,}verify_...
1918
  	else
08adb7dab   Al Viro   fold verify_iovec...
1919
  		err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1920
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
1921
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
1923
  
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1924
  	if (msg_sys->msg_controllen > INT_MAX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1925
  		goto out_freeiov;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1926
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1927
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1928
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1929
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
1930
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1931
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1932
1933
  		if (err)
  			goto out_freeiov;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1934
1935
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1936
  	} else if (ctl_len) {
ac4340fc3   David S. Miller   net: Assert at bu...
1937
1938
  		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
  			     CMSG_ALIGN(sizeof(struct cmsghdr)));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1939
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1940
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1941
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1942
1943
1944
1945
  				goto out_freeiov;
  		}
  		err = -EFAULT;
  		/*
228e548e6   Anton Blanchard   net: Add sendmmsg...
1946
  		 * Careful! Before this, msg_sys->msg_control contains a user pointer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
1948
1949
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
1950
  		if (copy_from_user(ctl_buf,
228e548e6   Anton Blanchard   net: Add sendmmsg...
1951
  				   (void __user __force *)msg_sys->msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1952
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1953
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1954
  		msg_sys->msg_control = ctl_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1955
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
1956
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
1958
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1959
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
1960
1961
1962
1963
1964
1965
  	/*
  	 * If this is sendmmsg() and current destination address is same as
  	 * previously succeeded address, omit asking LSM's decision.
  	 * used_address->name_len is initialized to UINT_MAX so that the first
  	 * destination address never matches.
  	 */
bc909d9dd   Mathieu Desnoyers   sendmmsg/sendmsg:...
1966
1967
1968
  	if (used_address && msg_sys->msg_name &&
  	    used_address->name_len == msg_sys->msg_namelen &&
  	    !memcmp(&used_address->name, msg_sys->msg_name,
c71d8ebe7   Tetsuo Handa   net: Fix security...
1969
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
1970
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1971
1972
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
1973
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1974
1975
1976
1977
1978
1979
  	/*
  	 * If this is sendmmsg() and sending to current destination address was
  	 * successful, remember it.
  	 */
  	if (used_address && err >= 0) {
  		used_address->name_len = msg_sys->msg_namelen;
bc909d9dd   Mathieu Desnoyers   sendmmsg/sendmsg:...
1980
1981
1982
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1983
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1984
1985
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1986
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1987
1988
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  out_freeiov:
da1842849   Al Viro   net: switch impor...
1989
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1990
1991
1992
1993
1994
1995
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
e1834a329   Dominik Brodowski   net: socket: move...
1996
1997
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1998
1999
2000
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2001
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2002
2003
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2004
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2005
2006
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2007
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2008

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2009
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2010
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2011
2012
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2013
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2014
  {
e1834a329   Dominik Brodowski   net: socket: move...
2015
  	return __sys_sendmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2016
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
2017
2018
2019
2020
2021
  /*
   *	Linux sendmmsg interface
   */
  
  int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
e1834a329   Dominik Brodowski   net: socket: move...
2022
  		   unsigned int flags, bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2023
2024
2025
2026
2027
2028
  {
  	int fput_needed, err, datagrams;
  	struct socket *sock;
  	struct mmsghdr __user *entry;
  	struct compat_mmsghdr __user *compat_entry;
  	struct msghdr msg_sys;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2029
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2030
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2031

e1834a329   Dominik Brodowski   net: socket: move...
2032
2033
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
98382f419   Anton Blanchard   net: Cap number o...
2034
2035
  	if (vlen > UIO_MAXIOV)
  		vlen = UIO_MAXIOV;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2036
2037
2038
2039
2040
2041
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2042
  	used_address.name_len = UINT_MAX;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2043
2044
  	entry = mmsg;
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2045
  	err = 0;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2046
  	flags |= MSG_BATCH;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2047
2048
  
  	while (datagrams < vlen) {
f092276d8   Tom Herbert   net: Add MSG_BATC...
2049
2050
  		if (datagrams == vlen - 1)
  			flags = oflags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2051
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2052
  			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2053
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2054
2055
2056
2057
2058
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2059
  			err = ___sys_sendmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2060
  					     (struct user_msghdr __user *)entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2061
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2062
2063
2064
2065
2066
2067
2068
2069
2070
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
  
  		if (err)
  			break;
  		++datagrams;
3023898b7   Soheil Hassas Yeganeh   sock: fix sendmms...
2071
2072
  		if (msg_data_left(&msg_sys))
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2073
  		cond_resched();
228e548e6   Anton Blanchard   net: Add sendmmsg...
2074
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2075
  	fput_light(sock->file, fput_needed);
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2076
2077
  	/* We only return an error if no datagrams were able to be sent */
  	if (datagrams != 0)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2078
  		return datagrams;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2079
2080
2081
2082
2083
2084
  	return err;
  }
  
  SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2085
  	return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2086
  }
666547ff5   Al Viro   separate kernel- ...
2087
  static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
2088
  			 struct msghdr *msg_sys, unsigned int flags, int nosec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2089
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2090
2091
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2092
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2093
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2094
  	unsigned long cmsg_ptr;
2da62906b   Al Viro   [net] drop 'size'...
2095
  	int len;
08adb7dab   Al Viro   fold verify_iovec...
2096
  	ssize_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2097
2098
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
2099
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2100
2101
2102
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
08adb7dab   Al Viro   fold verify_iovec...
2103
  	int __user *uaddr_len = COMPAT_NAMELEN(msg);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2104

08adb7dab   Al Viro   fold verify_iovec...
2105
  	msg_sys->msg_name = &addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2106

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2107
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
2108
  		err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov);
f3d334260   Hannes Frederic Sowa   net: rework recvm...
2109
  	else
08adb7dab   Al Viro   fold verify_iovec...
2110
  		err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2111
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
2112
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2113

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2114
2115
  	cmsg_ptr = (unsigned long)msg_sys->msg_control;
  	msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2116

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2117
2118
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2119
2120
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
2121
  	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2122
2123
2124
2125
2126
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
2127
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2128
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2129
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2130
2131
2132
  		if (err < 0)
  			goto out_freeiov;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2133
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
2134
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2135
2136
2137
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2138
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2139
2140
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2141
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2142
2143
2144
2145
2146
2147
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
da1842849   Al Viro   net: switch impor...
2148
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2149
2150
2151
2152
2153
2154
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
e1834a329   Dominik Brodowski   net: socket: move...
2155
2156
  long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2157
2158
2159
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2160
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2161
2162
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2163
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2164
2165
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2166
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2167

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2168
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2169
2170
2171
  out:
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2172
  SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2173
2174
  		unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2175
  	return __sys_recvmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2176
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
  /*
   *     Linux recvmmsg interface
   */
  
  int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
  		   unsigned int flags, struct timespec *timeout)
  {
  	int fput_needed, err, datagrams;
  	struct socket *sock;
  	struct mmsghdr __user *entry;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2187
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2188
  	struct msghdr msg_sys;
766b9f928   Deepa Dinamani   fs: poll/select/r...
2189
2190
  	struct timespec64 end_time;
  	struct timespec64 timeout64;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
  
  	if (timeout &&
  	    poll_select_set_timeout(&end_time, timeout->tv_sec,
  				    timeout->tv_nsec))
  		return -EINVAL;
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
7797dc414   Soheil Hassas Yeganeh   socket: skip chec...
2202
2203
2204
2205
2206
2207
  	if (likely(!(flags & MSG_ERRQUEUE))) {
  		err = sock_error(sock->sk);
  		if (err) {
  			datagrams = err;
  			goto out_put;
  		}
e623a9e9d   Maxime Jayat   net: socket: fix ...
2208
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2209
2210
  
  	entry = mmsg;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2211
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2212
2213
2214
2215
2216
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2217
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2218
  			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2219
2220
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2221
2222
2223
2224
2225
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2226
  			err = ___sys_recvmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2227
  					     (struct user_msghdr __user *)entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2228
2229
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2230
2231
2232
2233
2234
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2235
2236
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2237
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2238
2239
2240
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2241
  		if (timeout) {
766b9f928   Deepa Dinamani   fs: poll/select/r...
2242
2243
2244
  			ktime_get_ts64(&timeout64);
  			*timeout = timespec64_to_timespec(
  					timespec64_sub(end_time, timeout64));
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
  			if (timeout->tv_sec < 0) {
  				timeout->tv_sec = timeout->tv_nsec = 0;
  				break;
  			}
  
  			/* Timeout, return less than vlen datagrams */
  			if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
  				break;
  		}
  
  		/* Out of band data, return right away */
  		if (msg_sys.msg_flags & MSG_OOB)
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2258
  		cond_resched();
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2259
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2260
  	if (err == 0)
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2261
2262
2263
2264
2265
2266
  		goto out_put;
  
  	if (datagrams == 0) {
  		datagrams = err;
  		goto out_put;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2267

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2268
2269
2270
2271
2272
  	/*
  	 * We may return less entries than requested (vlen) if the
  	 * sock is non block and there aren't enough datagrams...
  	 */
  	if (err != -EAGAIN) {
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2273
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2274
2275
2276
2277
  		 * ... or  if recvmsg returns an error after we
  		 * received some datagrams, where we record the
  		 * error to return on the next call or if the
  		 * app asks about it using getsockopt(SO_ERROR).
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2278
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2279
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2280
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2281
2282
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2283

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2284
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2285
  }
1255e2690   Dominik Brodowski   net: socket: add ...
2286
2287
2288
  static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
  			   unsigned int vlen, unsigned int flags,
  			   struct timespec __user *timeout)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2289
2290
2291
  {
  	int datagrams;
  	struct timespec timeout_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2292
2293
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
  	if (!timeout)
  		return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
  
  	if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys)))
  		return -EFAULT;
  
  	datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
  
  	if (datagrams > 0 &&
  	    copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys)))
  		datagrams = -EFAULT;
  
  	return datagrams;
  }
1255e2690   Dominik Brodowski   net: socket: add ...
2308
2309
2310
2311
2312
2313
  SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags,
  		struct timespec __user *, timeout)
  {
  	return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout);
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2314
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2315
2316
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
228e548e6   Anton Blanchard   net: Add sendmmsg...
2317
  static const unsigned char nargs[21] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2318
2319
2320
  	AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
  	AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
  	AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
228e548e6   Anton Blanchard   net: Add sendmmsg...
2321
  	AL(4), AL(5), AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2322
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2323
2324
2325
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2326
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2327
2328
2329
   *
   *	Argument checking cleaned up. Saved 20% in size.
   *  This function doesn't need to set the kernel lock because
89bddce58   Stephen Hemminger   [NET] socket: cod...
2330
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2332
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2333
  {
2950fa9d3   Chen Gang   kernel: audit: be...
2334
  	unsigned long a[AUDITSC_ARGS];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2335
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2336
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2337
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2338

228e548e6   Anton Blanchard   net: Add sendmmsg...
2339
  	if (call < 1 || call > SYS_SENDMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2340
  		return -EINVAL;
c8e8cd579   Jeremy Cline   net: socket: fix ...
2341
  	call = array_index_nospec(call, SYS_SENDMMSG + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2342

47379052b   Arjan van de Ven   net: Add explicit...
2343
2344
2345
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2346
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2347
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2348
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2349

2950fa9d3   Chen Gang   kernel: audit: be...
2350
2351
2352
  	err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
  	if (err)
  		return err;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2353

89bddce58   Stephen Hemminger   [NET] socket: cod...
2354
2355
2356
2357
2358
  	a0 = a[0];
  	a1 = a[1];
  
  	switch (call) {
  	case SYS_SOCKET:
9d6a15c3f   Dominik Brodowski   net: socket: add ...
2359
  		err = __sys_socket(a0, a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2360
2361
  		break;
  	case SYS_BIND:
a87d35d87   Dominik Brodowski   net: socket: add ...
2362
  		err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2363
2364
  		break;
  	case SYS_CONNECT:
1387c2c2f   Dominik Brodowski   net: socket: add ...
2365
  		err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2366
2367
  		break;
  	case SYS_LISTEN:
25e290eed   Dominik Brodowski   net: socket: add ...
2368
  		err = __sys_listen(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2369
2370
  		break;
  	case SYS_ACCEPT:
4541e8056   Dominik Brodowski   net: socket: add ...
2371
2372
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2373
2374
2375
  		break;
  	case SYS_GETSOCKNAME:
  		err =
8882a107b   Dominik Brodowski   net: socket: add ...
2376
2377
  		    __sys_getsockname(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2378
2379
2380
  		break;
  	case SYS_GETPEERNAME:
  		err =
b21c8f838   Dominik Brodowski   net: socket: add ...
2381
2382
  		    __sys_getpeername(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2383
2384
  		break;
  	case SYS_SOCKETPAIR:
6debc8d83   Dominik Brodowski   net: socket: add ...
2385
  		err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2386
2387
  		break;
  	case SYS_SEND:
f3bf896b1   Dominik Brodowski   net: socket: repl...
2388
2389
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   NULL, 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2390
2391
  		break;
  	case SYS_SENDTO:
211b634b7   Dominik Brodowski   net: socket: add ...
2392
2393
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   (struct sockaddr __user *)a[4], a[5]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2394
2395
  		break;
  	case SYS_RECV:
d27e9afc6   Dominik Brodowski   net: socket: repl...
2396
2397
  		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				     NULL, NULL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2398
2399
  		break;
  	case SYS_RECVFROM:
7a09e1eb9   Dominik Brodowski   net: socket: add ...
2400
2401
2402
  		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				     (struct sockaddr __user *)a[4],
  				     (int __user *)a[5]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2403
2404
  		break;
  	case SYS_SHUTDOWN:
005a1aeac   Dominik Brodowski   net: socket: add ...
2405
  		err = __sys_shutdown(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2406
2407
  		break;
  	case SYS_SETSOCKOPT:
cc36dca0d   Dominik Brodowski   net: socket: add ...
2408
2409
  		err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
  				       a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2410
2411
2412
  		break;
  	case SYS_GETSOCKOPT:
  		err =
13a2d70e2   Dominik Brodowski   net: socket: add ...
2413
2414
  		    __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
  				     (int __user *)a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2415
2416
  		break;
  	case SYS_SENDMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2417
2418
  		err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2419
  		break;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2420
  	case SYS_SENDMMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2421
2422
  		err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
  				     a[3], true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2423
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2424
  	case SYS_RECVMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2425
2426
  		err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2427
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2428
  	case SYS_RECVMMSG:
1255e2690   Dominik Brodowski   net: socket: add ...
2429
2430
  		err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2],
  				      a[3], (struct timespec __user *)a[4]);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2431
  		break;
de11defeb   Ulrich Drepper   reintroduce accept4
2432
  	case SYS_ACCEPT4:
4541e8056   Dominik Brodowski   net: socket: add ...
2433
2434
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2435
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2436
2437
2438
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2439
2440
2441
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2442
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2443

55737fda0   Stephen Hemminger   [NET]: socket fam...
2444
2445
2446
2447
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2448
2449
   *	This function is called by a protocol handler that wants to
   *	advertise its address family, and have it linked into the
e793c0f70   Masanari Iida   net: treewide: Fi...
2450
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2451
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2452
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2453
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2454
2455
2456
2457
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2458
2459
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2460
2461
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2462
2463
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2464
2465
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2466
2467
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2468
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2469
2470
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2471
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2472
2473
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2476
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2477

55737fda0   Stephen Hemminger   [NET]: socket fam...
2478
2479
2480
2481
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2482
2483
   *	This function is called by a protocol handler that wants to
   *	remove its address family, and have it unlinked from the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2484
2485
2486
2487
2488
2489
   *	new socket creation.
   *
   *	If protocol handler is a module, then it can use module reference
   *	counts to protect against new references. If protocol handler is not
   *	a module then it needs to provide its own protection in
   *	the ops->create routine.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2490
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2491
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2492
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2493
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2494

55737fda0   Stephen Hemminger   [NET]: socket fam...
2495
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2496
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2497
2498
2499
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2500
2501
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2502
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2503
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2504

bf2ae2e4b   Xin Long   sock_diag: reques...
2505
2506
  bool sock_is_registered(int family)
  {
66b51b0a0   Jeremy Cline   net: sock_diag: F...
2507
  	return family < NPROTO && rcu_access_pointer(net_families[family]);
bf2ae2e4b   Xin Long   sock_diag: reques...
2508
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2509
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2510
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2511
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2512
2513
2514
2515
2516
2517
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2518

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2519
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2520
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521
2522
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2523
2524
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2525
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2526
2527
2528
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2529
2530
2531
2532
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
  		goto out_fs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2533
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2534
2535
2536
2537
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2538
2539
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2540
2541
2542
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2543
2544
2545
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2546
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2547

408eccce3   Daniel Borkmann   net: ptp: move PT...
2548
  	ptp_classifier_init();
c1f19b51d   Richard Cochran   net: support time...
2549

b3e19d924   Nick Piggin   fs: scale mntget/...
2550
2551
2552
2553
2554
2555
2556
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
  out_fs:
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2557
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2558
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2559
2560
2561
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
648845ab7   Tonghao Zhang   sock: Move the so...
2562
2563
2564
  	seq_printf(seq, "sockets: used %d
  ",
  		   sock_inuse_get(seq->private));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2565
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2566
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2567

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2568
  #ifdef CONFIG_COMPAT
6b96018b2   Arnd Bergmann   compat: move sock...
2569
  static int do_siocgstamp(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2570
  			 unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2571
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2572
2573
2574
2575
2576
  	mm_segment_t old_fs = get_fs();
  	struct timeval ktv;
  	int err;
  
  	set_fs(KERNEL_DS);
99f3c8966   Johannes Berg   Revert "socket: f...
2577
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
7a229387d   Arnd Bergmann   net: copy socket ...
2578
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2579
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2580
  		err = compat_put_timeval(&ktv, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2581

7a229387d   Arnd Bergmann   net: copy socket ...
2582
2583
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2584
  static int do_siocgstampns(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2585
  			   unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2586
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2587
2588
2589
2590
2591
  	mm_segment_t old_fs = get_fs();
  	struct timespec kts;
  	int err;
  
  	set_fs(KERNEL_DS);
99f3c8966   Johannes Berg   Revert "socket: f...
2592
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
7a229387d   Arnd Bergmann   net: copy socket ...
2593
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2594
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2595
  		err = compat_put_timespec(&kts, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2596

7a229387d   Arnd Bergmann   net: copy socket ...
2597
2598
  	return err;
  }
36fd633ec   Al Viro   net: separate SIO...
2599
  static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2600
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2601
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2602
  	struct ifconf ifc;
7a229387d   Arnd Bergmann   net: copy socket ...
2603
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2604
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2605
  		return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
2606
2607
  	ifc.ifc_len = ifc32.ifc_len;
  	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
7a229387d   Arnd Bergmann   net: copy socket ...
2608

36fd633ec   Al Viro   net: separate SIO...
2609
2610
2611
  	rtnl_lock();
  	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
  	rtnl_unlock();
7a229387d   Arnd Bergmann   net: copy socket ...
2612
2613
  	if (err)
  		return err;
36fd633ec   Al Viro   net: separate SIO...
2614
  	ifc32.ifc_len = ifc.ifc_len;
6b96018b2   Arnd Bergmann   compat: move sock...
2615
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2616
2617
2618
2619
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2620
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2621
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2622
2623
  	struct compat_ethtool_rxnfc __user *compat_rxnfc;
  	bool convert_in = false, convert_out = false;
44c02a2c3   Al Viro   dev_ioctl(): move...
2624
2625
2626
  	size_t buf_size = 0;
  	struct ethtool_rxnfc __user *rxnfc = NULL;
  	struct ifreq ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2627
2628
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2629
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2630
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2631

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2632
2633
  	if (get_user(data, &ifr32->ifr_ifru.ifru_data))
  		return -EFAULT;
7a229387d   Arnd Bergmann   net: copy socket ...
2634

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2635
2636
2637
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2638
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
  	/* Most ethtool structures are defined without padding.
  	 * Unfortunately struct ethtool_rxnfc is an exception.
  	 */
  	switch (ethcmd) {
  	default:
  		break;
  	case ETHTOOL_GRXCLSRLALL:
  		/* Buffer size is variable */
  		if (get_user(rule_cnt, &compat_rxnfc->rule_cnt))
  			return -EFAULT;
  		if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32))
  			return -ENOMEM;
  		buf_size += rule_cnt * sizeof(u32);
  		/* fall through */
  	case ETHTOOL_GRXRINGS:
  	case ETHTOOL_GRXCLSRLCNT:
  	case ETHTOOL_GRXCLSRULE:
55664f324   Ben Hutchings   ethtool: Allow dr...
2656
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2657
2658
2659
  		convert_out = true;
  		/* fall through */
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2660
2661
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
44c02a2c3   Al Viro   dev_ioctl(): move...
2662
  		rxnfc = compat_alloc_user_space(buf_size);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2663
2664
  		break;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2665
  	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2666
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2667
  	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
7a229387d   Arnd Bergmann   net: copy socket ...
2668

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2669
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2670
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2671
2672
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2673
2674
2675
2676
  		BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
  			     sizeof(compat_rxnfc->fs.m_ext) !=
  			     offsetof(struct ethtool_rxnfc, fs.m_ext) +
  			     sizeof(rxnfc->fs.m_ext));
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2677
2678
2679
2680
2681
2682
2683
  		BUILD_BUG_ON(
  			offsetof(struct compat_ethtool_rxnfc, fs.location) -
  			offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
  			offsetof(struct ethtool_rxnfc, fs.location) -
  			offsetof(struct ethtool_rxnfc, fs.ring_cookie));
  
  		if (copy_in_user(rxnfc, compat_rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
2684
2685
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2686
2687
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2688
  				 (void __user *)(&rxnfc->fs.location + 1) -
b6168562c   Wenwen Wang   net: socket: fix ...
2689
2690
2691
2692
2693
2694
2695
2696
  				 (void __user *)&rxnfc->fs.ring_cookie))
  			return -EFAULT;
  		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
  			if (put_user(rule_cnt, &rxnfc->rule_cnt))
  				return -EFAULT;
  		} else if (copy_in_user(&rxnfc->rule_cnt,
  					&compat_rxnfc->rule_cnt,
  					sizeof(rxnfc->rule_cnt)))
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2697
2698
  			return -EFAULT;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2699
  	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2700
2701
2702
2703
2704
  	if (ret)
  		return ret;
  
  	if (convert_out) {
  		if (copy_in_user(compat_rxnfc, rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
2705
2706
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2707
2708
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2709
2710
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
  		    copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
  				 sizeof(rxnfc->rule_cnt)))
  			return -EFAULT;
  
  		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
  			/* As an optimisation, we only copy the actual
  			 * number of rules that the underlying
  			 * function returned.  Since Mallory might
  			 * change the rule count in user memory, we
  			 * check that it is less than the rule count
  			 * originally given (as the user buffer size),
  			 * which has been range-checked.
  			 */
  			if (get_user(actual_rule_cnt, &rxnfc->rule_cnt))
  				return -EFAULT;
  			if (actual_rule_cnt < rule_cnt)
  				rule_cnt = actual_rule_cnt;
  			if (copy_in_user(&compat_rxnfc->rule_locs[0],
  					 &rxnfc->rule_locs[0],
  					 rule_cnt * sizeof(u32)))
  				return -EFAULT;
  		}
  	}
  
  	return 0;
7a229387d   Arnd Bergmann   net: copy socket ...
2736
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2737
2738
  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
  {
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2739
  	compat_uptr_t uptr32;
44c02a2c3   Al Viro   dev_ioctl(): move...
2740
2741
2742
  	struct ifreq ifr;
  	void __user *saved;
  	int err;
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2743

44c02a2c3   Al Viro   dev_ioctl(): move...
2744
  	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2745
2746
2747
2748
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2749
2750
  	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
  	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
7a229387d   Arnd Bergmann   net: copy socket ...
2751

44c02a2c3   Al Viro   dev_ioctl(): move...
2752
2753
2754
2755
2756
  	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
  	if (!err) {
  		ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
  		if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
  			err = -EFAULT;
ccbd6a5a4   Joe Perches   net: Remove unnec...
2757
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2758
  	return err;
7a229387d   Arnd Bergmann   net: copy socket ...
2759
  }
590d4693f   Ben Hutchings   net/compat: Merge...
2760
2761
  /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
  static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
6b96018b2   Arnd Bergmann   compat: move sock...
2762
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
2763
  {
44c02a2c3   Al Viro   dev_ioctl(): move...
2764
  	struct ifreq ifreq;
7a229387d   Arnd Bergmann   net: copy socket ...
2765
  	u32 data32;
44c02a2c3   Al Viro   dev_ioctl(): move...
2766
  	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2767
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2768
  	if (get_user(data32, &u_ifreq32->ifr_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2769
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2770
  	ifreq.ifr_data = compat_ptr(data32);
7a229387d   Arnd Bergmann   net: copy socket ...
2771

44c02a2c3   Al Viro   dev_ioctl(): move...
2772
  	return dev_ioctl(net, cmd, &ifreq, NULL);
7a229387d   Arnd Bergmann   net: copy socket ...
2773
  }
50021ba98   Johannes Berg   Revert "kill dev_...
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
  static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
  			      unsigned int cmd,
  			      struct compat_ifreq __user *uifr32)
  {
  	struct ifreq __user *uifr;
  	int err;
  
  	/* Handle the fact that while struct ifreq has the same *layout* on
  	 * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
  	 * which are handled elsewhere, it still has different *size* due to
  	 * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
  	 * resulting in struct ifreq being 32 and 40 bytes respectively).
  	 * As a result, if the struct happens to be at the end of a page and
  	 * the next page isn't readable/writable, we get a fault. To prevent
  	 * that, copy back and forth to the full size.
  	 */
  
  	uifr = compat_alloc_user_space(sizeof(*uifr));
  	if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
  		return -EFAULT;
  
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
  
  	if (!err) {
  		switch (cmd) {
  		case SIOCGIFFLAGS:
  		case SIOCGIFMETRIC:
  		case SIOCGIFMTU:
  		case SIOCGIFMEM:
  		case SIOCGIFHWADDR:
  		case SIOCGIFINDEX:
  		case SIOCGIFADDR:
  		case SIOCGIFBRDADDR:
  		case SIOCGIFDSTADDR:
  		case SIOCGIFNETMASK:
  		case SIOCGIFPFLAGS:
  		case SIOCGIFTXQLEN:
  		case SIOCGMIIPHY:
  		case SIOCGMIIREG:
e37c96c11   Johannes Berg   net: socket: fix ...
2813
  		case SIOCGIFNAME:
50021ba98   Johannes Berg   Revert "kill dev_...
2814
2815
2816
2817
2818
2819
2820
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
2821
2822
2823
2824
2825
  static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
  			struct compat_ifreq __user *uifr32)
  {
  	struct ifreq ifr;
  	struct compat_ifmap __user *uifmap32;
a2116ed22   Arnd Bergmann   net/compat: fix d...
2826
2827
2828
2829
  	int err;
  
  	uifmap32 = &uifr32->ifr_ifru.ifru_map;
  	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2830
2831
2832
2833
2834
2835
  	err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
  	err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
  	err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
  	err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
  	err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
  	err |= get_user(ifr.ifr_map.port, &uifmap32->port);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2836
2837
  	if (err)
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2838
  	err = dev_ioctl(net, cmd, &ifr, NULL);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2839
2840
2841
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2842
2843
2844
2845
2846
2847
  		err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
  		err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
  		err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
  		err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
  		err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
  		err |= put_user(ifr.ifr_map.port, &uifmap32->port);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2848
2849
2850
2851
2852
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2853
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2854
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
2855
2856
2857
  	struct sockaddr rt_dst;         /* target address               */
  	struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
  	struct sockaddr rt_genmask;     /* target network mask (IP)     */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2858
2859
2860
2861
2862
2863
2864
  	unsigned short	rt_flags;
  	short		rt_pad2;
  	u32		rt_pad3;
  	unsigned char	rt_tos;
  	unsigned char	rt_class;
  	short		rt_pad4;
  	short		rt_metric;      /* +1 for binary compatibility! */
7a229387d   Arnd Bergmann   net: copy socket ...
2865
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2866
2867
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
  	unsigned short  rt_irtt;        /* Initial RTT                  */
  };
  
  struct in6_rtmsg32 {
  	struct in6_addr		rtmsg_dst;
  	struct in6_addr		rtmsg_src;
  	struct in6_addr		rtmsg_gateway;
  	u32			rtmsg_type;
  	u16			rtmsg_dst_len;
  	u16			rtmsg_src_len;
  	u32			rtmsg_metric;
  	u32			rtmsg_info;
  	u32			rtmsg_flags;
  	s32			rtmsg_ifindex;
  };
6b96018b2   Arnd Bergmann   compat: move sock...
2883
2884
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2885
2886
2887
2888
2889
2890
2891
2892
  {
  	int ret;
  	void *r = NULL;
  	struct in6_rtmsg r6;
  	struct rtentry r4;
  	char devname[16];
  	u32 rtdev;
  	mm_segment_t old_fs = get_fs();
6b96018b2   Arnd Bergmann   compat: move sock...
2893
2894
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2895
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2896
  			3 * sizeof(struct in6_addr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2897
2898
2899
2900
2901
2902
2903
  		ret |= get_user(r6.rtmsg_type, &(ur6->rtmsg_type));
  		ret |= get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
  		ret |= get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
  		ret |= get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric));
  		ret |= get_user(r6.rtmsg_info, &(ur6->rtmsg_info));
  		ret |= get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags));
  		ret |= get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
7a229387d   Arnd Bergmann   net: copy socket ...
2904
2905
2906
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
2907
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2908
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2909
  					3 * sizeof(struct sockaddr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2910
2911
2912
2913
2914
2915
  		ret |= get_user(r4.rt_flags, &(ur4->rt_flags));
  		ret |= get_user(r4.rt_metric, &(ur4->rt_metric));
  		ret |= get_user(r4.rt_mtu, &(ur4->rt_mtu));
  		ret |= get_user(r4.rt_window, &(ur4->rt_window));
  		ret |= get_user(r4.rt_irtt, &(ur4->rt_irtt));
  		ret |= get_user(rtdev, &(ur4->rt_dev));
7a229387d   Arnd Bergmann   net: copy socket ...
2916
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2917
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
c3f52ae6a   stephen hemminger   socket: suppress ...
2918
2919
  			r4.rt_dev = (char __user __force *)devname;
  			devname[15] = 0;
7a229387d   Arnd Bergmann   net: copy socket ...
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2930
  	set_fs(KERNEL_DS);
99f3c8966   Johannes Berg   Revert "socket: f...
2931
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2932
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2933
2934
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
2935
2936
2937
2938
2939
  	return ret;
  }
  
  /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
   * for some operations; this forces use of the newer bridge-utils that
25985edce   Lucas De Marchi   Fix common misspe...
2940
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
2941
   */
6b96018b2   Arnd Bergmann   compat: move sock...
2942
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2943
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2944
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
2945

6b96018b2   Arnd Bergmann   compat: move sock...
2946
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
2947
2948
2949
2950
2951
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2952
2953
2954
2955
2956
2957
  static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
  			 unsigned int cmd, unsigned long arg)
  {
  	void __user *argp = compat_ptr(arg);
  	struct sock *sk = sock->sk;
  	struct net *net = sock_net(sk);
7a229387d   Arnd Bergmann   net: copy socket ...
2958

6b96018b2   Arnd Bergmann   compat: move sock...
2959
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
2960
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2961
2962
2963
2964
2965
  
  	switch (cmd) {
  	case SIOCSIFBR:
  	case SIOCGIFBR:
  		return old_bridge_ioctl(argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2966
  	case SIOCGIFCONF:
36fd633ec   Al Viro   net: separate SIO...
2967
  		return compat_dev_ifconf(net, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2968
2969
  	case SIOCETHTOOL:
  		return ethtool_ioctl(net, argp);
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2970
2971
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2972
2973
2974
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2975
2976
2977
2978
2979
2980
2981
  	case SIOCADDRT:
  	case SIOCDELRT:
  		return routing_ioctl(net, sock, cmd, argp);
  	case SIOCGSTAMP:
  		return do_siocgstamp(net, sock, cmd, argp);
  	case SIOCGSTAMPNS:
  		return do_siocgstampns(net, sock, cmd, argp);
590d4693f   Ben Hutchings   net/compat: Merge...
2982
2983
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2984
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
2985
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
2986
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
  
  	case FIOSETOWN:
  	case SIOCSPGRP:
  	case FIOGETOWN:
  	case SIOCGPGRP:
  	case SIOCBRADDBR:
  	case SIOCBRDELBR:
  	case SIOCGIFVLAN:
  	case SIOCSIFVLAN:
  	case SIOCADDDLCI:
  	case SIOCDELDLCI:
c62cce2ca   Andrey Vagin   net: add an ioctl...
2998
  	case SIOCGSKNS:
6b96018b2   Arnd Bergmann   compat: move sock...
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
  		return sock_ioctl(file, cmd, arg);
  
  	case SIOCGIFFLAGS:
  	case SIOCSIFFLAGS:
  	case SIOCGIFMETRIC:
  	case SIOCSIFMETRIC:
  	case SIOCGIFMTU:
  	case SIOCSIFMTU:
  	case SIOCGIFMEM:
  	case SIOCSIFMEM:
  	case SIOCGIFHWADDR:
  	case SIOCSIFHWADDR:
  	case SIOCADDMULTI:
  	case SIOCDELMULTI:
  	case SIOCGIFINDEX:
6b96018b2   Arnd Bergmann   compat: move sock...
3014
3015
3016
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
3017
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
  	case SIOCGIFBRDADDR:
  	case SIOCSIFBRDADDR:
  	case SIOCGIFDSTADDR:
  	case SIOCSIFDSTADDR:
  	case SIOCGIFNETMASK:
  	case SIOCSIFNETMASK:
  	case SIOCSIFPFLAGS:
  	case SIOCGIFPFLAGS:
  	case SIOCGIFTXQLEN:
  	case SIOCSIFTXQLEN:
  	case SIOCBRADDIF:
  	case SIOCBRDELIF:
e37c96c11   Johannes Berg   net: socket: fix ...
3030
  	case SIOCGIFNAME:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3031
3032
3033
3034
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
7aab1e6d9   Johannes Berg   net: socket: make...
3035
3036
3037
3038
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
50021ba98   Johannes Berg   Revert "kill dev_...
3039
  		return compat_ifreq_ioctl(net, sock, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3040
3041
3042
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
6b96018b2   Arnd Bergmann   compat: move sock...
3043
  	case SIOCATMARK:
99f3c8966   Johannes Berg   Revert "socket: f...
3044
  		return sock_do_ioctl(net, sock, cmd, arg);
9177efd39   Arnd Bergmann   net, compat_ioctl...
3045
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
3046
3047
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3048

95c961747   Eric Dumazet   net: cleanup unsi...
3049
  static long compat_sock_ioctl(struct file *file, unsigned int cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
3050
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3051
3052
3053
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
3054
3055
3056
3057
3058
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3059
3060
3061
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
3062
3063
3064
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
3065
3066
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3067
3068
3069
  	return ret;
  }
  #endif
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3070
3071
3072
3073
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3074
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3075
3076
3077
3078
3079
  
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3080
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
  
  int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
  {
  	struct sock *sk = sock->sk;
  	int err;
  
  	err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
  			       newsock);
  	if (err < 0)
  		goto done;
cdfbabfb2   David Howells   net: Work around ...
3091
  	err = sock->ops->accept(sock, *newsock, flags, true);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3092
3093
  	if (err < 0) {
  		sock_release(*newsock);
fa8705b00   Tony Battersby   [NET]: sanitize k...
3094
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3095
3096
3097
3098
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
3099
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3100
3101
3102
3103
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3104
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3105
3106
  
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
3107
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3108
3109
3110
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3111
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3112

9b2c45d47   Denys Vlasenko   net: make getname...
3113
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3114
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3115
  	return sock->ops->getname(sock, addr, 0);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3116
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3117
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3118

9b2c45d47   Denys Vlasenko   net: make getname...
3119
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3120
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3121
  	return sock->ops->getname(sock, addr, 1);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3122
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3123
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3124
3125
3126
3127
3128
  
  int kernel_getsockopt(struct socket *sock, int level, int optname,
  			char *optval, int *optlen)
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3129
3130
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3131
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3132
3133
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3134
3135
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3136
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3137
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3138
3139
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3140
3141
3142
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3143
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3144
3145
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
3146
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3147
3148
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3149
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3150
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3151
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3152
3153
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3154
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3155
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3156
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3157
3158
3159
3160
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3161
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3162
3163
3164
3165
3166
3167
3168
3169
3170
  
  int kernel_sendpage(struct socket *sock, struct page *page, int offset,
  		    size_t size, int flags)
  {
  	if (sock->ops->sendpage)
  		return sock->ops->sendpage(sock, page, offset, size, flags);
  
  	return sock_no_sendpage(sock, page, offset, size, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3171
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3172

306b13eb3   Tom Herbert   proto_ops: Add lo...
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
  int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
  			   size_t size, int flags)
  {
  	struct socket *sock = sk->sk_socket;
  
  	if (sock->ops->sendpage_locked)
  		return sock->ops->sendpage_locked(sk, page, offset, size,
  						  flags);
  
  	return sock_no_sendpage_locked(sk, page, offset, size, flags);
  }
  EXPORT_SYMBOL(kernel_sendpage_locked);
91cf45f02   Trond Myklebust   [NET]: Add the he...
3185
3186
3187
3188
  int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
  {
  	return sock->ops->shutdown(sock, how);
  }
91cf45f02   Trond Myklebust   [NET]: Add the he...
3189
  EXPORT_SYMBOL(kernel_sock_shutdown);
113c30759   R. Parameswaran   New kernel functi...
3190
3191
3192
3193
  
  /* This routine returns the IP overhead imposed by a socket i.e.
   * the length of the underlying IP header, depending on whether
   * this is an IPv4 or IPv6 socket and the length from IP options turned
57240d007   R. Parameswaran   l2tp: device MTU ...
3194
   * on at the socket. Assumes that the caller has a lock on the socket.
113c30759   R. Parameswaran   New kernel functi...
3195
3196
3197
3198
3199
3200
   */
  u32 kernel_sock_ip_overhead(struct sock *sk)
  {
  	struct inet_sock *inet;
  	struct ip_options_rcu *opt;
  	u32 overhead = 0;
113c30759   R. Parameswaran   New kernel functi...
3201
3202
3203
3204
3205
3206
3207
  #if IS_ENABLED(CONFIG_IPV6)
  	struct ipv6_pinfo *np;
  	struct ipv6_txoptions *optv6 = NULL;
  #endif /* IS_ENABLED(CONFIG_IPV6) */
  
  	if (!sk)
  		return overhead;
113c30759   R. Parameswaran   New kernel functi...
3208
3209
3210
3211
3212
  	switch (sk->sk_family) {
  	case AF_INET:
  		inet = inet_sk(sk);
  		overhead += sizeof(struct iphdr);
  		opt = rcu_dereference_protected(inet->inet_opt,
614d79c09   stephen hemminger   socket: fix set n...
3213
  						sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3214
3215
3216
3217
3218
3219
3220
3221
3222
  		if (opt)
  			overhead += opt->opt.optlen;
  		return overhead;
  #if IS_ENABLED(CONFIG_IPV6)
  	case AF_INET6:
  		np = inet6_sk(sk);
  		overhead += sizeof(struct ipv6hdr);
  		if (np)
  			optv6 = rcu_dereference_protected(np->opt,
614d79c09   stephen hemminger   socket: fix set n...
3223
  							  sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3224
3225
3226
3227
3228
3229
3230
3231
3232
  		if (optv6)
  			overhead += (optv6->opt_flen + optv6->opt_nflen);
  		return overhead;
  #endif /* IS_ENABLED(CONFIG_IPV6) */
  	default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */
  		return overhead;
  	}
  }
  EXPORT_SYMBOL(kernel_sock_ip_overhead);