Blame view

net/socket.c 84.8 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>
45c8178cf   Jeremy Cline   net: socket: fix ...
91
  #include <linux/nospec.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92

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

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

8ae5e030f   Al Viro   net: switch socke...
115
116
  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...
117
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
121
  
  static int sock_close(struct inode *inode, struct file *file);
  static unsigned int 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,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
  	.poll =		sock_poll,
  	.unlocked_ioctl = sock_ioctl,
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
145
146
147
  #ifdef CONFIG_COMPAT
  	.compat_ioctl = compat_sock_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  	.mmap =		sock_mmap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
  	.release =	sock_close,
  	.fasync =	sock_fasync,
5274f052e   Jens Axboe   [PATCH] Introduce...
151
152
  	.sendpage =	sock_sendpage,
  	.splice_write = generic_splice_sendpage,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
153
  	.splice_read =	sock_splice_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
158
  };
  
  /*
   *	The protocol list. Each protocol is registered in here.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  static DEFINE_SPINLOCK(net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
160
  static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161

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

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

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

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

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

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

600e17792   Masatake YAMATO   net: Providing pr...
383
384
385
386
387
388
389
  	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...
390
  	path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
284076305   Al Viro   take descriptor h...
391
392
  	if (unlikely(!path.dentry))
  		return ERR_PTR(-ENOMEM);
2c48b9c45   Al Viro   switch alloc_file...
393
  	path.mnt = mntget(sock_mnt);
39d8c1b6f   David S. Miller   [NET]: Do not los...
394

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

2c48b9c45   Al Viro   switch alloc_file...
397
  	file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
398
  		  &socket_file_ops);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
399
  	if (IS_ERR(file)) {
cc3808f8c   Al Viro   switch sock_alloc...
400
  		/* drop dentry, keep inode */
c5ef60352   David Howells   VFS: net/: d_inod...
401
  		ihold(d_inode(path.dentry));
2c48b9c45   Al Viro   switch alloc_file...
402
  		path_put(&path);
39b652527   Anatol Pomozov   fs: Preserve erro...
403
  		return file;
cc3808f8c   Al Viro   switch sock_alloc...
404
405
406
  	}
  
  	sock->file = file;
77d272005   Ulrich Drepper   flag parameters: ...
407
  	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
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
417
418
  	int fd = get_unused_fd_flags(flags);
  	if (unlikely(fd < 0))
  		return fd;
39d8c1b6f   David S. Miller   [NET]: Do not los...
419

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

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

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

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

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

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

19e8d69c5   Alex Shi   net: replace perc...
549
  	this_cpu_add(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
  	return sock;
  }
f4a00aacd   Tom Herbert   net: Make sock_al...
552
  EXPORT_SYMBOL(sock_alloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553

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

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

19e8d69c5   Alex Shi   net: replace perc...
579
  	this_cpu_sub(sockets_in_use, 1);
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
  }
91717ffc9   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
917
918
919
920
921
  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.
  	 */
  	if (err == -ENOIOCTLCMD)
  		err = dev_ioctl(net, cmd, argp);
  
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
923
924
925
  /*
   *	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.
   */
c62cce2ca   Andrey Vagin   net: add an ioctl...
926
927
928
929
  static struct ns_common *get_net_ns(struct ns_common *ns)
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
930
931
932
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
  	struct socket *sock;
881d966b4   Eric W. Biederman   [NET]: Make the d...
933
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
936
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937

b69aee04f   Eric Dumazet   [NET]: Use file->...
938
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
939
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
940
  	net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
942
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  	} else
3d23e349d   Johannes Berg   wext: refactor
944
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
946
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947
  	} else
