Blame view

net/socket.c 84.4 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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91

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

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

8ae5e030f   Al Viro   net: switch socke...
113
114
  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...
115
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
  
  static int sock_close(struct inode *inode, struct file *file);
152524231   Christoph Hellwig   net: add support ...
118
119
120
121
  static struct wait_queue_head *sock_get_poll_head(struct file *file,
  		__poll_t events);
  static __poll_t sock_poll_mask(struct file *file, __poll_t);
  static __poll_t sock_poll(struct file *file, struct poll_table_struct *wait);
89bddce58   Stephen Hemminger   [NET] socket: cod...
122
  static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
123
124
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file,
89bddce58   Stephen Hemminger   [NET] socket: cod...
125
  			      unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
126
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  static int sock_fasync(int fd, struct file *filp, int on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  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...
130
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
131
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
132
  				unsigned int flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  /*
   *	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...
138
  static const struct file_operations socket_file_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
  	.owner =	THIS_MODULE,
  	.llseek =	no_llseek,
8ae5e030f   Al Viro   net: switch socke...
141
142
  	.read_iter =	sock_read_iter,
  	.write_iter =	sock_write_iter,
152524231   Christoph Hellwig   net: add support ...
143
144
  	.get_poll_head = sock_get_poll_head,
  	.poll_mask =	sock_poll_mask,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
  	.poll =		sock_poll,
  	.unlocked_ioctl = sock_ioctl,
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
147
148
149
  #ifdef CONFIG_COMPAT
  	.compat_ioctl = compat_sock_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
  	.mmap =		sock_mmap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
  	.release =	sock_close,
  	.fasync =	sock_fasync,
5274f052e   Jens Axboe   [PATCH] Introduce...
153
154
  	.sendpage =	sock_sendpage,
  	.splice_write = generic_splice_sendpage,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
155
  	.splice_read =	sock_splice_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
159
160
  };
  
  /*
   *	The protocol list. Each protocol is registered in here.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  static DEFINE_SPINLOCK(net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
162
  static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
165
166
167
   * 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
168
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
171
172
173
174
175
176
177
178
  /**
   *	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...
179
  int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
181
  	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
183
  	if (ulen == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
  		return 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
185
  	if (copy_from_user(kaddr, uaddr, ulen))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
187
  	return audit_sockaddr(ulen, kaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  }
  
  /**
   *	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...
206

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
  	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
257
258
259
260
261
262
  
  	return &ei->vfs_inode;
  }
  
  static void sock_destroy_inode(struct inode *inode)
  {
438154823   Eric Dumazet   net: sock_def_rea...
263
  	struct socket_alloc *ei;
eaefd1105   Eric Dumazet   net: add __rcu an...
264
  	struct socket_wq *wq;
438154823   Eric Dumazet   net: sock_def_rea...
265
266
  
  	ei = container_of(inode, struct socket_alloc, vfs_inode);
eaefd1105   Eric Dumazet   net: add __rcu an...
267
  	wq = rcu_dereference_protected(ei->socket.wq, 1);
618452202   Lai Jiangshan   net,rcu: convert ...
268
  	kfree_rcu(wq, rcu);
438154823   Eric Dumazet   net: sock_def_rea...
269
  	kmem_cache_free(sock_inode_cachep, ei);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
271
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
273
  	struct socket_alloc *ei = (struct socket_alloc *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274

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

1e9116327   yuan linyu   net: change init_...
278
  static void init_inodecache(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
  {
  	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
89bddce58   Stephen Hemminger   [NET] socket: cod...
281
282
283
284
  					      sizeof(struct socket_alloc),
  					      0,
  					      (SLAB_HWCACHE_ALIGN |
  					       SLAB_RECLAIM_ACCOUNT |
5d097056c   Vladimir Davydov   kmemcg: account c...
285
  					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),
20c2df83d   Paul Mundt   mm: Remove slab d...
286
  					      init_once);
1e9116327   yuan linyu   net: change init_...
287
  	BUG_ON(sock_inode_cachep == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  }
b87221de6   Alexey Dobriyan   const: mark remai...
289
  static const struct super_operations sockfs_ops = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
290
291
292
  	.alloc_inode	= sock_alloc_inode,
  	.destroy_inode	= sock_destroy_inode,
  	.statfs		= simple_statfs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
  };
c23fbb6bc   Eric Dumazet   VFS: delay the de...
294
295
296
297
298
299
  /*
   * 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...
300
  				d_inode(dentry)->i_ino);
c23fbb6bc   Eric Dumazet   VFS: delay the de...
301
  }
3ba13d179   Al Viro   constify dentry_o...
302
  static const struct dentry_operations sockfs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
303
  	.d_dname  = sockfs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  };
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  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...
325
326
327
328
329
330
331
332
333
334
335
336
337
  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...
338
339
  static const struct xattr_handler *sockfs_xattr_handlers[] = {
  	&sockfs_xattr_handler,
4a5901537   Andreas Gruenbacher   xattr: Fix settin...
340
  	&sockfs_security_xattr_handler,
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
341
342
  	NULL
  };
c74a1cbb3   Al Viro   pass default dent...
343
344
345
  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...
346
347
348
  	return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops,
  				  sockfs_xattr_handlers,
  				  &sockfs_dentry_operations, SOCKFS_MAGIC);
c74a1cbb3   Al Viro   pass default dent...
349
350
351
352
353
354
355
356
357
  }
  
  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
358
359
360
  /*
   *	Obtains the first available file descriptor and sets it up for use.
   *
39d8c1b6f   David S. Miller   [NET]: Do not los...
361
362
   *	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
363
364
365
366
367
368
369
370
371
372
373
   *	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...
374
  struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
  {
7cbe66b6b   Al Viro   merge sock_alloc_...
376
  	struct qstr name = { .name = "" };
2c48b9c45   Al Viro   switch alloc_file...
377
  	struct path path;
7cbe66b6b   Al Viro   merge sock_alloc_...
378
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379

600e17792   Masatake YAMATO   net: Providing pr...
380
381
382
383
384
385
386
  	if (dname) {
  		name.name = dname;
  		name.len = strlen(name.name);
  	} else if (sock->sk) {
  		name.name = sock->sk->sk_prot_creator->name;
  		name.len = strlen(name.name);
  	}
4b936885a   Nick Piggin   fs: improve scala...
387
  	path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
8e1611e23   Al Viro   make sock_alloc_f...
388
389
  	if (unlikely(!path.dentry)) {
  		sock_release(sock);
284076305   Al Viro   take descriptor h...
390
  		return ERR_PTR(-ENOMEM);
8e1611e23   Al Viro   make sock_alloc_f...
391
  	}
2c48b9c45   Al Viro   switch alloc_file...
392
  	path.mnt = mntget(sock_mnt);
39d8c1b6f   David S. Miller   [NET]: Do not los...
393

2c48b9c45   Al Viro   switch alloc_file...
394
  	d_instantiate(path.dentry, SOCK_INODE(sock));
39d8c1b6f   David S. Miller   [NET]: Do not los...
395

c9c554f21   Al Viro   alloc_file(): swi...
396
  	file = alloc_file(&path, O_RDWR | (flags & O_NONBLOCK),
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
397
  		  &socket_file_ops);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
398
  	if (IS_ERR(file)) {
8e1611e23   Al Viro   make sock_alloc_f...
399
  		/* drop dentry, keep inode for a bit */
c5ef60352   David Howells   VFS: net/: d_inod...
400
  		ihold(d_inode(path.dentry));
2c48b9c45   Al Viro   switch alloc_file...
401
  		path_put(&path);
8e1611e23   Al Viro   make sock_alloc_f...
402
403
  		/* ... and now kill it properly */
  		sock_release(sock);
39b652527   Anatol Pomozov   fs: Preserve erro...
404
  		return file;
cc3808f8c   Al Viro   switch sock_alloc...
405
406
407
  	}
  
  	sock->file = file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
408
  	file->private_data = sock;
284076305   Al Viro   take descriptor h...
409
  	return file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
410
  }
56b31d1c9   Al Viro   unexport sock_map...
411
  EXPORT_SYMBOL(sock_alloc_file);
39d8c1b6f   David S. Miller   [NET]: Do not los...
412

56b31d1c9   Al Viro   unexport sock_map...
413
  static int sock_map_fd(struct socket *sock, int flags)
39d8c1b6f   David S. Miller   [NET]: Do not los...
414
415
  {
  	struct file *newfile;
284076305   Al Viro   take descriptor h...
416
  	int fd = get_unused_fd_flags(flags);
ce4bb04ca   Al Viro   Fix a leak in soc...
417
418
  	if (unlikely(fd < 0)) {
  		sock_release(sock);
284076305   Al Viro   take descriptor h...
419
  		return fd;
ce4bb04ca   Al Viro   Fix a leak in soc...
420
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
421

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

284076305   Al Viro   take descriptor h...
428
429
  	put_unused_fd(fd);
  	return PTR_ERR(newfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  }
406a3c638   John Fastabend   net: netprio_cgro...
431
  struct socket *sock_from_file(struct file *file, int *err)
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
432
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
433
434
  	if (file->f_op == &socket_file_ops)
  		return file->private_data;	/* set in sock_map_fd */
23bb80d21   Eric Dumazet   [NET]: cleanup so...
435
436
  	*err = -ENOTSOCK;
  	return NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
437
  }
406a3c638   John Fastabend   net: netprio_cgro...
438
  EXPORT_SYMBOL(sock_from_file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
439

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  /**
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
441
   *	sockfd_lookup - Go from a file number to its socket slot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
445
   *	@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 ...
446
   *	to is returned. If an error occurs the err pointer is overwritten
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
450
451
452
453
454
455
   *	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
456
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
457
458
  	file = fget(fd);
  	if (!file) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
461
  		*err = -EBADF;
  		return NULL;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
462

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
463
464
  	sock = sock_from_file(file, err);
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
  		fput(file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
466
467
  	return sock;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
468
  EXPORT_SYMBOL(sockfd_lookup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
470
471
  static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
  {
00e188ef6   Al Viro   sockfd_lookup_lig...
472
  	struct fd f = fdget(fd);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
473
  	struct socket *sock;
3672558c6   Hua Zhong   [NET]: sockfd_loo...
474
  	*err = -EBADF;
00e188ef6   Al Viro   sockfd_lookup_lig...
475
476
477
478
  	if (f.file) {
  		sock = sock_from_file(f.file, err);
  		if (likely(sock)) {
  			*fput_needed = f.flags;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
479
  			return sock;
00e188ef6   Al Viro   sockfd_lookup_lig...
480
481
  		}
  		fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
483
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  }
600e17792   Masatake YAMATO   net: Providing pr...
485
486
487
488
489
  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...
490
  	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
600e17792   Masatake YAMATO   net: Providing pr...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  	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...
511
  static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
86741ec25   Lorenzo Colitti   net: core: Add a ...
512
513
  {
  	int err = simple_setattr(dentry, iattr);
e1a3a60a2   Eric Biggers   net: socket: don'...
514
  	if (!err && (iattr->ia_valid & ATTR_UID)) {
86741ec25   Lorenzo Colitti   net: core: Add a ...
515
  		struct socket *sock = SOCKET_I(d_inode(dentry));
6d8c50dcb   Cong Wang   socket: close rac...
516
517
518
519
  		if (sock->sk)
  			sock->sk->sk_uid = iattr->ia_uid;
  		else
  			err = -ENOENT;
86741ec25   Lorenzo Colitti   net: core: Add a ...
520
521
522
523
  	}
  
  	return err;
  }
600e17792   Masatake YAMATO   net: Providing pr...
524
  static const struct inode_operations sockfs_inode_ops = {
600e17792   Masatake YAMATO   net: Providing pr...
525
  	.listxattr = sockfs_listxattr,
86741ec25   Lorenzo Colitti   net: core: Add a ...
526
  	.setattr = sockfs_setattr,
600e17792   Masatake YAMATO   net: Providing pr...
527
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
  /**
   *	sock_alloc	-	allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
530
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
533
534
   *	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...
535
  struct socket *sock_alloc(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
537
538
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539

a209dfc7b   Eric Dumazet   vfs: dont chain p...
540
  	inode = new_inode_pseudo(sock_mnt->mnt_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
542
543
544
  	if (!inode)
  		return NULL;
  
  	sock = SOCKET_I(inode);
85fe4025c   Christoph Hellwig   fs: do not assign...
545
  	inode->i_ino = get_next_ino();
89bddce58   Stephen Hemminger   [NET] socket: cod...
546
  	inode->i_mode = S_IFSOCK | S_IRWXUGO;
8192b0c48   David Howells   CRED: Wrap task c...
547
548
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
600e17792   Masatake YAMATO   net: Providing pr...
549
  	inode->i_op = &sockfs_inode_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551
552
  	return sock;
  }
f4a00aacd   Tom Herbert   net: Make sock_al...
553
  EXPORT_SYMBOL(sock_alloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
557
558
559
560
  /**
   *	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...
561
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
563

6d8c50dcb   Cong Wang   socket: close rac...
564
  static void __sock_release(struct socket *sock, struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
565
566
567
  {
  	if (sock->ops) {
  		struct module *owner = sock->ops->owner;
6d8c50dcb   Cong Wang   socket: close rac...
568
569
  		if (inode)
  			inode_lock(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
  		sock->ops->release(sock);
6d8c50dcb   Cong Wang   socket: close rac...
571
572
  		if (inode)
  			inode_unlock(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
575
  		sock->ops = NULL;
  		module_put(owner);
  	}
eaefd1105   Eric Dumazet   net: add __rcu an...
576
  	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
3410f22ea   Yang Yingliang   socket: replace s...
577
578
  		pr_err("%s: fasync list not empty!
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
581
582
583
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
584
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  }
6d8c50dcb   Cong Wang   socket: close rac...
586
587
588
589
590
  
  void sock_release(struct socket *sock)
  {
  	__sock_release(sock, NULL);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
591
  EXPORT_SYMBOL(sock_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592

c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
593
  void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)
20d494735   Patrick Ohly   net: socket infra...
594
  {
140c55d4b   Eric Dumazet   net-timestamp: so...
595
  	u8 flags = *tx_flags;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
596
  	if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE)
140c55d4b   Eric Dumazet   net-timestamp: so...
597
  		flags |= SKBTX_HW_TSTAMP;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
598
  	if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE)
140c55d4b   Eric Dumazet   net-timestamp: so...
599
  		flags |= SKBTX_SW_TSTAMP;
c14ac9451   Soheil Hassas Yeganeh   sock: enable time...
600
  	if (tsflags & SOF_TIMESTAMPING_TX_SCHED)
140c55d4b   Eric Dumazet   net-timestamp: so...
601
  		flags |= SKBTX_SCHED_TSTAMP;
140c55d4b   Eric Dumazet   net-timestamp: so...
602
  	*tx_flags = flags;
20d494735   Patrick Ohly   net: socket infra...
603
  }
67cc0d407   Willem de Bruijn   net-timestamp: op...
604
  EXPORT_SYMBOL(__sock_tx_timestamp);
20d494735   Patrick Ohly   net: socket infra...
605

d8725c86a   Al Viro   get rid of the si...
606
  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
  {
01e97e651   Al Viro   new helper: msg_d...
608
  	int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg));
d8725c86a   Al Viro   get rid of the si...
609
610
  	BUG_ON(ret == -EIOCBQUEUED);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  }
d8725c86a   Al Viro   get rid of the si...
612
  int sock_sendmsg(struct socket *sock, struct msghdr *msg)
228e548e6   Anton Blanchard   net: Add sendmmsg...
613
  {
d8725c86a   Al Viro   get rid of the si...
614
  	int err = security_socket_sendmsg(sock, msg,
01e97e651   Al Viro   new helper: msg_d...
615
  					  msg_data_left(msg));
228e548e6   Anton Blanchard   net: Add sendmmsg...
616

d8725c86a   Al Viro   get rid of the si...
617
  	return err ?: sock_sendmsg_nosec(sock, msg);
0cf00c6f3   Gu Zheng   net/socket.c : in...
618
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
619
  EXPORT_SYMBOL(sock_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
621
622
623
  
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size)
  {
6aa248145   Al Viro   switch kernel_sen...
624
  	iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size);
d8725c86a   Al Viro   get rid of the si...
625
  	return sock_sendmsg(sock, msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
627
  EXPORT_SYMBOL(kernel_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628

306b13eb3   Tom Herbert   proto_ops: Add lo...
629
630
631
632
633
634
  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...
635
  		return sock_no_sendmsg_locked(sk, msg, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
636
637
638
639
640
641
  
  	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...
642
643
644
645
646
647
648
649
650
  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...
651
652
653
654
655
656
657
658
659
660
661
662
  /* 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...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  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_...
683
684
685
686
687
688
  /*
   * 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...
689
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
f24b9be59   Willem de Bruijn   net-timestamp: ex...
690
  	struct scm_timestamping tss;
b50a5c70f   Miroslav Lichvar   net: allow simult...
691
  	int empty = 1, false_tstamp = 0;
20d494735   Patrick Ohly   net: socket infra...
692
693
694
695
696
  	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...
697
  	if (need_software_tstamp && skb->tstamp == 0) {
20d494735   Patrick Ohly   net: socket infra...
698
  		__net_timestamp(skb);
b50a5c70f   Miroslav Lichvar   net: allow simult...
699
700
  		false_tstamp = 1;
  	}
20d494735   Patrick Ohly   net: socket infra...
701
702
703
704
705
706
707
708
  
  	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...
709
710
  			struct timespec ts;
  			skb_get_timestampns(skb, &ts);
20d494735   Patrick Ohly   net: socket infra...
711
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
712
  				 sizeof(ts), &ts);
20d494735   Patrick Ohly   net: socket infra...
713
714
  		}
  	}
f24b9be59   Willem de Bruijn   net-timestamp: ex...
715
  	memset(&tss, 0, sizeof(tss));
c199105d1   Willem de Bruijn   net-timestamp: on...
716
  	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
f24b9be59   Willem de Bruijn   net-timestamp: ex...
717
  	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
20d494735   Patrick Ohly   net: socket infra...
718
  		empty = 0;
4d276eb6a   Willem de Bruijn   net: remove depre...
719
  	if (shhwtstamps &&
b9f40e21e   Willem de Bruijn   net-timestamp: mo...
720
  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
b50a5c70f   Miroslav Lichvar   net: allow simult...
721
  	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
aad9c8c47   Miroslav Lichvar   net: add new cont...
722
  	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
4d276eb6a   Willem de Bruijn   net: remove depre...
723
  		empty = 0;
aad9c8c47   Miroslav Lichvar   net: add new cont...
724
725
726
727
  		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
  		    !skb_is_err_queue(skb))
  			put_ts_pktinfo(msg, skb);
  	}
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
728
  	if (!empty) {
20d494735   Patrick Ohly   net: socket infra...
729
  		put_cmsg(msg, SOL_SOCKET,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
730
  			 SCM_TIMESTAMPING, sizeof(tss), &tss);
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
731

8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
732
  		if (skb_is_err_queue(skb) && skb->len &&
4ef1b2869   Soheil Hassas Yeganeh   tcp: mark skbs wi...
733
  		    SKB_EXT_ERR(skb)->opt_stats)
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
734
735
736
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
  				 skb->len, skb->data);
  	}
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
737
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
738
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
6e3e939f3   Johannes Berg   net: add wireless...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
  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 ...
754
755
  static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
  				   struct sk_buff *skb)
3b885787e   Neil Horman   net: Generalize s...
756
  {
744d5a3e9   Eyal Birger   net: move skb->dr...
757
  	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
3b885787e   Neil Horman   net: Generalize s...
758
  		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
744d5a3e9   Eyal Birger   net: move skb->dr...
759
  			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
3b885787e   Neil Horman   net: Generalize s...
760
  }
767dd0336   Eric Dumazet   net: speedup sock...
761
  void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
3b885787e   Neil Horman   net: Generalize s...
762
763
764
765
766
  	struct sk_buff *skb)
  {
  	sock_recv_timestamp(msg, sk, skb);
  	sock_recv_drops(msg, sk, skb);
  }
767dd0336   Eric Dumazet   net: speedup sock...
767
  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
3b885787e   Neil Horman   net: Generalize s...
768

1b7841404   Ying Xue   net: Remove iocb ...
769
  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
2da62906b   Al Viro   [net] drop 'size'...
770
  				     int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
  {
2da62906b   Al Viro   [net] drop 'size'...
772
  	return sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773
  }
2da62906b   Al Viro   [net] drop 'size'...
774
  int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
775
  {
2da62906b   Al Viro   [net] drop 'size'...
776
  	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
777

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

c1249c0aa   Martin Lucina   net: Document the...
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
  /**
   * 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...
797
798
  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
799
800
801
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
6aa248145   Al Viro   switch kernel_sen...
802
  	iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  	set_fs(KERNEL_DS);
2da62906b   Al Viro   [net] drop 'size'...
804
  	result = sock_recvmsg(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
808
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
810
811
  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
812
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
814
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
815
  	sock = file->private_data;
35f9c09fe   Eric Dumazet   tcp: tcp_sendpage...
816
817
818
  	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...
819

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

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
823
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
824
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
825
826
827
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
828
829
  	if (unlikely(!sock->ops->splice_read))
  		return -EINVAL;
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
830
831
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
8ae5e030f   Al Viro   net: switch socke...
832
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
833
  {
6d6523302   Al Viro   net/socket.c: fol...
834
835
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
836
837
  	struct msghdr msg = {.msg_iter = *to,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
838
  	ssize_t res;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
839

8ae5e030f   Al Viro   net: switch socke...
840
841
842
843
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
  
  	if (iocb->ki_pos != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
845

66ee59af6   Christoph Hellwig   fs: remove ki_nbytes
846
  	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
847
  		return 0;
2da62906b   Al Viro   [net] drop 'size'...
848
  	res = sock_recvmsg(sock, &msg, msg.msg_flags);
8ae5e030f   Al Viro   net: switch socke...
849
850
  	*to = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
  }
8ae5e030f   Al Viro   net: switch socke...
852
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
853
  {
6d6523302   Al Viro   net/socket.c: fol...
854
855
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
856
857
  	struct msghdr msg = {.msg_iter = *from,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
858
  	ssize_t res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859

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

8ae5e030f   Al Viro   net: switch socke...
863
864
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
6d6523302   Al Viro   net/socket.c: fol...
865
866
  	if (sock->type == SOCK_SEQPACKET)
  		msg.msg_flags |= MSG_EOR;
d8725c86a   Al Viro   get rid of the si...
867
  	res = sock_sendmsg(sock, &msg);
8ae5e030f   Al Viro   net: switch socke...
868
869
  	*from = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
872
873
874
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
875
  static DEFINE_MUTEX(br_ioctl_mutex);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
876
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877

881d966b4   Eric W. Biederman   [NET]: Make the d...
878
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
880
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
881
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
882
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883
884
  }
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
885
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
886
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887

881d966b4   Eric W. Biederman   [NET]: Make the d...
888
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
889
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
890
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
892
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
  }
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
895
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
896
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897

89bddce58   Stephen Hemminger   [NET] socket: cod...
898
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
900
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
902
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
904
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
905
906
907
908
909
910
911
912
913
914
915
916
  static long sock_do_ioctl(struct net *net, struct socket *sock,
  				 unsigned int cmd, unsigned long arg)
  {
  	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...
917
918
  	if (err != -ENOIOCTLCMD)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
919

36fd633ec   Al Viro   net: separate SIO...
920
921
922
923
924
925
926
927
928
  	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...
929
930
931
932
933
934
935
936
937
  	} else {
  		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;
36fd633ec   Al Viro   net: separate SIO...
938
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
939
940
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
942
943
944
  /*
   *	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 ...
945
  struct ns_common *get_net_ns(struct ns_common *ns)
c62cce2ca   Andrey Vagin   net: add an ioctl...
946
947
948
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
d8d211a2a   Kirill Tkhai   net: Make extern ...
949
  EXPORT_SYMBOL_GPL(get_net_ns);
c62cce2ca   Andrey Vagin   net: add an ioctl...
950

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
952
953
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
  	struct socket *sock;
881d966b4   Eric W. Biederman   [NET]: Make the d...
954
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
957
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958

b69aee04f   Eric Dumazet   [NET]: Use file->...
959
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
960
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
961
  	net = sock_net(sk);
44c02a2c3   Al Viro   dev_ioctl(): move...
962
963
964
965
966
967
968
969
970
  	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
971
  	} else
3d23e349d   Johannes Berg   wext: refactor
972
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
b1b0c2450   Al Viro   lift handling of ...
974
  		err = wext_handle_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  	} else
3d23e349d   Johannes Berg   wext: refactor
976
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
977
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
980
981
982
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
393cc3f51   Jiri Slaby   fs/fcntl: f_setow...
983
  			err = f_setown(sock->file, pid, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984
985
986
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
987
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
988
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
990
991
992
993
994
995
996
  			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: ...
997
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
998
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
999
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1000
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1001
1002
1003
1004
1005
1006
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1007
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1008
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
1009
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1010
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
1015
1016
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1017
1018
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1020
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1021
  			break;
c62cce2ca   Andrey Vagin   net: add an ioctl...
1022
1023
1024
1025
1026
1027
1028
  		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
1029
  		default:
6b96018b2   Arnd Bergmann   compat: move sock...
1030
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1032
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
1036
1037
1038
1039
  	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...
1040

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
1043
1044
1045
1046
1047
1048
1049
  	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
1050
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1051
1052
1053
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
1055
1056
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1057
1058
1059
1060
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1062
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1063

152524231   Christoph Hellwig   net: add support ...
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
  static struct wait_queue_head *sock_get_poll_head(struct file *file,
  		__poll_t events)
  {
  	struct socket *sock = file->private_data;
  
  	if (!sock->ops->poll_mask)
  		return NULL;
  	sock_poll_busy_loop(sock, events);
  	return sk_sleep(sock->sk);
  }
  
  static __poll_t sock_poll_mask(struct file *file, __poll_t events)
  {
  	struct socket *sock = file->private_data;
  
  	/*
  	 * We need to be sure we are in sync with the socket flags modification.
  	 *
  	 * This memory barrier is paired in the wq_has_sleeper.
  	 */
  	smp_mb();
  
  	/* this socket can poll_ll so tell the system call */
  	return sock->ops->poll_mask(sock, events) |
  		(sk_can_busy_loop(sock->sk) ? POLL_BUSY_LOOP : 0);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  /* No kernel lock held - perfect */
ade994f4f   Al Viro   net: annotate ->p...
1091
  static __poll_t sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
  {
3cafb3763   Christoph Hellwig   net: refactor soc...
1093
  	struct socket *sock = file->private_data;
152524231   Christoph Hellwig   net: add support ...
1094
1095
1096
1097
1098
1099
1100
1101
1102
  	__poll_t events = poll_requested_events(wait), mask = 0;
  
  	if (sock->ops->poll) {
  		sock_poll_busy_loop(sock, events);
  		mask = sock->ops->poll(file, sock, wait);
  	} else if (sock->ops->poll_mask) {
  		sock_poll_wait(file, sock_get_poll_head(file, events), wait);
  		mask = sock->ops->poll_mask(sock, events);
  	}
2d48d67fa   Eliezer Tamir   net: poll/select ...
1103

152524231   Christoph Hellwig   net: add support ...
1104
  	return mask | sock_poll_busy_flag(sock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1106
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
1108
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109
1110
1111
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1112
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1113
  {
6d8c50dcb   Cong Wang   socket: close rac...
1114
  	__sock_release(SOCKET_I(inode), inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
  	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...
1126
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1127
1128
1129
1130
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1131
1132
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
eaefd1105   Eric Dumazet   net: add __rcu an...
1133
  	struct socket_wq *wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134

989a29792   Eric Dumazet   fasync: RCU and f...
1135
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1137
1138
  
  	lock_sock(sk);
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
1139
  	wq = rcu_dereference_protected(sock->wq, lockdep_sock_is_held(sk));
eaefd1105   Eric Dumazet   net: add __rcu an...
1140
  	fasync_helper(fd, filp, on, &wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141

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

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

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1152
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1154
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1156

89bddce58   Stephen Hemminger   [NET] socket: cod...
1157
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1158
  	case SOCK_WAKE_WAITD:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1159
  		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1160
1161
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1162
  	case SOCK_WAKE_SPACE:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1163
  		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1164
1165
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1166
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1167
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1168
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1170
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1171
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1172
  	}
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1173

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
1175
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1176
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177

721db93a5   Pavel Emelyanov   net: Export __soc...
1178
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1179
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1180
1181
1182
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1183
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
1185
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1186
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
  	 */
  	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 ...
1199
1200
1201
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1202
1203
1204
1205
1206
1207
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1208

55737fda0   Stephen Hemminger   [NET]: socket fam...
1209
1210
1211
1212
1213
1214
1215
  	/*
  	 *	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_...
1216
1217
  		net_warn_ratelimited("socket: no more sockets
  ");
55737fda0   Stephen Hemminger   [NET]: socket fam...
1218
1219
1220
1221
1222
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1223
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1224
1225
1226
  	/* 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
1227
1228
1229
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
190683a9d   Eric Dumazet   net: net_families...
1230
  	if (rcu_access_pointer(net_families[family]) == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1231
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1232
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1233
1234
1235
1236
1237
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
1239
1240
1241
1242
  
  	/*
  	 * 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...
1243
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1245
1246
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1247
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1248
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1250

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251
1252
1253
1254
  	/*
  	 * 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...
1255
1256
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
1258
1259
1260
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1261
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1262
1263
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1264
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1265
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266

55737fda0   Stephen Hemminger   [NET]: socket fam...
1267
1268
1269
1270
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1271
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1272
1273
1274
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1276
1277
1278
1279
1280
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
  }
721db93a5   Pavel Emelyanov   net: Export __soc...
1282
  EXPORT_SYMBOL(__sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
1284
1285
  
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1286
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1288
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1289

eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1290
  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
  {
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1292
  	return __sock_create(net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1294
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1295

9d6a15c3f   Dominik Brodowski   net: socket: add ...
1296
  int __sys_socket(int family, int type, int protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297
1298
1299
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1300
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1301
1302
1303
1304
1305
  	/* 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: ...
1306
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1307
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1308
1309
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310

aaca0bdca   Ulrich Drepper   flag parameters: ...
1311
1312
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1313
1314
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
8e1611e23   Al Viro   make sock_alloc_f...
1315
  		return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1316

8e1611e23   Al Viro   make sock_alloc_f...
1317
  	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1318
  }
9d6a15c3f   Dominik Brodowski   net: socket: add ...
1319
1320
1321
1322
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
  {
  	return __sys_socket(family, type, protocol);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
1324
1325
  /*
   *	Create a pair of connected sockets.
   */
6debc8d83   Dominik Brodowski   net: socket: add ...
1326
  int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
1328
1329
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1330
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1331
1332
1333
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1334
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1335
1336
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1337

aaca0bdca   Ulrich Drepper   flag parameters: ...
1338
1339
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1340
  	/*
016a266bd   Al Viro   socketpair(): all...
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
  	 * 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
1363
1364
1365
1366
1367
  	 * 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...
1368
  	if (unlikely(err < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
1370
1371
  		goto out;
  
  	err = sock_create(family, type, protocol, &sock2);
016a266bd   Al Viro   socketpair(): all...
1372
1373
1374
  	if (unlikely(err < 0)) {
  		sock_release(sock1);
  		goto out;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1375
  	}
d73aa2867   Yann Droneaud   net: handle error...
1376

d47cd9450   David Herrmann   net: hook socketp...
1377
1378
1379
1380
1381
1382
  	err = security_socket_socketpair(sock1, sock2);
  	if (unlikely(err)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
  	}
016a266bd   Al Viro   socketpair(): all...
1383
1384
1385
1386
1387
  	err = sock1->ops->socketpair(sock1, sock2);
  	if (unlikely(err < 0)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
284076305   Al Viro   take descriptor h...
1388
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1389
  	newfile1 = sock_alloc_file(sock1, flags, NULL);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1390
  	if (IS_ERR(newfile1)) {
284076305   Al Viro   take descriptor h...
1391
  		err = PTR_ERR(newfile1);
016a266bd   Al Viro   socketpair(): all...
1392
1393
  		sock_release(sock2);
  		goto out;
284076305   Al Viro   take descriptor h...
1394
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1395
  	newfile2 = sock_alloc_file(sock2, flags, NULL);
284076305   Al Viro   take descriptor h...
1396
1397
  	if (IS_ERR(newfile2)) {
  		err = PTR_ERR(newfile2);
016a266bd   Al Viro   socketpair(): all...
1398
1399
  		fput(newfile1);
  		goto out;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1400
  	}
157cf649a   Al Viro   sanitize audit_fd...
1401
  	audit_fd_pair(fd1, fd2);
d73aa2867   Yann Droneaud   net: handle error...
1402

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

016a266bd   Al Viro   socketpair(): all...
1407
  out:
d73aa2867   Yann Droneaud   net: handle error...
1408
  	put_unused_fd(fd2);
d73aa2867   Yann Droneaud   net: handle error...
1409
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410
1411
  	return err;
  }
6debc8d83   Dominik Brodowski   net: socket: add ...
1412
1413
1414
1415
1416
  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
1417
1418
1419
1420
1421
1422
1423
  /*
   *	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 ...
1424
  int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425
1426
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1427
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1428
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429

89bddce58   Stephen Hemminger   [NET] socket: cod...
1430
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1431
  	if (sock) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1432
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1433
1434
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1435
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1436
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1437
1438
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1439
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1440
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1442
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1443
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
1445
  	return err;
  }
a87d35d87   Dominik Brodowski   net: socket: add ...
1446
1447
1448
1449
  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
1450
1451
1452
1453
1454
  /*
   *	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 ...
1455
  int __sys_listen(int fd, int backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1456
1457
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1458
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1459
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1460
1461
1462
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1463
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1464
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1465
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
1467
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1468
1469
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1471
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472
1473
1474
  	}
  	return err;
  }
25e290eed   Dominik Brodowski   net: socket: add ...
1475
1476
1477
1478
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  {
  	return __sys_listen(fd, backlog);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1479
1480
1481
1482
1483
1484
1485
1486
1487
  /*
   *	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...
1488
   *	clean when we restructure accept also.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1489
   */
4541e8056   Dominik Brodowski   net: socket: add ...
1490
1491
  int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
  		  int __user *upeer_addrlen, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1492
1493
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1494
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1495
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1496
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497

77d272005   Ulrich Drepper   flag parameters: ...
1498
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1499
1500
1501
1502
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1503
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504
1505
1506
1507
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1508
1509
  	newsock = sock_alloc();
  	if (!newsock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
1511
1512
1513
  		goto out_put;
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1514
1515
1516
1517
1518
  	/*
  	 * 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...
1519
  	newfd = get_unused_fd_flags(flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1520
1521
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1522
1523
  		sock_release(newsock);
  		goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1524
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1525
  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1526
  	if (IS_ERR(newfile)) {
284076305   Al Viro   take descriptor h...
1527
1528
  		err = PTR_ERR(newfile);
  		put_unused_fd(newfd);
284076305   Al Viro   take descriptor h...
1529
1530
  		goto out_put;
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
1531

a79af59ef   Frank Filz   [NET]: Fix module...
1532
1533
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1534
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1535

cdfbabfb2   David Howells   net: Work around ...
1536
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags, false);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1538
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1539
1540
  
  	if (upeer_sockaddr) {
9b2c45d47   Denys Vlasenko   net: make getname...
1541
1542
1543
  		len = newsock->ops->getname(newsock,
  					(struct sockaddr *)&address, 2);
  		if (len < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1545
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546
  		}
43db362d3   Maciej Żenczykowski   net: get rid of s...
1547
  		err = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1548
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1550
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
1552
1553
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1554
1555
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1557
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1558
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559
1560
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1561
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1562
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1563
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1564
1565
  	goto out_put;
  }
4541e8056   Dominik Brodowski   net: socket: add ...
1566
1567
1568
1569
1570
  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...
1571
1572
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1573
  {
4541e8056   Dominik Brodowski   net: socket: add ...
1574
  	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1575
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
  /*
   *	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 ...
1587
  int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1588
1589
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1590
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1591
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1592

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1593
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594
1595
  	if (!sock)
  		goto out;
43db362d3   Maciej Żenczykowski   net: get rid of s...
1596
  	err = move_addr_to_kernel(uservaddr, addrlen, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1597
1598
  	if (err < 0)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1599
  	err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1600
  	    security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1601
1602
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1603
  	err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1604
1605
  				 sock->file->f_flags);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1606
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
1609
  out:
  	return err;
  }
1387c2c2f   Dominik Brodowski   net: socket: add ...
1610
1611
1612
1613
1614
  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
1615
1616
1617
1618
  /*
   *	Get the local address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
8882a107b   Dominik Brodowski   net: socket: add ...
1619
1620
  int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
1622
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1623
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1624
  	int err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1625

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1626
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627
1628
1629
1630
1631
1632
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1633
1634
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1635
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1636
1637
          /* "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
1638
1639
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1640
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
1642
1643
  out:
  	return err;
  }
8882a107b   Dominik Brodowski   net: socket: add ...
1644
1645
1646
1647
1648
  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
1649
1650
1651
1652
  /*
   *	Get the remote address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
b21c8f838   Dominik Brodowski   net: socket: add ...
1653
1654
  int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1655
1656
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1657
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1658
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1659

89bddce58   Stephen Hemminger   [NET] socket: cod...
1660
1661
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
1663
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1664
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665
1666
  			return err;
  		}
9b2c45d47   Denys Vlasenko   net: make getname...
1667
1668
1669
1670
  		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...
1671
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1672
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
1674
1675
  	}
  	return err;
  }
b21c8f838   Dominik Brodowski   net: socket: add ...
1676
1677
1678
1679
1680
  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
1681
1682
1683
1684
1685
  /*
   *	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 ...
1686
1687
  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
1688
1689
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1690
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
1692
1693
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1694
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1695

602bd0e90   Al Viro   net: switch sendt...
1696
1697
1698
  	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1699
1700
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1701
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1702

89bddce58   Stephen Hemminger   [NET] socket: cod...
1703
  	msg.msg_name = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1704
1705
1706
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1707
  	if (addr) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1708
  		err = move_addr_to_kernel(addr, addr_len, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
1710
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1711
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1712
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
1714
1715
1716
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
d8725c86a   Al Viro   get rid of the si...
1717
  	err = sock_sendmsg(sock, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718

89bddce58   Stephen Hemminger   [NET] socket: cod...
1719
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1720
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1721
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
1723
  	return err;
  }
211b634b7   Dominik Brodowski   net: socket: add ...
1724
1725
1726
1727
1728
1729
  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
1730
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1731
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1733
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1734
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1735
  {
211b634b7   Dominik Brodowski   net: socket: add ...
1736
  	return __sys_sendto(fd, buff, len, flags, NULL, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
1738
1739
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1740
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1741
1742
1743
   *	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 ...
1744
1745
  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
1746
1747
1748
1749
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1750
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1751
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1752
  	int fput_needed;
602bd0e90   Al Viro   net: switch sendt...
1753
1754
1755
  	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1756
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1757
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1758
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1759

89bddce58   Stephen Hemminger   [NET] socket: cod...
1760
1761
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1762
1763
1764
1765
  	/* 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...
1766
  	msg.msg_iocb = NULL;
9f138fa60   Alexander Potapenko   net: initialize m...
1767
  	msg.msg_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1768
1769
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1770
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771

89bddce58   Stephen Hemminger   [NET] socket: cod...
1772
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1773
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1774
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1775
1776
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1778
1779
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1780
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781
1782
  	return err;
  }
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1783
1784
1785
1786
1787
1788
  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
1789
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1790
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1792
1793
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1794
  {
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1795
  	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
1798
1799
1800
1801
  }
  
  /*
   *	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 ...
1802
1803
  static int __sys_setsockopt(int fd, int level, int optname,
  			    char __user *optval, int optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1804
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1805
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806
1807
1808
1809
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1810
1811
1812
1813
  
  	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...
1814
1815
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
1817
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1818
1819
1820
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1821
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1822
1823
1824
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1825
1826
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
1828
1829
  	}
  	return err;
  }
cc36dca0d   Dominik Brodowski   net: socket: add ...
1830
1831
1832
1833
1834
  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
1835
1836
1837
1838
  /*
   *	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 ...
1839
1840
  static int __sys_getsockopt(int fd, int level, int optname,
  			    char __user *optval, int __user *optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1841
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1842
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1843
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1844
1845
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1846
1847
1848
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1849
1850
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1851
1852
1853
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1855
1856
1857
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1858
1859
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
1861
1862
  	}
  	return err;
  }
13a2d70e2   Dominik Brodowski   net: socket: add ...
1863
1864
1865
1866
1867
  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
1868
1869
1870
  /*
   *	Shutdown a socket.
   */
005a1aeac   Dominik Brodowski   net: socket: add ...
1871
  int __sys_shutdown(int fd, int how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1872
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1873
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1874
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1875
1876
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1878
1879
1880
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
1882
1883
  	}
  	return err;
  }
005a1aeac   Dominik Brodowski   net: socket: add ...
1884
1885
1886
1887
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
  {
  	return __sys_shutdown(fd, how);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1888
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1889
1890
1891
1892
1893
   * 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...
1894
1895
1896
1897
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
da1842849   Al Viro   net: switch impor...
1898
1899
1900
1901
  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...
1902
  {
ffb07550c   Al Viro   copy_msghdr_from_...
1903
  	struct user_msghdr msg;
08adb7dab   Al Viro   fold verify_iovec...
1904
  	ssize_t err;
ffb07550c   Al Viro   copy_msghdr_from_...
1905
  	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
1661bf364   Dan Carpenter   net: heap overflo...
1906
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
1907

864d96642   Paolo Abeni   net/socket: fix t...
1908
  	kmsg->msg_control = (void __force *)msg.msg_control;
ffb07550c   Al Viro   copy_msghdr_from_...
1909
1910
1911
1912
1913
  	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...
1914
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
1915
1916
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
1917
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
1918
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
1919
1920
  
  	if (save_addr)
ffb07550c   Al Viro   copy_msghdr_from_...
1921
  		*save_addr = msg.msg_name;
08adb7dab   Al Viro   fold verify_iovec...
1922

ffb07550c   Al Viro   copy_msghdr_from_...
1923
  	if (msg.msg_name && kmsg->msg_namelen) {
08adb7dab   Al Viro   fold verify_iovec...
1924
  		if (!save_addr) {
864d96642   Paolo Abeni   net/socket: fix t...
1925
1926
  			err = move_addr_to_kernel(msg.msg_name,
  						  kmsg->msg_namelen,
08adb7dab   Al Viro   fold verify_iovec...
1927
1928
1929
1930
1931
1932
1933
1934
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
ffb07550c   Al Viro   copy_msghdr_from_...
1935
  	if (msg.msg_iovlen > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
1936
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
1937
  	kmsg->msg_iocb = NULL;
ffb07550c   Al Viro   copy_msghdr_from_...
1938
1939
  	return import_iovec(save_addr ? READ : WRITE,
  			    msg.msg_iov, msg.msg_iovlen,
da1842849   Al Viro   net: switch impor...
1940
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
1661bf364   Dan Carpenter   net: heap overflo...
1941
  }
666547ff5   Al Viro   separate kernel- ...
1942
  static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
1943
  			 struct msghdr *msg_sys, unsigned int flags,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1944
1945
  			 struct used_address *used_address,
  			 unsigned int allowed_msghdr_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1946
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1947
1948
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1949
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1950
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
b9d717a7b   Alex Williamson   [NET]: Make sure ...
1951
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
846cc1231   Amit Kushwaha   net: socket: pref...
1952
  				__aligned(sizeof(__kernel_size_t));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1953
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1954
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
1955
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
1956
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1957

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

084493200   Al Viro   {compat_,}verify_...
1960
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
1961
  		err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
084493200   Al Viro   {compat_,}verify_...
1962
  	else
08adb7dab   Al Viro   fold verify_iovec...
1963
  		err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1964
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
1965
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
  
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1968
  	if (msg_sys->msg_controllen > INT_MAX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1969
  		goto out_freeiov;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1970
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1971
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1972
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1973
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
1974
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1975
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1976
1977
  		if (err)
  			goto out_freeiov;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1978
1979
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1980
  	} else if (ctl_len) {
ac4340fc3   David S. Miller   net: Assert at bu...
1981
1982
  		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
  			     CMSG_ALIGN(sizeof(struct cmsghdr)));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1983
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1984
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1985
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1986
1987
1988
1989
  				goto out_freeiov;
  		}
  		err = -EFAULT;
  		/*
228e548e6   Anton Blanchard   net: Add sendmmsg...
1990
  		 * Careful! Before this, msg_sys->msg_control contains a user pointer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1991
1992
1993
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
1994
  		if (copy_from_user(ctl_buf,
228e548e6   Anton Blanchard   net: Add sendmmsg...
1995
  				   (void __user __force *)msg_sys->msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1996
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1997
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1998
  		msg_sys->msg_control = ctl_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2000
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2001
2002
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2003
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2004
2005
2006
2007
2008
2009
  	/*
  	 * 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:...
2010
2011
2012
  	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...
2013
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
2014
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2015
2016
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
2017
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2018
2019
2020
2021
2022
2023
  	/*
  	 * 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:...
2024
2025
2026
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2027
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2028
2029
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
2030
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2031
2032
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  out_freeiov:
da1842849   Al Viro   net: switch impor...
2033
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2034
2035
2036
2037
2038
2039
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
e1834a329   Dominik Brodowski   net: socket: move...
2040
2041
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2042
2043
2044
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2045
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2046
2047
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2048
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2049
2050
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2051
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2052

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2053
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2054
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055
2056
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2057
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2058
  {
e1834a329   Dominik Brodowski   net: socket: move...
2059
  	return __sys_sendmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2060
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
2061
2062
2063
2064
2065
  /*
   *	Linux sendmmsg interface
   */
  
  int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
e1834a329   Dominik Brodowski   net: socket: move...
2066
  		   unsigned int flags, bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2067
2068
2069
2070
2071
2072
  {
  	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...
2073
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2074
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2075

e1834a329   Dominik Brodowski   net: socket: move...
2076
2077
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
98382f419   Anton Blanchard   net: Cap number o...
2078
2079
  	if (vlen > UIO_MAXIOV)
  		vlen = UIO_MAXIOV;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2080
2081
2082
2083
2084
2085
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2086
  	used_address.name_len = UINT_MAX;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2087
2088
  	entry = mmsg;
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2089
  	err = 0;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2090
  	flags |= MSG_BATCH;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2091
2092
  
  	while (datagrams < vlen) {
f092276d8   Tom Herbert   net: Add MSG_BATC...
2093
2094
  		if (datagrams == vlen - 1)
  			flags = oflags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2095
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2096
  			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2097
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2098
2099
2100
2101
2102
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2103
  			err = ___sys_sendmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2104
  					     (struct user_msghdr __user *)entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2105
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2106
2107
2108
2109
2110
2111
2112
2113
2114
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
  
  		if (err)
  			break;
  		++datagrams;
3023898b7   Soheil Hassas Yeganeh   sock: fix sendmms...
2115
2116
  		if (msg_data_left(&msg_sys))
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2117
  		cond_resched();
228e548e6   Anton Blanchard   net: Add sendmmsg...
2118
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2119
  	fput_light(sock->file, fput_needed);
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2120
2121
  	/* We only return an error if no datagrams were able to be sent */
  	if (datagrams != 0)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2122
  		return datagrams;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2123
2124
2125
2126
2127
2128
  	return err;
  }
  
  SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2129
  	return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2130
  }
666547ff5   Al Viro   separate kernel- ...
2131
  static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
2132
  			 struct msghdr *msg_sys, unsigned int flags, int nosec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2133
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2134
2135
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2136
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2137
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2138
  	unsigned long cmsg_ptr;
2da62906b   Al Viro   [net] drop 'size'...
2139
  	int len;
08adb7dab   Al Viro   fold verify_iovec...
2140
  	ssize_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2141
2142
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
2143
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2144
2145
2146
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
08adb7dab   Al Viro   fold verify_iovec...
2147
  	int __user *uaddr_len = COMPAT_NAMELEN(msg);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2148

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

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2151
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
2152
  		err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov);
f3d334260   Hannes Frederic Sowa   net: rework recvm...
2153
  	else
08adb7dab   Al Viro   fold verify_iovec...
2154
  		err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2155
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
2156
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2157

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2158
2159
  	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...
2160

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2161
2162
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2163
2164
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
2165
  	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2166
2167
2168
2169
2170
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
2171
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2172
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2173
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2174
2175
2176
  		if (err < 0)
  			goto out_freeiov;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2177
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
2178
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2179
2180
2181
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2182
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2183
2184
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2185
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2186
2187
2188
2189
2190
2191
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
da1842849   Al Viro   net: switch impor...
2192
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2193
2194
2195
2196
2197
2198
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
e1834a329   Dominik Brodowski   net: socket: move...
2199
2200
  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...
2201
2202
2203
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2204
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2205
2206
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2207
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2208
2209
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2210
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2211

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2212
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2213
2214
2215
  out:
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2216
  SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2217
2218
  		unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2219
  	return __sys_recvmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2220
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
  /*
   *     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...
2231
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2232
  	struct msghdr msg_sys;
766b9f928   Deepa Dinamani   fs: poll/select/r...
2233
2234
  	struct timespec64 end_time;
  	struct timespec64 timeout64;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
  
  	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...
2246
2247
2248
2249
2250
2251
  	if (likely(!(flags & MSG_ERRQUEUE))) {
  		err = sock_error(sock->sk);
  		if (err) {
  			datagrams = err;
  			goto out_put;
  		}
e623a9e9d   Maxime Jayat   net: socket: fix ...
2252
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2253
2254
  
  	entry = mmsg;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2255
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2256
2257
2258
2259
2260
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2261
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2262
  			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2263
2264
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2265
2266
2267
2268
2269
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2270
  			err = ___sys_recvmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2271
  					     (struct user_msghdr __user *)entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2272
2273
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2274
2275
2276
2277
2278
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2279
2280
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2281
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2282
2283
2284
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2285
  		if (timeout) {
766b9f928   Deepa Dinamani   fs: poll/select/r...
2286
2287
2288
  			ktime_get_ts64(&timeout64);
  			*timeout = timespec64_to_timespec(
  					timespec64_sub(end_time, timeout64));
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
  			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...
2302
  		cond_resched();
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2303
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2304
  	if (err == 0)
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2305
2306
2307
2308
2309
2310
  		goto out_put;
  
  	if (datagrams == 0) {
  		datagrams = err;
  		goto out_put;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2311

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2312
2313
2314
2315
2316
  	/*
  	 * 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...
2317
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2318
2319
2320
2321
  		 * ... 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...
2322
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2323
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2324
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2325
2326
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2327

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2328
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2329
  }
1255e2690   Dominik Brodowski   net: socket: add ...
2330
2331
2332
  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...
2333
2334
2335
  {
  	int datagrams;
  	struct timespec timeout_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2336
2337
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
  	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 ...
2352
2353
2354
2355
2356
2357
  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...
2358
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2359
2360
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
228e548e6   Anton Blanchard   net: Add sendmmsg...
2361
  static const unsigned char nargs[21] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2362
2363
2364
  	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...
2365
  	AL(4), AL(5), AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2366
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2367
2368
2369
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2370
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2371
2372
2373
   *
   *	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...
2374
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2375
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2376
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2377
  {
2950fa9d3   Chen Gang   kernel: audit: be...
2378
  	unsigned long a[AUDITSC_ARGS];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2379
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2380
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2381
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2382

228e548e6   Anton Blanchard   net: Add sendmmsg...
2383
  	if (call < 1 || call > SYS_SENDMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2384
  		return -EINVAL;
47379052b   Arjan van de Ven   net: Add explicit...
2385
2386
2387
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2388
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2389
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2390
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2391

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
2396
2397
2398
2399
2400
  	a0 = a[0];
  	a1 = a[1];
  
  	switch (call) {
  	case SYS_SOCKET:
9d6a15c3f   Dominik Brodowski   net: socket: add ...
2401
  		err = __sys_socket(a0, a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2402
2403
  		break;
  	case SYS_BIND:
a87d35d87   Dominik Brodowski   net: socket: add ...
2404
  		err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2405
2406
  		break;
  	case SYS_CONNECT:
1387c2c2f   Dominik Brodowski   net: socket: add ...
2407
  		err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2408
2409
  		break;
  	case SYS_LISTEN:
25e290eed   Dominik Brodowski   net: socket: add ...
2410
  		err = __sys_listen(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2411
2412
  		break;
  	case SYS_ACCEPT:
4541e8056   Dominik Brodowski   net: socket: add ...
2413
2414
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2415
2416
2417
  		break;
  	case SYS_GETSOCKNAME:
  		err =
8882a107b   Dominik Brodowski   net: socket: add ...
2418
2419
  		    __sys_getsockname(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2420
2421
2422
  		break;
  	case SYS_GETPEERNAME:
  		err =
b21c8f838   Dominik Brodowski   net: socket: add ...
2423
2424
  		    __sys_getpeername(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2425
2426
  		break;
  	case SYS_SOCKETPAIR:
6debc8d83   Dominik Brodowski   net: socket: add ...
2427
  		err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2428
2429
  		break;
  	case SYS_SEND:
f3bf896b1   Dominik Brodowski   net: socket: repl...
2430
2431
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   NULL, 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2432
2433
  		break;
  	case SYS_SENDTO:
211b634b7   Dominik Brodowski   net: socket: add ...
2434
2435
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   (struct sockaddr __user *)a[4], a[5]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2436
2437
  		break;
  	case SYS_RECV:
d27e9afc6   Dominik Brodowski   net: socket: repl...
2438
2439
  		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				     NULL, NULL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2440
2441
  		break;
  	case SYS_RECVFROM:
7a09e1eb9   Dominik Brodowski   net: socket: add ...
2442
2443
2444
  		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...
2445
2446
  		break;
  	case SYS_SHUTDOWN:
005a1aeac   Dominik Brodowski   net: socket: add ...
2447
  		err = __sys_shutdown(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2448
2449
  		break;
  	case SYS_SETSOCKOPT:
cc36dca0d   Dominik Brodowski   net: socket: add ...
2450
2451
  		err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
  				       a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2452
2453
2454
  		break;
  	case SYS_GETSOCKOPT:
  		err =
13a2d70e2   Dominik Brodowski   net: socket: add ...
2455
2456
  		    __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
  				     (int __user *)a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2457
2458
  		break;
  	case SYS_SENDMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2459
2460
  		err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2461
  		break;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2462
  	case SYS_SENDMMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2463
2464
  		err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
  				     a[3], true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2465
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2466
  	case SYS_RECVMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2467
2468
  		err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2469
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2470
  	case SYS_RECVMMSG:
1255e2690   Dominik Brodowski   net: socket: add ...
2471
2472
  		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...
2473
  		break;
de11defeb   Ulrich Drepper   reintroduce accept4
2474
  	case SYS_ACCEPT4:
4541e8056   Dominik Brodowski   net: socket: add ...
2475
2476
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2477
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2478
2479
2480
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2481
2482
2483
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2484
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2485

55737fda0   Stephen Hemminger   [NET]: socket fam...
2486
2487
2488
2489
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2490
2491
   *	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...
2492
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2493
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2494
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2495
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496
2497
2498
2499
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2500
2501
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2502
2503
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2504
2505
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2506
2507
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2508
2509
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2510
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2511
2512
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2513
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2514
2515
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2516
2517
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2518
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2519

55737fda0   Stephen Hemminger   [NET]: socket fam...
2520
2521
2522
2523
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2524
2525
   *	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...
2526
2527
2528
2529
2530
2531
   *	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
2532
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2533
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2534
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2535
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2536

55737fda0   Stephen Hemminger   [NET]: socket fam...
2537
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2538
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2539
2540
2541
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2542
2543
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2544
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2545
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2546

bf2ae2e4b   Xin Long   sock_diag: reques...
2547
2548
2549
2550
  bool sock_is_registered(int family)
  {
  	return family < NPROTO && rcu_access_pointer(net_families[family]);
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2551
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2552
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2553
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2554
2555
2556
2557
2558
2559
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2560

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2561
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2562
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2563
2564
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2565
2566
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2567
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2568
2569
2570
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2571
2572
2573
2574
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
  		goto out_fs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2575
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2576
2577
2578
2579
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2580
2581
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2582
2583
2584
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2585
2586
2587
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2588
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2589

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

b3e19d924   Nick Piggin   fs: scale mntget/...
2592
2593
2594
2595
2596
2597
2598
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
  out_fs:
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2599
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2600
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2601
2602
2603
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
648845ab7   Tonghao Zhang   sock: Move the so...
2604
2605
2606
  	seq_printf(seq, "sockets: used %d
  ",
  		   sock_inuse_get(seq->private));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2607
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2608
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2609

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2610
  #ifdef CONFIG_COMPAT
6b96018b2   Arnd Bergmann   compat: move sock...
2611
  static int do_siocgstamp(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2612
  			 unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2613
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2614
2615
2616
2617
2618
  	mm_segment_t old_fs = get_fs();
  	struct timeval ktv;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2619
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
7a229387d   Arnd Bergmann   net: copy socket ...
2620
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2621
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2622
  		err = compat_put_timeval(&ktv, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2623

7a229387d   Arnd Bergmann   net: copy socket ...
2624
2625
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2626
  static int do_siocgstampns(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2627
  			   unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2628
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2629
2630
2631
2632
2633
  	mm_segment_t old_fs = get_fs();
  	struct timespec kts;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2634
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
7a229387d   Arnd Bergmann   net: copy socket ...
2635
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2636
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2637
  		err = compat_put_timespec(&kts, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2638

7a229387d   Arnd Bergmann   net: copy socket ...
2639
2640
  	return err;
  }
36fd633ec   Al Viro   net: separate SIO...
2641
  static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2642
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2643
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2644
  	struct ifconf ifc;
7a229387d   Arnd Bergmann   net: copy socket ...
2645
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2646
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2647
  		return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
2648
2649
  	ifc.ifc_len = ifc32.ifc_len;
  	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
7a229387d   Arnd Bergmann   net: copy socket ...
2650

36fd633ec   Al Viro   net: separate SIO...
2651
2652
2653
  	rtnl_lock();
  	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
  	rtnl_unlock();
7a229387d   Arnd Bergmann   net: copy socket ...
2654
2655
  	if (err)
  		return err;
36fd633ec   Al Viro   net: separate SIO...
2656
  	ifc32.ifc_len = ifc.ifc_len;
6b96018b2   Arnd Bergmann   compat: move sock...
2657
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2658
2659
2660
2661
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2662
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2663
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2664
2665
  	struct compat_ethtool_rxnfc __user *compat_rxnfc;
  	bool convert_in = false, convert_out = false;
44c02a2c3   Al Viro   dev_ioctl(): move...
2666
2667
2668
  	size_t buf_size = 0;
  	struct ethtool_rxnfc __user *rxnfc = NULL;
  	struct ifreq ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2669
2670
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2671
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2672
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2673

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

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2677
2678
2679
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2680
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
  	/* 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...
2698
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2699
2700
2701
  		convert_out = true;
  		/* fall through */
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2702
2703
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
44c02a2c3   Al Viro   dev_ioctl(): move...
2704
  		rxnfc = compat_alloc_user_space(buf_size);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2705
2706
  		break;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2707
  	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2708
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2709
  	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
7a229387d   Arnd Bergmann   net: copy socket ...
2710

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2711
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2712
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2713
2714
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2715
2716
2717
2718
  		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...
2719
2720
2721
2722
2723
2724
2725
  		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...
2726
2727
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2728
2729
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2730
2731
  				 (void __user *)(&rxnfc->fs.location + 1) -
  				 (void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2732
2733
2734
2735
  		    copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt,
  				 sizeof(rxnfc->rule_cnt)))
  			return -EFAULT;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2736
  	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2737
2738
2739
2740
2741
  	if (ret)
  		return ret;
  
  	if (convert_out) {
  		if (copy_in_user(compat_rxnfc, rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
2742
2743
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2744
2745
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2746
2747
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
  		    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 ...
2773
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2774
2775
  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
  {
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2776
  	compat_uptr_t uptr32;
44c02a2c3   Al Viro   dev_ioctl(): move...
2777
2778
2779
  	struct ifreq ifr;
  	void __user *saved;
  	int err;
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2780

44c02a2c3   Al Viro   dev_ioctl(): move...
2781
  	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2782
2783
2784
2785
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2786
2787
  	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
  	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
7a229387d   Arnd Bergmann   net: copy socket ...
2788

44c02a2c3   Al Viro   dev_ioctl(): move...
2789
2790
2791
2792
2793
  	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...
2794
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2795
  	return err;
7a229387d   Arnd Bergmann   net: copy socket ...
2796
  }
590d4693f   Ben Hutchings   net/compat: Merge...
2797
2798
  /* 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...
2799
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
2800
  {
44c02a2c3   Al Viro   dev_ioctl(): move...
2801
  	struct ifreq ifreq;
7a229387d   Arnd Bergmann   net: copy socket ...
2802
  	u32 data32;
44c02a2c3   Al Viro   dev_ioctl(): move...
2803
  	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2804
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2805
  	if (get_user(data32, &u_ifreq32->ifr_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2806
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2807
  	ifreq.ifr_data = compat_ptr(data32);
7a229387d   Arnd Bergmann   net: copy socket ...
2808

44c02a2c3   Al Viro   dev_ioctl(): move...
2809
  	return dev_ioctl(net, cmd, &ifreq, NULL);
7a229387d   Arnd Bergmann   net: copy socket ...
2810
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
2811
2812
2813
2814
2815
  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...
2816
2817
2818
2819
  	int err;
  
  	uifmap32 = &uifr32->ifr_ifru.ifru_map;
  	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2820
2821
2822
2823
2824
2825
  	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...
2826
2827
  	if (err)
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2828
  	err = dev_ioctl(net, cmd, &ifr, NULL);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2829
2830
2831
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2832
2833
2834
2835
2836
2837
  		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...
2838
2839
2840
2841
2842
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2843
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2844
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
2845
2846
2847
  	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...
2848
2849
2850
2851
2852
2853
2854
  	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 ...
2855
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2856
2857
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
  	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...
2873
2874
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2875
2876
2877
2878
2879
2880
2881
2882
  {
  	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...
2883
2884
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2885
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2886
  			3 * sizeof(struct in6_addr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2887
2888
2889
2890
2891
2892
2893
  		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 ...
2894
2895
2896
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
2897
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2898
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2899
  					3 * sizeof(struct sockaddr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2900
2901
2902
2903
2904
2905
  		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 ...
2906
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2907
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
c3f52ae6a   stephen hemminger   socket: suppress ...
2908
2909
  			r4.rt_dev = (char __user __force *)devname;
  			devname[15] = 0;
7a229387d   Arnd Bergmann   net: copy socket ...
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2920
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2921
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2922
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2923
2924
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
2925
2926
2927
2928
2929
  	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...
2930
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
2931
   */
6b96018b2   Arnd Bergmann   compat: move sock...
2932
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2933
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2934
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
2935

6b96018b2   Arnd Bergmann   compat: move sock...
2936
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
2937
2938
2939
2940
2941
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2942
2943
2944
2945
2946
2947
  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 ...
2948

6b96018b2   Arnd Bergmann   compat: move sock...
2949
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
2950
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2951
2952
2953
2954
2955
  
  	switch (cmd) {
  	case SIOCSIFBR:
  	case SIOCGIFBR:
  		return old_bridge_ioctl(argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2956
  	case SIOCGIFCONF:
36fd633ec   Al Viro   net: separate SIO...
2957
  		return compat_dev_ifconf(net, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2958
2959
  	case SIOCETHTOOL:
  		return ethtool_ioctl(net, argp);
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2960
2961
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2962
2963
2964
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2965
2966
2967
2968
2969
2970
2971
  	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...
2972
2973
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2974
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
2975
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
2976
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
  
  	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...
2988
  	case SIOCGSKNS:
6b96018b2   Arnd Bergmann   compat: move sock...
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
  		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...
3004
3005
3006
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
3007
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
  	case SIOCGIFBRDADDR:
  	case SIOCSIFBRDADDR:
  	case SIOCGIFDSTADDR:
  	case SIOCSIFDSTADDR:
  	case SIOCGIFNETMASK:
  	case SIOCSIFNETMASK:
  	case SIOCSIFPFLAGS:
  	case SIOCGIFPFLAGS:
  	case SIOCGIFTXQLEN:
  	case SIOCSIFTXQLEN:
  	case SIOCBRADDIF:
  	case SIOCBRDELIF:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3020
3021
3022
3023
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
6b96018b2   Arnd Bergmann   compat: move sock...
3024
3025
3026
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
6b96018b2   Arnd Bergmann   compat: move sock...
3027
  	case SIOCATMARK:
f92d4fc95   Al Viro   kill bond_ioctl()
3028
3029
3030
3031
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
4cf808e7a   Al Viro   kill dev_ifname32()
3032
  	case SIOCGIFNAME:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3033
3034
  		return sock_do_ioctl(net, sock, cmd, arg);
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
3035
3036
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3037

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

9b2c45d47   Denys Vlasenko   net: make getname...
3102
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3103
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3104
  	return sock->ops->getname(sock, addr, 0);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3105
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3106
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3107

9b2c45d47   Denys Vlasenko   net: make getname...
3108
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3109
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3110
  	return sock->ops->getname(sock, addr, 1);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3111
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3112
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3113
3114
3115
3116
3117
  
  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...
3118
3119
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3120
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3121
3122
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3123
3124
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3125
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3126
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3127
3128
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3129
3130
3131
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3132
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3133
3134
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
3135
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3136
3137
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3138
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3139
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3140
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3141
3142
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3143
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3144
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3145
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3146
3147
3148
3149
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3150
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3151
3152
3153
3154
3155
3156
3157
3158
3159
  
  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...
3160
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3161

306b13eb3   Tom Herbert   proto_ops: Add lo...
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
  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...
3174
3175
3176
3177
  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...
3178
  EXPORT_SYMBOL(kernel_sock_shutdown);
113c30759   R. Parameswaran   New kernel functi...
3179
3180
3181
3182
  
  /* 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 ...
3183
   * on at the socket. Assumes that the caller has a lock on the socket.
113c30759   R. Parameswaran   New kernel functi...
3184
3185
3186
3187
3188
3189
   */
  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...
3190
3191
3192
3193
3194
3195
3196
  #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...
3197
3198
3199
3200
3201
  	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...
3202
  						sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3203
3204
3205
3206
3207
3208
3209
3210
3211
  		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...
3212
  							  sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3213
3214
3215
3216
3217
3218
3219
3220
3221
  		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);