3d23e349d   Johannes Berg   wext: refactor
948
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
949
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
952
953
954
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
393cc3f51   Jiri Slaby   fs/fcntl: f_setow...
955
  			err = f_setown(sock->file, pid, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
957
958
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
959
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
960
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
962
963
964
965
966
967
968
  			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: ...
969
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
970
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
971
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
972
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
974
975
976
977
978
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
979
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
981
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
982
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984
985
986
987
988
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
989
990
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
992
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
  			break;
c62cce2ca   Andrey Vagin   net: add an ioctl...
994
995
996
997
998
999
1000
  		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
1001
  		default:
6b96018b2   Arnd Bergmann   compat: move sock...
1002
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1004
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
1006
1007
1008
1009
1010
1011
  	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...
1012

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1013
1014
1015
1016
1017
1018
1019
1020
1021
  	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
1022
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1023
1024
1025
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
1027
1028
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1029
1030
1031
1032
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1034
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
1036
  
  /* No kernel lock held - perfect */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1037
  static unsigned int sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1038
  {
cbf55001b   Eliezer Tamir   net: rename low l...
1039
  	unsigned int busy_flag = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
1041
1042
  	struct socket *sock;
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1043
  	 *      We can't return errors to poll, so it's either yes or no.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
  	 */
b69aee04f   Eric Dumazet   [NET]: Use file->...
1045
  	sock = file->private_data;
2d48d67fa   Eliezer Tamir   net: poll/select ...
1046

cbf55001b   Eliezer Tamir   net: rename low l...
1047
  	if (sk_can_busy_loop(sock->sk)) {
2d48d67fa   Eliezer Tamir   net: poll/select ...
1048
  		/* this socket can poll_ll so tell the system call */
cbf55001b   Eliezer Tamir   net: rename low l...
1049
  		busy_flag = POLL_BUSY_LOOP;
2d48d67fa   Eliezer Tamir   net: poll/select ...
1050
1051
  
  		/* once, only if requested by syscall */
cbf55001b   Eliezer Tamir   net: rename low l...
1052
1053
  		if (wait && (wait->_key & POLL_BUSY_LOOP))
  			sk_busy_loop(sock->sk, 1);
2d48d67fa   Eliezer Tamir   net: poll/select ...
1054
  	}
cbf55001b   Eliezer Tamir   net: rename low l...
1055
  	return busy_flag | sock->ops->poll(file, sock, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1057
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1058
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
1059
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
1062
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1063
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
  {
91717ffc9   Cong Wang   socket: close rac...
1065
  	__sock_release(SOCKET_I(inode), inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  	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...
1077
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1078
1079
1080
1081
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1082
1083
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
eaefd1105   Eric Dumazet   net: add __rcu an...
1084
  	struct socket_wq *wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085

989a29792   Eric Dumazet   fasync: RCU and f...
1086
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1087
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1088
1089
  
  	lock_sock(sk);
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
1090
  	wq = rcu_dereference_protected(sock->wq, lockdep_sock_is_held(sk));
eaefd1105   Eric Dumazet   net: add __rcu an...
1091
  	fasync_helper(fd, filp, on, &wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092

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

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

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1103
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1105
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1107

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1127
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128

721db93a5   Pavel Emelyanov   net: Export __soc...
1129
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1130
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
1132
1133
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1134
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
1136
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1137
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
  	 */
  	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 ...
1150
1151
1152
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
1154
1155
1156
1157
1158
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1159

55737fda0   Stephen Hemminger   [NET]: socket fam...
1160
1161
1162
1163
1164
1165
1166
  	/*
  	 *	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_...
1167
1168
  		net_warn_ratelimited("socket: no more sockets
  ");
55737fda0   Stephen Hemminger   [NET]: socket fam...
1169
1170
1171
1172
1173
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1174
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1175
1176
1177
  	/* 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
1178
1179
1180
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
190683a9d   Eric Dumazet   net: net_families...
1181
  	if (rcu_access_pointer(net_families[family]) == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1182
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1184
1185
1186
1187
1188
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1189
1190
1191
1192
1193
  
  	/*
  	 * 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...
1194
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1195
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1196
1197
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1198
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1199
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1201

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1202
1203
1204
1205
  	/*
  	 * 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...
1206
1207
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1208
1209
1210
1211
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1212
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1213
1214
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1215
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1216
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217

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

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

3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1247
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1248
1249
1250
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1251
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1252
1253
1254
1255
1256
  	/* 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: ...
1257
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1258
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1259
1260
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1261

aaca0bdca   Ulrich Drepper   flag parameters: ...
1262
1263
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
1265
1266
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
  		goto out;
77d272005   Ulrich Drepper   flag parameters: ...
1267
  	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
  	if (retval < 0)
  		goto out_release;
  
  out:
  	/* It may be already another descriptor 8) Not kernel problem. */
  	return retval;
  
  out_release:
  	sock_release(sock);
  	return retval;
  }
  
  /*
   *	Create a pair of connected sockets.
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1283
1284
  SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
  		int __user *, usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1285
1286
1287
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1288
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1289
1290
1291
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1292
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1293
1294
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1295

aaca0bdca   Ulrich Drepper   flag parameters: ...
1296
1297
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
  	/*
  	 * Obtain the first socket and check if the underlying protocol
  	 * supports the socketpair call.
  	 */
  
  	err = sock_create(family, type, protocol, &sock1);
  	if (err < 0)
  		goto out;
  
  	err = sock_create(family, type, protocol, &sock2);
  	if (err < 0)
  		goto out_release_1;
  
  	err = sock1->ops->socketpair(sock1, sock2);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1312
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1313
  		goto out_release_both;
284076305   Al Viro   take descriptor h...
1314
  	fd1 = get_unused_fd_flags(flags);
bf3c23d17   David S. Miller   [NET]: Fix error ...
1315
1316
  	if (unlikely(fd1 < 0)) {
  		err = fd1;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1317
  		goto out_release_both;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1318
  	}
d73aa2867   Yann Droneaud   net: handle error...
1319

284076305   Al Viro   take descriptor h...
1320
  	fd2 = get_unused_fd_flags(flags);
198de4d7a   Al Viro   reorder alloc_fd/...
1321
1322
  	if (unlikely(fd2 < 0)) {
  		err = fd2;
d73aa2867   Yann Droneaud   net: handle error...
1323
  		goto out_put_unused_1;
284076305   Al Viro   take descriptor h...
1324
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1325
  	newfile1 = sock_alloc_file(sock1, flags, NULL);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1326
  	if (IS_ERR(newfile1)) {
284076305   Al Viro   take descriptor h...
1327
  		err = PTR_ERR(newfile1);
d73aa2867   Yann Droneaud   net: handle error...
1328
  		goto out_put_unused_both;
284076305   Al Viro   take descriptor h...
1329
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1330
  	newfile2 = sock_alloc_file(sock2, flags, NULL);
284076305   Al Viro   take descriptor h...
1331
1332
  	if (IS_ERR(newfile2)) {
  		err = PTR_ERR(newfile2);
d73aa2867   Yann Droneaud   net: handle error...
1333
  		goto out_fput_1;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1334
  	}
d73aa2867   Yann Droneaud   net: handle error...
1335
1336
1337
1338
1339
1340
1341
  	err = put_user(fd1, &usockvec[0]);
  	if (err)
  		goto out_fput_both;
  
  	err = put_user(fd2, &usockvec[1]);
  	if (err)
  		goto out_fput_both;
157cf649a   Al Viro   sanitize audit_fd...
1342
  	audit_fd_pair(fd1, fd2);
d73aa2867   Yann Droneaud   net: handle error...
1343

db3495099   Al Viro   [PATCH] AUDIT_FD_...
1344
1345
  	fd_install(fd1, newfile1);
  	fd_install(fd2, newfile2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1346
1347
1348
  	/* fd1 and fd2 may be already another descriptors.
  	 * Not kernel problem.
  	 */
d73aa2867   Yann Droneaud   net: handle error...
1349
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350

d73aa2867   Yann Droneaud   net: handle error...
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
  out_fput_both:
  	fput(newfile2);
  	fput(newfile1);
  	put_unused_fd(fd2);
  	put_unused_fd(fd1);
  	goto out;
  
  out_fput_1:
  	fput(newfile1);
  	put_unused_fd(fd2);
  	put_unused_fd(fd1);
  	sock_release(sock2);
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1364

d73aa2867   Yann Droneaud   net: handle error...
1365
1366
1367
1368
  out_put_unused_both:
  	put_unused_fd(fd2);
  out_put_unused_1:
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
  out_release_both:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1370
  	sock_release(sock2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
  out_release_1:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1372
  	sock_release(sock1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1373
1374
1375
  out:
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1376
1377
1378
1379
1380
1381
1382
  /*
   *	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).
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1383
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1384
1385
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1386
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1387
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1388

89bddce58   Stephen Hemminger   [NET] socket: cod...
1389
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1390
  	if (sock) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1391
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1392
1393
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1394
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1395
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1396
1397
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1398
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1399
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1401
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1402
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403
1404
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405
1406
1407
1408
1409
  /*
   *	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.
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1410
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1411
1412
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1413
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1414
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1415
1416
1417
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1418
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1419
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1420
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1421
1422
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1423
1424
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1426
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1427
1428
1429
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
  /*
   *	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
   *	clean when we restucture accept also.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1441
1442
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443
1444
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1445
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1446
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1447
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448

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

a79af59ef   Frank Filz   [NET]: Fix module...
1484
1485
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1486
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1487

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1509
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
1511
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1512
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1513
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1514
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
  	goto out_put;
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1517
1518
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1519
  {
de11defeb   Ulrich Drepper   reintroduce accept4
1520
  	return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1521
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
  /*
   *	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.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1533
1534
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
1536
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1537
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1538
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1539

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1540
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1541
1542
  	if (!sock)
  		goto out;
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1543
  	err = move_addr_to_kernel(uservaddr, addrlen, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
1545
  	if (err < 0)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1546
  	err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1547
  	    security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1548
1549
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1550
  	err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1551
1552
  				 sock->file->f_flags);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1553
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
1555
1556
1557
1558
1559
1560
1561
  out:
  	return err;
  }
  
  /*
   *	Get the local address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1562
1563
  SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1564
1565
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1566
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1567
  	int len, err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1568

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1569
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1570
1571
1572
1573
1574
1575
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1576
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
1578
  	if (err)
  		goto out_put;
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1579
  	err = move_addr_to_user(&address, len, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1580
1581
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1582
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
1584
1585
1586
1587
1588
1589
1590
  out:
  	return err;
  }
  
  /*
   *	Get the remote address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1591
1592
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1593
1594
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1595
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1596
  	int len, err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1597

89bddce58   Stephen Hemminger   [NET] socket: cod...
1598
1599
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1600
1601
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1602
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603
1604
  			return err;
  		}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1605
  		err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1606
  		    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1607
  				       1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1608
  		if (!err)
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1609
  			err = move_addr_to_user(&address, len, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1610
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1611
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
1613
1614
1615
1616
1617
1618
1619
1620
  	}
  	return err;
  }
  
  /*
   *	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.
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1621
  SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1622
  		unsigned int, flags, struct sockaddr __user *, addr,
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1623
  		int, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1624
1625
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1626
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627
1628
1629
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1630
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1631

602bd0e90   Al Viro   net: switch sendt...
1632
1633
1634
  	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1635
1636
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1637
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1638

89bddce58   Stephen Hemminger   [NET] socket: cod...
1639
  	msg.msg_name = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1640
1641
1642
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1643
  	if (addr) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1644
  		err = move_addr_to_kernel(addr, addr_len, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1645
1646
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1647
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1648
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1649
1650
1651
1652
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
d8725c86a   Al Viro   get rid of the si...
1653
  	err = sock_sendmsg(sock, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654

89bddce58   Stephen Hemminger   [NET] socket: cod...
1655
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1656
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1657
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1658
1659
1660
1661
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1662
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1664
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1665
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1666
1667
1668
1669
1670
  {
  	return sys_sendto(fd, buff, len, flags, NULL, 0);
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1671
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
1673
1674
   *	sender. We verify the buffers are writable and if needed move the
   *	sender address from kernel to user space.
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1675
  SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
95c961747   Eric Dumazet   net: cleanup unsi...
1676
  		unsigned int, flags, struct sockaddr __user *, addr,
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1677
  		int __user *, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
1679
1680
1681
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1682
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1683
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1684
  	int fput_needed;
602bd0e90   Al Viro   net: switch sendt...
1685
1686
1687
  	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1688
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1690
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691

89bddce58   Stephen Hemminger   [NET] socket: cod...
1692
1693
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1694
1695
1696
1697
  	/* 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...
1698
  	msg.msg_iocb = NULL;
9f138fa60   Alexander Potapenko   net: initialize m...
1699
  	msg.msg_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1700
1701
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1702
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1703

89bddce58   Stephen Hemminger   [NET] socket: cod...
1704
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1705
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1706
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1707
1708
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1710
1711
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1712
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
1714
1715
1716
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1717
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1719
1720
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1721
1722
1723
1724
1725
1726
1727
1728
  {
  	return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
  }
  
  /*
   *	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.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1729
1730
  SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1732
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
1734
1735
1736
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1737
1738
1739
1740
  
  	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...
1741
1742
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1743
1744
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1745
1746
1747
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1748
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1749
1750
1751
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1752
1753
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1754
1755
1756
1757
1758
1759
1760
1761
  	}
  	return err;
  }
  
  /*
   *	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.
   */
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1762
1763
  SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int __user *, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1764
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1765
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1766
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1767
1768
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1769
1770
1771
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1772
1773
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1774
1775
1776
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1778
1779
1780
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1781
1782
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
1785
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1786
1787
1788
  /*
   *	Shutdown a socket.
   */
754fe8d29   Heiko Carstens   [CVE-2009-0029] S...
1789
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1790
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1791
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1792
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1793
1794
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1795
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1796
1797
1798
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
1800
1801
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1802
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1803
1804
1805
1806
1807
   * 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...
1808
1809
1810
1811
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
da1842849   Al Viro   net: switch impor...
1812
1813
1814
1815
  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...
1816
  {
ffb07550c   Al Viro   copy_msghdr_from_...
1817
  	struct user_msghdr msg;
08adb7dab   Al Viro   fold verify_iovec...
1818
  	ssize_t err;
ffb07550c   Al Viro   copy_msghdr_from_...
1819
  	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
1661bf364   Dan Carpenter   net: heap overflo...
1820
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
1821

864d96642   Paolo Abeni   net/socket: fix t...
1822
  	kmsg->msg_control = (void __force *)msg.msg_control;
ffb07550c   Al Viro   copy_msghdr_from_...
1823
1824
1825
1826
1827
  	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...
1828
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
1829
1830
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
1831
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
1832
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
1833
1834
  
  	if (save_addr)
ffb07550c   Al Viro   copy_msghdr_from_...
1835
  		*save_addr = msg.msg_name;
08adb7dab   Al Viro   fold verify_iovec...
1836

ffb07550c   Al Viro   copy_msghdr_from_...
1837
  	if (msg.msg_name && kmsg->msg_namelen) {
08adb7dab   Al Viro   fold verify_iovec...
1838
  		if (!save_addr) {
864d96642   Paolo Abeni   net/socket: fix t...
1839
1840
  			err = move_addr_to_kernel(msg.msg_name,
  						  kmsg->msg_namelen,
08adb7dab   Al Viro   fold verify_iovec...
1841
1842
1843
1844
1845
1846
1847
1848
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
ffb07550c   Al Viro   copy_msghdr_from_...
1849
  	if (msg.msg_iovlen > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
1850
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
1851
  	kmsg->msg_iocb = NULL;
ffb07550c   Al Viro   copy_msghdr_from_...
1852
1853
  	return import_iovec(save_addr ? READ : WRITE,
  			    msg.msg_iov, msg.msg_iovlen,
da1842849   Al Viro   net: switch impor...
1854
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
1661bf364   Dan Carpenter   net: heap overflo...
1855
  }
666547ff5   Al Viro   separate kernel- ...
1856
  static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
1857
  			 struct msghdr *msg_sys, unsigned int flags,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1858
1859
  			 struct used_address *used_address,
  			 unsigned int allowed_msghdr_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1861
1862
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1863
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1864
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
b9d717a7b   Alex Williamson   [NET]: Make sure ...
1865
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
846cc1231   Amit Kushwaha   net: socket: pref...
1866
  				__aligned(sizeof(__kernel_size_t));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1867
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
1869
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
1870
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1871

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

084493200   Al Viro   {compat_,}verify_...
1874
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
1875
  		err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
084493200   Al Viro   {compat_,}verify_...
1876
  	else
08adb7dab   Al Viro   fold verify_iovec...
1877
  		err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1878
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
1879
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
1881
  
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1882
  	if (msg_sys->msg_controllen > INT_MAX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
  		goto out_freeiov;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1884
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1885
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1887
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
1888
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1889
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
1891
  		if (err)
  			goto out_freeiov;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1892
1893
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1894
  	} else if (ctl_len) {
ac4340fc3   David S. Miller   net: Assert at bu...
1895
1896
  		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
  			     CMSG_ALIGN(sizeof(struct cmsghdr)));
89bddce58   Stephen Hemminger   [NET] socket: cod...
1897
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1898
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1899
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1900
1901
1902
1903
  				goto out_freeiov;
  		}
  		err = -EFAULT;
  		/*
228e548e6   Anton Blanchard   net: Add sendmmsg...
1904
  		 * Careful! Before this, msg_sys->msg_control contains a user pointer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1905
1906
1907
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
1908
  		if (copy_from_user(ctl_buf,
228e548e6   Anton Blanchard   net: Add sendmmsg...
1909
  				   (void __user __force *)msg_sys->msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1910
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1911
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1912
  		msg_sys->msg_control = ctl_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
1914
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
1916
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1917
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
1918
1919
1920
1921
1922
1923
  	/*
  	 * 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:...
1924
1925
1926
  	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...
1927
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
1928
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1929
1930
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
1931
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1932
1933
1934
1935
1936
1937
  	/*
  	 * 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:...
1938
1939
1940
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1941
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1942
1943
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1944
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1945
1946
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  out_freeiov:
da1842849   Al Viro   net: switch impor...
1947
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1948
1949
1950
1951
1952
1953
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
666547ff5   Al Viro   separate kernel- ...
1954
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1955
1956
1957
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
1958
  	struct socket *sock;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
1959
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1960
1961
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1962
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1963

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1964
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1965
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
1968
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
1969
1970
1971
1972
1973
  {
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  	return __sys_sendmsg(fd, msg, flags);
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
  /*
   *	Linux sendmmsg interface
   */
  
  int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
  		   unsigned int flags)
  {
  	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...
1986
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
1987
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1988

98382f419   Anton Blanchard   net: Cap number o...
1989
1990
  	if (vlen > UIO_MAXIOV)
  		vlen = UIO_MAXIOV;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1991
1992
1993
1994
1995
1996
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
c71d8ebe7   Tetsuo Handa   net: Fix security...
1997
  	used_address.name_len = UINT_MAX;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1998
1999
  	entry = mmsg;
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2000
  	err = 0;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2001
  	flags |= MSG_BATCH;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2002
2003
  
  	while (datagrams < vlen) {
f092276d8   Tom Herbert   net: Add MSG_BATC...
2004
2005
  		if (datagrams == vlen - 1)
  			flags = oflags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2006
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2007
  			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2008
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2009
2010
2011
2012
2013
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2014
  			err = ___sys_sendmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2015
  					     (struct user_msghdr __user *)entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2016
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2017
2018
2019
2020
2021
2022
2023
2024
2025
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
  
  		if (err)
  			break;
  		++datagrams;
3023898b7   Soheil Hassas Yeganeh   sock: fix sendmms...
2026
2027
  		if (msg_data_left(&msg_sys))
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2028
  		cond_resched();
228e548e6   Anton Blanchard   net: Add sendmmsg...
2029
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2030
  	fput_light(sock->file, fput_needed);
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2031
2032
  	/* We only return an error if no datagrams were able to be sent */
  	if (datagrams != 0)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2033
  		return datagrams;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2034
2035
2036
2037
2038
2039
  	return err;
  }
  
  SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags)
  {
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2040
2041
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2042
2043
  	return __sys_sendmmsg(fd, mmsg, vlen, flags);
  }
666547ff5   Al Viro   separate kernel- ...
2044
  static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
2045
  			 struct msghdr *msg_sys, unsigned int flags, int nosec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2046
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2047
2048
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2049
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2050
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2051
  	unsigned long cmsg_ptr;
2da62906b   Al Viro   [net] drop 'size'...
2052
  	int len;
08adb7dab   Al Viro   fold verify_iovec...
2053
  	ssize_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054
2055
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
2056
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2057
2058
2059
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
08adb7dab   Al Viro   fold verify_iovec...
2060
  	int __user *uaddr_len = COMPAT_NAMELEN(msg);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2061

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

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2064
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
2065
  		err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov);
f3d334260   Hannes Frederic Sowa   net: rework recvm...
2066
  	else
08adb7dab   Al Viro   fold verify_iovec...
2067
  		err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2068
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
2069
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2070

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2071
2072
  	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...
2073

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2074
2075
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2076
2077
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
2078
  	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2079
2080
2081
2082
2083
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
2084
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2085
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2086
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2087
2088
2089
  		if (err < 0)
  			goto out_freeiov;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2090
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
2091
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2092
2093
2094
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2095
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2096
2097
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2098
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2099
2100
2101
2102
2103
2104
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
da1842849   Al Viro   net: switch impor...
2105
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2106
2107
2108
2109
2110
2111
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
666547ff5   Al Viro   separate kernel- ...
2112
  long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2113
2114
2115
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2116
  	struct socket *sock;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2117
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2118
2119
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2120
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2121

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2122
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2123
2124
2125
  out:
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2126
  SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2127
2128
2129
2130
2131
2132
  		unsigned int, flags)
  {
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  	return __sys_recvmsg(fd, msg, flags);
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
  /*
   *     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...
2143
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2144
  	struct msghdr msg_sys;
766b9f928   Deepa Dinamani   fs: poll/select/r...
2145
2146
  	struct timespec64 end_time;
  	struct timespec64 timeout64;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
  
  	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;
  
  	err = sock_error(sock->sk);
e623a9e9d   Maxime Jayat   net: socket: fix ...
2160
2161
  	if (err) {
  		datagrams = err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2162
  		goto out_put;
e623a9e9d   Maxime Jayat   net: socket: fix ...
2163
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2164
2165
  
  	entry = mmsg;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2166
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2167
2168
2169
2170
2171
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2172
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2173
  			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2174
2175
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2176
2177
2178
2179
2180
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2181
  			err = ___sys_recvmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2182
  					     (struct user_msghdr __user *)entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2183
2184
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2185
2186
2187
2188
2189
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2190
2191
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2192
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2193
2194
2195
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2196
  		if (timeout) {
766b9f928   Deepa Dinamani   fs: poll/select/r...
2197
2198
2199
  			ktime_get_ts64(&timeout64);
  			*timeout = timespec64_to_timespec(
  					timespec64_sub(end_time, timeout64));
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
  			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...
2213
  		cond_resched();
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2214
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2215
  	if (err == 0)
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2216
2217
2218
2219
2220
2221
  		goto out_put;
  
  	if (datagrams == 0) {
  		datagrams = err;
  		goto out_put;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2222

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2223
2224
2225
2226
2227
  	/*
  	 * 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...
2228
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2229
2230
2231
2232
  		 * ... 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...
2233
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2234
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2235
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2236
2237
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2238

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2239
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2240
2241
2242
2243
2244
2245
2246
2247
  }
  
  SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags,
  		struct timespec __user *, timeout)
  {
  	int datagrams;
  	struct timespec timeout_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2248
2249
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
  	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;
  }
  
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2266
2267
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
228e548e6   Anton Blanchard   net: Add sendmmsg...
2268
  static const unsigned char nargs[21] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2269
2270
2271
  	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...
2272
  	AL(4), AL(5), AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2273
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2274
2275
2276
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2277
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
2279
2280
   *
   *	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...
2281
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2282
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2283
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2284
  {
2950fa9d3   Chen Gang   kernel: audit: be...
2285
  	unsigned long a[AUDITSC_ARGS];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2286
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2287
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2288
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2289

228e548e6   Anton Blanchard   net: Add sendmmsg...
2290
  	if (call < 1 || call > SYS_SENDMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2291
  		return -EINVAL;
45c8178cf   Jeremy Cline   net: socket: fix ...
2292
  	call = array_index_nospec(call, SYS_SENDMMSG + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2293

47379052b   Arjan van de Ven   net: Add explicit...
2294
2295
2296
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2297
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2298
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2299
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2300

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
  	a0 = a[0];
  	a1 = a[1];
  
  	switch (call) {
  	case SYS_SOCKET:
  		err = sys_socket(a0, a1, a[2]);
  		break;
  	case SYS_BIND:
  		err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
  		break;
  	case SYS_CONNECT:
  		err = sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
  		break;
  	case SYS_LISTEN:
  		err = sys_listen(a0, a1);
  		break;
  	case SYS_ACCEPT:
de11defeb   Ulrich Drepper   reintroduce accept4
2322
2323
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
  		break;
  	case SYS_GETSOCKNAME:
  		err =
  		    sys_getsockname(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2]);
  		break;
  	case SYS_GETPEERNAME:
  		err =
  		    sys_getpeername(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2]);
  		break;
  	case SYS_SOCKETPAIR:
  		err = sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
  		break;
  	case SYS_SEND:
  		err = sys_send(a0, (void __user *)a1, a[2], a[3]);
  		break;
  	case SYS_SENDTO:
  		err = sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				 (struct sockaddr __user *)a[4], a[5]);
  		break;
  	case SYS_RECV:
  		err = sys_recv(a0, (void __user *)a1, a[2], a[3]);
  		break;
  	case SYS_RECVFROM:
  		err = sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				   (struct sockaddr __user *)a[4],
  				   (int __user *)a[5]);
  		break;
  	case SYS_SHUTDOWN:
  		err = sys_shutdown(a0, a1);
  		break;
  	case SYS_SETSOCKOPT:
  		err = sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]);
  		break;
  	case SYS_GETSOCKOPT:
  		err =
  		    sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
  				   (int __user *)a[4]);
  		break;
  	case SYS_SENDMSG:
666547ff5   Al Viro   separate kernel- ...
2365
  		err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2366
  		break;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2367
2368
2369
  	case SYS_SENDMMSG:
  		err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2370
  	case SYS_RECVMSG:
666547ff5   Al Viro   separate kernel- ...
2371
  		err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2372
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2373
2374
2375
2376
  	case SYS_RECVMMSG:
  		err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
  				   (struct timespec __user *)a[4]);
  		break;
de11defeb   Ulrich Drepper   reintroduce accept4
2377
2378
2379
  	case SYS_ACCEPT4:
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2380
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2381
2382
2383
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2384
2385
2386
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2387
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2388

55737fda0   Stephen Hemminger   [NET]: socket fam...
2389
2390
2391
2392
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2393
2394
   *	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...
2395
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2396
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2397
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2398
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2399
2400
2401
2402
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2403
2404
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2405
2406
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2407
2408
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2409
2410
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2411
2412
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2413
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2414
2415
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2416
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2417
2418
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2419
2420
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2421
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2422

55737fda0   Stephen Hemminger   [NET]: socket fam...
2423
2424
2425
2426
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2427
2428
   *	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...
2429
2430
2431
2432
2433
2434
   *	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
2435
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2436
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2437
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2438
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2439

55737fda0   Stephen Hemminger   [NET]: socket fam...
2440
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2441
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2442
2443
2444
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2445
2446
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2447
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2448
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2449

77d76ea31   Andi Kleen   [NET]: Small clea...
2450
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2451
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2452
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2453
2454
2455
2456
2457
2458
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2459

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2460
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2461
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2462
2463
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2464
2465
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2466
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2467
2468
2469
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2470
2471
2472
2473
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
  		goto out_fs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2475
2476
2477
2478
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2479
2480
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2481
2482
2483
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2484
2485
2486
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2487
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2488

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

b3e19d924   Nick Piggin   fs: scale mntget/...
2491
2492
2493
2494
2495
2496
2497
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
  out_fs:
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2499
  core_initcall(sock_init);	/* early initcall */
6fde36d5c   Alexei Starovoitov   bpf: introduce BP...
2500
2501
2502
2503
2504
2505
2506
2507
  static int __init jit_init(void)
  {
  #ifdef CONFIG_BPF_JIT_ALWAYS_ON
  	bpf_jit_enable = 1;
  #endif
  	return 0;
  }
  pure_initcall(jit_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2508
2509
2510
2511
2512
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
  	int cpu;
  	int counter = 0;
6f9120422   KAMEZAWA Hiroyuki   [PATCH] for_each_...
2513
  	for_each_possible_cpu(cpu)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2514
  	    counter += per_cpu(sockets_in_use, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2515
2516
2517
2518
2519
2520
2521
2522
  
  	/* It can be negative, by the way. 8) */
  	if (counter < 0)
  		counter = 0;
  
  	seq_printf(seq, "sockets: used %d
  ", counter);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2523
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2524

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2525
  #ifdef CONFIG_COMPAT
6b96018b2   Arnd Bergmann   compat: move sock...
2526
  static int do_siocgstamp(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2527
  			 unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2528
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2529
2530
2531
2532
2533
  	mm_segment_t old_fs = get_fs();
  	struct timeval ktv;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2534
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
7a229387d   Arnd Bergmann   net: copy socket ...
2535
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2536
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2537
  		err = compat_put_timeval(&ktv, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2538

7a229387d   Arnd Bergmann   net: copy socket ...
2539
2540
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2541
  static int do_siocgstampns(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2542
  			   unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2543
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2544
2545
2546
2547
2548
  	mm_segment_t old_fs = get_fs();
  	struct timespec kts;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2549
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
7a229387d   Arnd Bergmann   net: copy socket ...
2550
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2551
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2552
  		err = compat_put_timespec(&kts, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2553

7a229387d   Arnd Bergmann   net: copy socket ...
2554
2555
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2556
  static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2557
2558
2559
2560
2561
  {
  	struct ifreq __user *uifr;
  	int err;
  
  	uifr = compat_alloc_user_space(sizeof(struct ifreq));
6b96018b2   Arnd Bergmann   compat: move sock...
2562
  	if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2563
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2564
  	err = dev_ioctl(net, SIOCGIFNAME, uifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2565
2566
  	if (err)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
2567
  	if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2568
2569
2570
2571
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2572
  static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2573
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2574
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2575
2576
  	struct ifconf ifc;
  	struct ifconf __user *uifc;
6b96018b2   Arnd Bergmann   compat: move sock...
2577
  	struct compat_ifreq __user *ifr32;
7a229387d   Arnd Bergmann   net: copy socket ...
2578
2579
2580
  	struct ifreq __user *ifr;
  	unsigned int i, j;
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2581
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2582
  		return -EFAULT;
43da5f2e0   Mathias Krause   net: fix info lea...
2583
  	memset(&ifc, 0, sizeof(ifc));
7a229387d   Arnd Bergmann   net: copy socket ...
2584
2585
2586
2587
2588
2589
  	if (ifc32.ifcbuf == 0) {
  		ifc32.ifc_len = 0;
  		ifc.ifc_len = 0;
  		ifc.ifc_req = NULL;
  		uifc = compat_alloc_user_space(sizeof(struct ifconf));
  	} else {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2590
2591
  		size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
  			sizeof(struct ifreq);
7a229387d   Arnd Bergmann   net: copy socket ...
2592
2593
2594
2595
  		uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
  		ifc.ifc_len = len;
  		ifr = ifc.ifc_req = (void __user *)(uifc + 1);
  		ifr32 = compat_ptr(ifc32.ifcbuf);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2596
  		for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
6b96018b2   Arnd Bergmann   compat: move sock...
2597
  			if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2598
2599
2600
2601
2602
2603
2604
  				return -EFAULT;
  			ifr++;
  			ifr32++;
  		}
  	}
  	if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2605
  	err = dev_ioctl(net, SIOCGIFCONF, uifc);
7a229387d   Arnd Bergmann   net: copy socket ...
2606
2607
2608
2609
2610
2611
2612
2613
2614
  	if (err)
  		return err;
  
  	if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
  		return -EFAULT;
  
  	ifr = ifc.ifc_req;
  	ifr32 = compat_ptr(ifc32.ifcbuf);
  	for (i = 0, j = 0;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2615
2616
2617
  	     i + sizeof(struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
  	     i += sizeof(struct compat_ifreq), j += sizeof(struct ifreq)) {
  		if (copy_in_user(ifr32, ifr, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
  			return -EFAULT;
  		ifr32++;
  		ifr++;
  	}
  
  	if (ifc32.ifcbuf == 0) {
  		/* Translate from 64-bit structure multiple to
  		 * a 32-bit one.
  		 */
  		i = ifc.ifc_len;
6b96018b2   Arnd Bergmann   compat: move sock...
2628
  		i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
7a229387d   Arnd Bergmann   net: copy socket ...
2629
2630
2631
2632
  		ifc32.ifc_len = i;
  	} else {
  		ifc32.ifc_len = i;
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
2633
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2634
2635
2636
2637
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2638
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2639
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2640
2641
2642
2643
  	struct compat_ethtool_rxnfc __user *compat_rxnfc;
  	bool convert_in = false, convert_out = false;
  	size_t buf_size = ALIGN(sizeof(struct ifreq), 8);
  	struct ethtool_rxnfc __user *rxnfc;
7a229387d   Arnd Bergmann   net: copy socket ...
2644
  	struct ifreq __user *ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2645
2646
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2647
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2648
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2649

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

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2653
2654
2655
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2656
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
  	/* 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...
2674
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2675
2676
2677
  		convert_out = true;
  		/* fall through */
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2678
2679
2680
2681
2682
2683
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
  		break;
  	}
  
  	ifr = compat_alloc_user_space(buf_size);
954b12445   Stephen Hemminger   ethtool: fix spar...
2684
  	rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2685
2686
  
  	if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2687
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2688
2689
  	if (put_user(convert_in ? rxnfc : compat_ptr(data),
  		     &ifr->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2690
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2691
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2692
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2693
2694
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2695
2696
2697
2698
  		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...
2699
2700
2701
2702
2703
2704
2705
  		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...
2706
2707
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2708
2709
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2710
2711
  				 (void __user *)(&rxnfc->fs.location + 1) -
  				 (void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
  		    copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt,
  				 sizeof(rxnfc->rule_cnt)))
  			return -EFAULT;
  	}
  
  	ret = dev_ioctl(net, SIOCETHTOOL, ifr);
  	if (ret)
  		return ret;
  
  	if (convert_out) {
  		if (copy_in_user(compat_rxnfc, rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
2723
2724
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2725
2726
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2727
2728
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
  		    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 ...
2754
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2755
2756
2757
2758
2759
  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
  {
  	void __user *uptr;
  	compat_uptr_t uptr32;
  	struct ifreq __user *uifr;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2760
  	uifr = compat_alloc_user_space(sizeof(*uifr));
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
  	if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
  		return -EFAULT;
  
  	uptr = compat_ptr(uptr32);
  
  	if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
  		return -EFAULT;
  
  	return dev_ioctl(net, SIOCWANDEV, uifr);
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2774
2775
  static int bond_ioctl(struct net *net, unsigned int cmd,
  			 struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2776
2777
  {
  	struct ifreq kifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2778
2779
  	mm_segment_t old_fs;
  	int err;
7a229387d   Arnd Bergmann   net: copy socket ...
2780
2781
2782
2783
2784
2785
  
  	switch (cmd) {
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
6b96018b2   Arnd Bergmann   compat: move sock...
2786
  		if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2787
2788
2789
  			return -EFAULT;
  
  		old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2790
  		set_fs(KERNEL_DS);
c3f52ae6a   stephen hemminger   socket: suppress ...
2791
2792
  		err = dev_ioctl(net, cmd,
  				(struct ifreq __user __force *) &kifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2793
  		set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2794
2795
  
  		return err;
7a229387d   Arnd Bergmann   net: copy socket ...
2796
  	default:
07d106d0a   Linus Torvalds   vfs: fix up ENOIO...
2797
  		return -ENOIOCTLCMD;
ccbd6a5a4   Joe Perches   net: Remove unnec...
2798
  	}
7a229387d   Arnd Bergmann   net: copy socket ...
2799
  }
590d4693f   Ben Hutchings   net/compat: Merge...
2800
2801
  /* 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...
2802
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
2803
2804
  {
  	struct ifreq __user *u_ifreq64;
7a229387d   Arnd Bergmann   net: copy socket ...
2805
2806
2807
2808
2809
2810
2811
  	char tmp_buf[IFNAMSIZ];
  	void __user *data64;
  	u32 data32;
  
  	if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
  			   IFNAMSIZ))
  		return -EFAULT;
417c3522b   Ben Hutchings   net/compat: Fix m...
2812
  	if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2813
2814
2815
2816
  		return -EFAULT;
  	data64 = compat_ptr(data32);
  
  	u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
7a229387d   Arnd Bergmann   net: copy socket ...
2817
2818
2819
  	if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
  			 IFNAMSIZ))
  		return -EFAULT;
417c3522b   Ben Hutchings   net/compat: Fix m...
2820
  	if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2821
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2822
  	return dev_ioctl(net, cmd, u_ifreq64);
7a229387d   Arnd Bergmann   net: copy socket ...
2823
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2824
2825
  static int dev_ifsioc(struct net *net, struct socket *sock,
  			 unsigned int cmd, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2826
  {
a2116ed22   Arnd Bergmann   net/compat: fix d...
2827
  	struct ifreq __user *uifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2828
  	int err;
a2116ed22   Arnd Bergmann   net/compat: fix d...
2829
2830
2831
2832
2833
  	uifr = compat_alloc_user_space(sizeof(*uifr));
  	if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
  		return -EFAULT;
  
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
  	if (!err) {
  		switch (cmd) {
  		case SIOCGIFFLAGS:
  		case SIOCGIFMETRIC:
  		case SIOCGIFMTU:
  		case SIOCGIFMEM:
  		case SIOCGIFHWADDR:
  		case SIOCGIFINDEX:
  		case SIOCGIFADDR:
  		case SIOCGIFBRDADDR:
  		case SIOCGIFDSTADDR:
  		case SIOCGIFNETMASK:
fab2532ba   Arnd Bergmann   net, compat_ioctl...
2846
  		case SIOCGIFPFLAGS:
7a229387d   Arnd Bergmann   net: copy socket ...
2847
  		case SIOCGIFTXQLEN:
fab2532ba   Arnd Bergmann   net, compat_ioctl...
2848
2849
  		case SIOCGMIIPHY:
  		case SIOCGMIIREG:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2850
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
7a229387d   Arnd Bergmann   net: copy socket ...
2851
2852
2853
2854
2855
2856
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
  static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
  			struct compat_ifreq __user *uifr32)
  {
  	struct ifreq ifr;
  	struct compat_ifmap __user *uifmap32;
  	mm_segment_t old_fs;
  	int err;
  
  	uifmap32 = &uifr32->ifr_ifru.ifru_map;
  	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2867
2868
2869
2870
2871
2872
  	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...
2873
2874
2875
2876
  	if (err)
  		return -EFAULT;
  
  	old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2877
  	set_fs(KERNEL_DS);
c3f52ae6a   stephen hemminger   socket: suppress ...
2878
  	err = dev_ioctl(net, cmd, (void  __user __force *)&ifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2879
  	set_fs(old_fs);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2880
2881
2882
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2883
2884
2885
2886
2887
2888
  		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...
2889
2890
2891
2892
2893
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2894
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2895
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
2896
2897
2898
  	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...
2899
2900
2901
2902
2903
2904
2905
  	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 ...
2906
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2907
2908
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
  	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...
2924
2925
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2926
2927
2928
2929
2930
2931
2932
2933
  {
  	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...
2934
2935
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2936
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2937
  			3 * sizeof(struct in6_addr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2938
2939
2940
2941
2942
2943
2944
  		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 ...
2945
2946
2947
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
2948
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2949
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2950
  					3 * sizeof(struct sockaddr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2951
2952
2953
2954
2955
2956
  		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 ...
2957
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2958
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
c3f52ae6a   stephen hemminger   socket: suppress ...
2959
2960
  			r4.rt_dev = (char __user __force *)devname;
  			devname[15] = 0;
7a229387d   Arnd Bergmann   net: copy socket ...
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2971
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2972
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2973
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2974
2975
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
2976
2977
2978
2979
2980
  	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...
2981
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
2982
   */
6b96018b2   Arnd Bergmann   compat: move sock...
2983
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2984
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2985
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
2986

6b96018b2   Arnd Bergmann   compat: move sock...
2987
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
2988
2989
2990
2991
2992
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2993
2994
2995
2996
2997
2998
  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 ...
2999

6b96018b2   Arnd Bergmann   compat: move sock...
3000
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
3001
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
  
  	switch (cmd) {
  	case SIOCSIFBR:
  	case SIOCGIFBR:
  		return old_bridge_ioctl(argp);
  	case SIOCGIFNAME:
  		return dev_ifname32(net, argp);
  	case SIOCGIFCONF:
  		return dev_ifconf(net, argp);
  	case SIOCETHTOOL:
  		return ethtool_ioctl(net, argp);
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3013
3014
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3015
3016
3017
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3018
3019
3020
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3021
3022
3023
3024
3025
3026
3027
3028
3029
  	case SIOCBONDCHANGEACTIVE:
  		return bond_ioctl(net, cmd, argp);
  	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...
3030
3031
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
3032
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
3033
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
3034
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
  
  	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...
3046
  	case SIOCGSKNS:
6b96018b2   Arnd Bergmann   compat: move sock...
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
  		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...
3062
3063
3064
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
3065
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
  	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...
3078
3079
3080
3081
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
6b96018b2   Arnd Bergmann   compat: move sock...
3082
  		return dev_ifsioc(net, sock, cmd, argp);
9177efd39   Arnd Bergmann   net, compat_ioctl...
3083

6b96018b2   Arnd Bergmann   compat: move sock...
3084
3085
3086
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
6b96018b2   Arnd Bergmann   compat: move sock...
3087
  	case SIOCATMARK:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3088
3089
  		return sock_do_ioctl(net, sock, cmd, arg);
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
3090
3091
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3092

95c961747   Eric Dumazet   net: cleanup unsi...
3093
  static long compat_sock_ioctl(struct file *file, unsigned int cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
3094
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3095
3096
3097
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
3098
3099
3100
3101
3102
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3103
3104
3105
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
3106
3107
3108
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
3109
3110
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3111
3112
3113
  	return ret;
  }
  #endif
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3114
3115
3116
3117
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3118
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3119
3120
3121
3122
3123
  
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3124
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
  
  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 ...
3135
  	err = sock->ops->accept(sock, *newsock, flags, true);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3136
3137
  	if (err < 0) {
  		sock_release(*newsock);
fa8705b00   Tony Battersby   [NET]: sanitize k...
3138
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3139
3140
3141
3142
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
3143
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3144
3145
3146
3147
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3148
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3149
3150
  
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
3151
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3152
3153
3154
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3155
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3156
3157
3158
3159
3160
3161
  
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 0);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3162
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3163
3164
3165
3166
3167
3168
  
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 1);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3169
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3170
3171
3172
3173
3174
  
  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...
3175
3176
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3177
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3178
3179
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3180
3181
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3182
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3183
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3184
3185
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3186
3187
3188
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3189
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3190
3191
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
3192
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3193
3194
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3195
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3196
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3197
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3198
3199
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3200
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3201
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3202
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3203
3204
3205
3206
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3207
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3208
3209
3210
3211
3212
3213
3214
3215
3216
  
  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...
3217
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3218

306b13eb3   Tom Herbert   proto_ops: Add lo...
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
  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);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
  int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
  {
  	mm_segment_t oldfs = get_fs();
  	int err;
  
  	set_fs(KERNEL_DS);
  	err = sock->ops->ioctl(sock, cmd, arg);
  	set_fs(oldfs);
  
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3242
  EXPORT_SYMBOL(kernel_sock_ioctl);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3243

91cf45f02   Trond Myklebust   [NET]: Add the he...
3244
3245
3246
3247
  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...
3248
  EXPORT_SYMBOL(kernel_sock_shutdown);
113c30759   R. Parameswaran   New kernel functi...
3249
3250
3251
3252
  
  /* 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 ...
3253
   * on at the socket. Assumes that the caller has a lock on the socket.
113c30759   R. Parameswaran   New kernel functi...
3254
3255
3256
3257
3258
3259
   */
  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...
3260
3261
3262
3263
3264
3265
3266
  #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...
3267
3268
3269
3270
3271
  	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...
3272
  						sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3273
3274
3275
3276
3277
3278
3279
3280
3281
  		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...
3282
  							  sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3283
3284
3285
3286
3287
3288
3289
3290
3291
  		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);