Blame view

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

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

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

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

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

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

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

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

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

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

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

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

2c48b9c45   Al Viro   switch alloc_file...
398
  	file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
399
  		  &socket_file_ops);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
400
  	if (IS_ERR(file)) {
cc3808f8c   Al Viro   switch sock_alloc...
401
  		/* drop dentry, keep inode */
c5ef60352   David Howells   VFS: net/: d_inod...
402
  		ihold(d_inode(path.dentry));
2c48b9c45   Al Viro   switch alloc_file...
403
  		path_put(&path);
39b652527   Anatol Pomozov   fs: Preserve erro...
404
  		return file;
cc3808f8c   Al Viro   switch sock_alloc...
405
406
407
  	}
  
  	sock->file = file;
77d272005   Ulrich Drepper   flag parameters: ...
408
  	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
39d8c1b6f   David S. Miller   [NET]: Do not los...
409
  	file->private_data = sock;
284076305   Al Viro   take descriptor h...
410
  	return file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
411
  }
56b31d1c9   Al Viro   unexport sock_map...
412
  EXPORT_SYMBOL(sock_alloc_file);
39d8c1b6f   David S. Miller   [NET]: Do not los...
413

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

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

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

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

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

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
469
470
  static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
  {
00e188ef6   Al Viro   sockfd_lookup_lig...
471
  	struct fd f = fdget(fd);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
472
  	struct socket *sock;
3672558c6   Hua Zhong   [NET]: sockfd_loo...
473
  	*err = -EBADF;
00e188ef6   Al Viro   sockfd_lookup_lig...
474
475
476
477
  	if (f.file) {
  		sock = sock_from_file(f.file, err);
  		if (likely(sock)) {
  			*fput_needed = f.flags;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
478
  			return sock;
00e188ef6   Al Viro   sockfd_lookup_lig...
479
480
  		}
  		fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
482
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  }
600e17792   Masatake YAMATO   net: Providing pr...
484
485
486
487
488
  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...
489
  	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
600e17792   Masatake YAMATO   net: Providing pr...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  	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;
  }
  
  static const struct inode_operations sockfs_inode_ops = {
600e17792   Masatake YAMATO   net: Providing pr...
512
513
  	.listxattr = sockfs_listxattr,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
515
  /**
   *	sock_alloc	-	allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
516
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
519
520
   *	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...
521
  struct socket *sock_alloc(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
523
524
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525

a209dfc7b   Eric Dumazet   vfs: dont chain p...
526
  	inode = new_inode_pseudo(sock_mnt->mnt_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
529
530
  	if (!inode)
  		return NULL;
  
  	sock = SOCKET_I(inode);
29a020d35   Eric Dumazet   [PATCH] net: kmem...
531
  	kmemcheck_annotate_bitfield(sock, type);
85fe4025c   Christoph Hellwig   fs: do not assign...
532
  	inode->i_ino = get_next_ino();
89bddce58   Stephen Hemminger   [NET] socket: cod...
533
  	inode->i_mode = S_IFSOCK | S_IRWXUGO;
8192b0c48   David Howells   CRED: Wrap task c...
534
535
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
600e17792   Masatake YAMATO   net: Providing pr...
536
  	inode->i_op = &sockfs_inode_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537

19e8d69c5   Alex Shi   net: replace perc...
538
  	this_cpu_add(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
  	return sock;
  }
f4a00aacd   Tom Herbert   net: Make sock_al...
541
  EXPORT_SYMBOL(sock_alloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
  /**
   *	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...
549
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
555
556
557
558
559
560
  void sock_release(struct socket *sock)
  {
  	if (sock->ops) {
  		struct module *owner = sock->ops->owner;
  
  		sock->ops->release(sock);
  		sock->ops = NULL;
  		module_put(owner);
  	}
eaefd1105   Eric Dumazet   net: add __rcu an...
561
  	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
3410f22ea   Yang Yingliang   socket: replace s...
562
563
  		pr_err("%s: fasync list not empty!
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564

19e8d69c5   Alex Shi   net: replace perc...
565
  	this_cpu_sub(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
568
569
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
570
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
572
  EXPORT_SYMBOL(sock_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573

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

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

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

92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
610
611
612
613
614
615
  /*
   * 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...
616
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
f24b9be59   Willem de Bruijn   net-timestamp: ex...
617
  	struct scm_timestamping tss;
20d494735   Patrick Ohly   net: socket infra...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
  	int empty = 1;
  	struct skb_shared_hwtstamps *shhwtstamps =
  		skb_hwtstamps(skb);
  
  	/* Race occurred between timestamp enabling and packet
  	   receiving.  Fill in the current time for now. */
  	if (need_software_tstamp && skb->tstamp.tv64 == 0)
  		__net_timestamp(skb);
  
  	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...
634
635
  			struct timespec ts;
  			skb_get_timestampns(skb, &ts);
20d494735   Patrick Ohly   net: socket infra...
636
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
637
  				 sizeof(ts), &ts);
20d494735   Patrick Ohly   net: socket infra...
638
639
  		}
  	}
f24b9be59   Willem de Bruijn   net-timestamp: ex...
640
  	memset(&tss, 0, sizeof(tss));
c199105d1   Willem de Bruijn   net-timestamp: on...
641
  	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
f24b9be59   Willem de Bruijn   net-timestamp: ex...
642
  	    ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
20d494735   Patrick Ohly   net: socket infra...
643
  		empty = 0;
4d276eb6a   Willem de Bruijn   net: remove depre...
644
  	if (shhwtstamps &&
b9f40e21e   Willem de Bruijn   net-timestamp: mo...
645
  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
f24b9be59   Willem de Bruijn   net-timestamp: ex...
646
  	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))
4d276eb6a   Willem de Bruijn   net: remove depre...
647
  		empty = 0;
20d494735   Patrick Ohly   net: socket infra...
648
649
  	if (!empty)
  		put_cmsg(msg, SOL_SOCKET,
f24b9be59   Willem de Bruijn   net-timestamp: ex...
650
  			 SCM_TIMESTAMPING, sizeof(tss), &tss);
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
651
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
652
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
6e3e939f3   Johannes Berg   net: add wireless...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
  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 ...
668
669
  static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
  				   struct sk_buff *skb)
3b885787e   Neil Horman   net: Generalize s...
670
  {
744d5a3e9   Eyal Birger   net: move skb->dr...
671
  	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
3b885787e   Neil Horman   net: Generalize s...
672
  		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
744d5a3e9   Eyal Birger   net: move skb->dr...
673
  			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
3b885787e   Neil Horman   net: Generalize s...
674
  }
767dd0336   Eric Dumazet   net: speedup sock...
675
  void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
3b885787e   Neil Horman   net: Generalize s...
676
677
678
679
680
  	struct sk_buff *skb)
  {
  	sock_recv_timestamp(msg, sk, skb);
  	sock_recv_drops(msg, sk, skb);
  }
767dd0336   Eric Dumazet   net: speedup sock...
681
  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
3b885787e   Neil Horman   net: Generalize s...
682

1b7841404   Ying Xue   net: Remove iocb ...
683
  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
2da62906b   Al Viro   [net] drop 'size'...
684
  				     int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
  {
2da62906b   Al Viro   [net] drop 'size'...
686
  	return sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
687
  }
2da62906b   Al Viro   [net] drop 'size'...
688
  int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
689
  {
2da62906b   Al Viro   [net] drop 'size'...
690
  	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
691

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

c1249c0aa   Martin Lucina   net: Document the...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  /**
   * 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...
711
712
  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
713
714
715
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
6aa248145   Al Viro   switch kernel_sen...
716
  	iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  	set_fs(KERNEL_DS);
2da62906b   Al Viro   [net] drop 'size'...
718
  	result = sock_recvmsg(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
722
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
724
725
  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
726
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
729
  	sock = file->private_data;
35f9c09fe   Eric Dumazet   tcp: tcp_sendpage...
730
731
732
  	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...
733

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

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
737
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
738
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
739
740
741
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
742
743
  	if (unlikely(!sock->ops->splice_read))
  		return -EINVAL;
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
744
745
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
8ae5e030f   Al Viro   net: switch socke...
746
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
747
  {
6d6523302   Al Viro   net/socket.c: fol...
748
749
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
750
751
  	struct msghdr msg = {.msg_iter = *to,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
752
  	ssize_t res;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
753

8ae5e030f   Al Viro   net: switch socke...
754
755
756
757
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
  
  	if (iocb->ki_pos != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
758
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
759

66ee59af6   Christoph Hellwig   fs: remove ki_nbytes
760
  	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
  		return 0;
2da62906b   Al Viro   [net] drop 'size'...
762
  	res = sock_recvmsg(sock, &msg, msg.msg_flags);
8ae5e030f   Al Viro   net: switch socke...
763
764
  	*to = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765
  }
8ae5e030f   Al Viro   net: switch socke...
766
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
767
  {
6d6523302   Al Viro   net/socket.c: fol...
768
769
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
770
771
  	struct msghdr msg = {.msg_iter = *from,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
772
  	ssize_t res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773

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

8ae5e030f   Al Viro   net: switch socke...
777
778
  	if (file->f_flags & O_NONBLOCK)
  		msg.msg_flags = MSG_DONTWAIT;
6d6523302   Al Viro   net/socket.c: fol...
779
780
  	if (sock->type == SOCK_SEQPACKET)
  		msg.msg_flags |= MSG_EOR;
d8725c86a   Al Viro   get rid of the si...
781
  	res = sock_sendmsg(sock, &msg);
8ae5e030f   Al Viro   net: switch socke...
782
783
  	*from = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
788
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
789
  static DEFINE_MUTEX(br_ioctl_mutex);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
790
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791

881d966b4   Eric W. Biederman   [NET]: Make the d...
792
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
794
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
795
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
796
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
798
  }
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
799
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
800
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801

881d966b4   Eric W. Biederman   [NET]: Make the d...
802
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
804
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
806
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
807
808
  }
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
809
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
810
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811

89bddce58   Stephen Hemminger   [NET] socket: cod...
812
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
814
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
816
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
818
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  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
836
837
838
839
840
841
842
843
  /*
   *	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.
   */
  
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
  	struct socket *sock;
881d966b4   Eric W. Biederman   [NET]: Make the d...
844
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
847
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848

b69aee04f   Eric Dumazet   [NET]: Use file->...
849
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
850
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
851
  	net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
853
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
  	} else
3d23e349d   Johannes Berg   wext: refactor
855
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
857
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
  	} else
3d23e349d   Johannes Berg   wext: refactor
859
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
860
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
862
863
864
865
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
e0b93eddf   Jeff Layton   security: make se...
866
867
  			f_setown(sock->file, pid, 1);
  			err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
869
870
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
871
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
872
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
874
875
876
877
878
879
880
  			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: ...
881
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
882
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
883
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
884
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
887
888
889
890
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
891
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
892
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
893
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
894
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
897
898
899
900
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
901
902
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
904
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
906
  			break;
  		default:
6b96018b2   Arnd Bergmann   compat: move sock...
907
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
909
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
910
911
912
913
914
915
916
  	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...
917

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
919
920
921
922
923
924
925
926
  	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
927
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
928
929
930
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
932
933
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
934
935
936
937
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
939
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940
941
  
  /* No kernel lock held - perfect */
89bddce58   Stephen Hemminger   [NET] socket: cod...
942
  static unsigned int sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  {
cbf55001b   Eliezer Tamir   net: rename low l...
944
  	unsigned int busy_flag = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
946
947
  	struct socket *sock;
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
948
  	 *      We can't return errors to poll, so it's either yes or no.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
  	 */
b69aee04f   Eric Dumazet   [NET]: Use file->...
950
  	sock = file->private_data;
2d48d67fa   Eliezer Tamir   net: poll/select ...
951

cbf55001b   Eliezer Tamir   net: rename low l...
952
  	if (sk_can_busy_loop(sock->sk)) {
2d48d67fa   Eliezer Tamir   net: poll/select ...
953
  		/* this socket can poll_ll so tell the system call */
cbf55001b   Eliezer Tamir   net: rename low l...
954
  		busy_flag = POLL_BUSY_LOOP;
2d48d67fa   Eliezer Tamir   net: poll/select ...
955
956
  
  		/* once, only if requested by syscall */
cbf55001b   Eliezer Tamir   net: rename low l...
957
958
  		if (wait && (wait->_key & POLL_BUSY_LOOP))
  			sk_busy_loop(sock->sk, 1);
2d48d67fa   Eliezer Tamir   net: poll/select ...
959
  	}
cbf55001b   Eliezer Tamir   net: rename low l...
960
  	return busy_flag | sock->ops->poll(file, sock, wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
962
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
964
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
966
967
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
968
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
971
972
973
974
975
976
977
978
979
980
981
  	sock_release(SOCKET_I(inode));
  	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...
982
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
984
985
986
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
987
988
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
eaefd1105   Eric Dumazet   net: add __rcu an...
989
  	struct socket_wq *wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990

989a29792   Eric Dumazet   fasync: RCU and f...
991
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
994
  
  	lock_sock(sk);
1e1d04e67   Hannes Frederic Sowa   net: introduce lo...
995
  	wq = rcu_dereference_protected(sock->wq, lockdep_sock_is_held(sk));
eaefd1105   Eric Dumazet   net: add __rcu an...
996
  	fasync_helper(fd, filp, on, &wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997

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

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

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1008
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1010
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1012

89bddce58   Stephen Hemminger   [NET] socket: cod...
1013
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1014
  	case SOCK_WAKE_WAITD:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1015
  		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
1017
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1018
  	case SOCK_WAKE_SPACE:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1019
  		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1020
1021
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1022
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1023
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1024
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1025
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1026
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1027
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1028
  	}
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1029

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
1031
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1032
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033

721db93a5   Pavel Emelyanov   net: Export __soc...
1034
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1035
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
1037
1038
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1039
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
1041
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1042
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
  	 */
  	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 ...
1055
1056
1057
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1058
1059
1060
1061
1062
1063
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1064

55737fda0   Stephen Hemminger   [NET]: socket fam...
1065
1066
1067
1068
1069
1070
1071
  	/*
  	 *	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_...
1072
1073
  		net_warn_ratelimited("socket: no more sockets
  ");
55737fda0   Stephen Hemminger   [NET]: socket fam...
1074
1075
1076
1077
1078
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1079
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1080
1081
1082
  	/* 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
1083
1084
1085
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
190683a9d   Eric Dumazet   net: net_families...
1086
  	if (rcu_access_pointer(net_families[family]) == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1087
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1088
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1089
1090
1091
1092
1093
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1094
1095
1096
1097
1098
  
  	/*
  	 * 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...
1099
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1101
1102
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1103
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1104
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1106

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107
1108
1109
1110
  	/*
  	 * 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...
1111
1112
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1113
1114
1115
1116
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1117
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1118
1119
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1120
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1121
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122

55737fda0   Stephen Hemminger   [NET]: socket fam...
1123
1124
1125
1126
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1127
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1128
1129
1130
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1132
1133
1134
1135
1136
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1137
  }
721db93a5   Pavel Emelyanov   net: Export __soc...
1138
  EXPORT_SYMBOL(__sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1139
1140
1141
  
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1142
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1144
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1145

eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1146
  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
  {
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1148
  	return __sock_create(net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1150
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151

3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1152
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
1154
1155
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1156
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1157
1158
1159
1160
1161
  	/* 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: ...
1162
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1163
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1164
1165
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166

aaca0bdca   Ulrich Drepper   flag parameters: ...
1167
1168
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1169
1170
1171
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
  		goto out;
77d272005   Ulrich Drepper   flag parameters: ...
1172
  	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
  	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...
1188
1189
  SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
  		int __user *, usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1190
1191
1192
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1193
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1194
1195
1196
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1197
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1198
1199
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200

aaca0bdca   Ulrich Drepper   flag parameters: ...
1201
1202
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
  	/*
  	 * 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...
1217
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218
  		goto out_release_both;
284076305   Al Viro   take descriptor h...
1219
  	fd1 = get_unused_fd_flags(flags);
bf3c23d17   David S. Miller   [NET]: Fix error ...
1220
1221
  	if (unlikely(fd1 < 0)) {
  		err = fd1;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1222
  		goto out_release_both;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1223
  	}
d73aa2867   Yann Droneaud   net: handle error...
1224

284076305   Al Viro   take descriptor h...
1225
  	fd2 = get_unused_fd_flags(flags);
198de4d7a   Al Viro   reorder alloc_fd/...
1226
1227
  	if (unlikely(fd2 < 0)) {
  		err = fd2;
d73aa2867   Yann Droneaud   net: handle error...
1228
  		goto out_put_unused_1;
284076305   Al Viro   take descriptor h...
1229
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1230
  	newfile1 = sock_alloc_file(sock1, flags, NULL);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1231
  	if (IS_ERR(newfile1)) {
284076305   Al Viro   take descriptor h...
1232
  		err = PTR_ERR(newfile1);
d73aa2867   Yann Droneaud   net: handle error...
1233
  		goto out_put_unused_both;
284076305   Al Viro   take descriptor h...
1234
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1235
  	newfile2 = sock_alloc_file(sock2, flags, NULL);
284076305   Al Viro   take descriptor h...
1236
1237
  	if (IS_ERR(newfile2)) {
  		err = PTR_ERR(newfile2);
d73aa2867   Yann Droneaud   net: handle error...
1238
  		goto out_fput_1;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1239
  	}
d73aa2867   Yann Droneaud   net: handle error...
1240
1241
1242
1243
1244
1245
1246
  	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...
1247
  	audit_fd_pair(fd1, fd2);
d73aa2867   Yann Droneaud   net: handle error...
1248

db3495099   Al Viro   [PATCH] AUDIT_FD_...
1249
1250
  	fd_install(fd1, newfile1);
  	fd_install(fd2, newfile2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251
1252
1253
  	/* fd1 and fd2 may be already another descriptors.
  	 * Not kernel problem.
  	 */
d73aa2867   Yann Droneaud   net: handle error...
1254
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255

d73aa2867   Yann Droneaud   net: handle error...
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
  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
1269

d73aa2867   Yann Droneaud   net: handle error...
1270
1271
1272
1273
  out_put_unused_both:
  	put_unused_fd(fd2);
  out_put_unused_1:
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1274
  out_release_both:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1275
  	sock_release(sock2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
  out_release_1:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1277
  	sock_release(sock1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1278
1279
1280
  out:
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
1282
1283
1284
1285
1286
1287
  /*
   *	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...
1288
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1289
1290
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1291
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1292
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293

89bddce58   Stephen Hemminger   [NET] socket: cod...
1294
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1295
  	if (sock) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1296
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1297
1298
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1299
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1300
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1301
1302
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1303
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1304
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1306
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1307
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
1309
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310
1311
1312
1313
1314
  /*
   *	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...
1315
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1316
1317
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1318
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1319
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1320
1321
1322
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1323
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1324
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1325
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1326
1327
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1328
1329
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1330

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1331
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
1333
1334
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
  /*
   *	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...
1346
1347
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1348
1349
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1350
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1351
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1352
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353

77d272005   Ulrich Drepper   flag parameters: ...
1354
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1355
1356
1357
1358
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1359
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
1361
1362
1363
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1364
1365
  	newsock = sock_alloc();
  	if (!newsock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1366
1367
1368
1369
  		goto out_put;
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370
1371
1372
1373
1374
  	/*
  	 * 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...
1375
  	newfd = get_unused_fd_flags(flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1376
1377
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1378
1379
  		sock_release(newsock);
  		goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1380
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1381
  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1382
  	if (IS_ERR(newfile)) {
284076305   Al Viro   take descriptor h...
1383
1384
1385
1386
1387
  		err = PTR_ERR(newfile);
  		put_unused_fd(newfd);
  		sock_release(newsock);
  		goto out_put;
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
1388

a79af59ef   Frank Filz   [NET]: Fix module...
1389
1390
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1391
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1392

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1393
1394
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1395
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
1397
  
  	if (upeer_sockaddr) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1398
  		if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1399
  					  &len, 2) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1400
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1401
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1402
  		}
43db362d3   Maciej Żenczykowski   net: get rid of s...
1403
  		err = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1404
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1406
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1407
1408
1409
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1410
1411
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1414
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1415
1416
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1417
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1418
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1419
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1420
1421
  	goto out_put;
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1422
1423
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1424
  {
de11defeb   Ulrich Drepper   reintroduce accept4
1425
  	return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1426
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
  /*
   *	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...
1438
1439
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1440
1441
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1442
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1443
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1445
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1446
1447
  	if (!sock)
  		goto out;
43db362d3   Maciej Żenczykowski   net: get rid of s...
1448
  	err = move_addr_to_kernel(uservaddr, addrlen, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1449
1450
  	if (err < 0)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1451
  	err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1452
  	    security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1453
1454
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1455
  	err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1456
1457
  				 sock->file->f_flags);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1458
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1459
1460
1461
1462
1463
1464
1465
1466
  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...
1467
1468
  SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1469
1470
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1471
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1472
  	int len, err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1473

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1474
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1475
1476
1477
1478
1479
1480
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1481
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482
1483
  	if (err)
  		goto out_put;
43db362d3   Maciej Żenczykowski   net: get rid of s...
1484
  	err = move_addr_to_user(&address, len, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1485
1486
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1487
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
1489
1490
1491
1492
1493
1494
1495
  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...
1496
1497
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1498
1499
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1500
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1501
  	int len, err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502

89bddce58   Stephen Hemminger   [NET] socket: cod...
1503
1504
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505
1506
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1507
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
1509
  			return err;
  		}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1510
  		err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1511
  		    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1512
  				       1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  		if (!err)
43db362d3   Maciej Żenczykowski   net: get rid of s...
1514
  			err = move_addr_to_user(&address, len, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1515
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1516
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1517
1518
1519
1520
1521
1522
1523
1524
1525
  	}
  	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...
1526
  SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1527
  		unsigned int, flags, struct sockaddr __user *, addr,
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1528
  		int, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
1530
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1531
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
1533
1534
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1535
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1536

602bd0e90   Al Viro   net: switch sendt...
1537
1538
1539
  	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1540
1541
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1542
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1543

89bddce58   Stephen Hemminger   [NET] socket: cod...
1544
  	msg.msg_name = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1545
1546
1547
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1548
  	if (addr) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1549
  		err = move_addr_to_kernel(addr, addr_len, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
1551
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1552
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1553
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
1555
1556
1557
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
d8725c86a   Al Viro   get rid of the si...
1558
  	err = sock_sendmsg(sock, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1559

89bddce58   Stephen Hemminger   [NET] socket: cod...
1560
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1561
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1562
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1563
1564
1565
1566
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1567
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1568
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1569
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1570
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
1572
1573
1574
1575
  {
  	return sys_sendto(fd, buff, len, flags, NULL, 0);
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1576
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
1578
1579
   *	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...
1580
  SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
95c961747   Eric Dumazet   net: cleanup unsi...
1581
  		unsigned int, flags, struct sockaddr __user *, addr,
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1582
  		int __user *, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
1584
1585
1586
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1587
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1588
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1589
  	int fput_needed;
602bd0e90   Al Viro   net: switch sendt...
1590
1591
1592
  	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1593
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1595
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1596

89bddce58   Stephen Hemminger   [NET] socket: cod...
1597
1598
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1599
1600
1601
1602
  	/* 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...
1603
  	msg.msg_iocb = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1604
1605
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1606
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607

89bddce58   Stephen Hemminger   [NET] socket: cod...
1608
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1609
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1610
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1611
1612
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1613
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1614
1615
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1616
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1617
1618
1619
1620
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1621
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1622
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1623
1624
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625
1626
1627
1628
1629
1630
1631
1632
  {
  	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...
1633
1634
  SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1635
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1636
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637
1638
1639
1640
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1641
1642
1643
1644
  
  	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...
1645
1646
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
1648
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1649
1650
1651
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1652
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1653
1654
1655
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1656
1657
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1658
1659
1660
1661
1662
1663
1664
1665
  	}
  	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...
1666
1667
  SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int __user *, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1668
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1669
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1671
1672
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1673
1674
1675
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
1677
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1678
1679
1680
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1681
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1682
1683
1684
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1685
1686
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
1688
1689
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1690
1691
1692
  /*
   *	Shutdown a socket.
   */
754fe8d29   Heiko Carstens   [CVE-2009-0029] S...
1693
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1695
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1697
1698
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1699
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1700
1701
1702
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1703
1704
1705
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1706
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1707
1708
1709
1710
1711
   * 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...
1712
1713
1714
1715
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
da1842849   Al Viro   net: switch impor...
1716
1717
1718
1719
  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...
1720
  {
08adb7dab   Al Viro   fold verify_iovec...
1721
1722
  	struct sockaddr __user *uaddr;
  	struct iovec __user *uiov;
c0371da60   Al Viro   put iov_iter into...
1723
  	size_t nr_segs;
08adb7dab   Al Viro   fold verify_iovec...
1724
1725
1726
1727
1728
1729
  	ssize_t err;
  
  	if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
  	    __get_user(uaddr, &umsg->msg_name) ||
  	    __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
  	    __get_user(uiov, &umsg->msg_iov) ||
c0371da60   Al Viro   put iov_iter into...
1730
  	    __get_user(nr_segs, &umsg->msg_iovlen) ||
08adb7dab   Al Viro   fold verify_iovec...
1731
1732
1733
  	    __get_user(kmsg->msg_control, &umsg->msg_control) ||
  	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
  	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
1661bf364   Dan Carpenter   net: heap overflo...
1734
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
1735

08adb7dab   Al Viro   fold verify_iovec...
1736
  	if (!uaddr)
6a2a2b3ae   Ani Sinha   net:socket: set m...
1737
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
1738
1739
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
1740
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
1741
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
  
  	if (save_addr)
  		*save_addr = uaddr;
  
  	if (uaddr && kmsg->msg_namelen) {
  		if (!save_addr) {
  			err = move_addr_to_kernel(uaddr, kmsg->msg_namelen,
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
c0371da60   Al Viro   put iov_iter into...
1757
  	if (nr_segs > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
1758
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
1759
  	kmsg->msg_iocb = NULL;
da1842849   Al Viro   net: switch impor...
1760
1761
  	return import_iovec(save_addr ? READ : WRITE, uiov, nr_segs,
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
1661bf364   Dan Carpenter   net: heap overflo...
1762
  }
666547ff5   Al Viro   separate kernel- ...
1763
  static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
1764
  			 struct msghdr *msg_sys, unsigned int flags,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1765
1766
  			 struct used_address *used_address,
  			 unsigned int allowed_msghdr_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1767
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1768
1769
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1770
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
b9d717a7b   Alex Williamson   [NET]: Make sure ...
1772
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
89bddce58   Stephen Hemminger   [NET] socket: cod...
1773
1774
  	    __attribute__ ((aligned(sizeof(__kernel_size_t))));
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1775
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
1776
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
1777
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1778

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

084493200   Al Viro   {compat_,}verify_...
1781
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
1782
  		err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
084493200   Al Viro   {compat_,}verify_...
1783
  	else
08adb7dab   Al Viro   fold verify_iovec...
1784
  		err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1785
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
1786
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1787
1788
  
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1789
  	if (msg_sys->msg_controllen > INT_MAX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1790
  		goto out_freeiov;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1791
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1792
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1794
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
1795
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1796
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1797
1798
  		if (err)
  			goto out_freeiov;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1799
1800
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801
  	} else if (ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1802
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1803
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1804
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1805
1806
1807
1808
  				goto out_freeiov;
  		}
  		err = -EFAULT;
  		/*
228e548e6   Anton Blanchard   net: Add sendmmsg...
1809
  		 * Careful! Before this, msg_sys->msg_control contains a user pointer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
1811
1812
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
1813
  		if (copy_from_user(ctl_buf,
228e548e6   Anton Blanchard   net: Add sendmmsg...
1814
  				   (void __user __force *)msg_sys->msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1815
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1817
  		msg_sys->msg_control = ctl_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
1819
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1820
1821
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1822
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
1823
1824
1825
1826
1827
1828
  	/*
  	 * 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:...
1829
1830
1831
  	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...
1832
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
1833
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1834
1835
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
1836
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1837
1838
1839
1840
1841
1842
  	/*
  	 * 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:...
1843
1844
1845
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
1846
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1847
1848
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1849
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1850
1851
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  out_freeiov:
da1842849   Al Viro   net: switch impor...
1852
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1853
1854
1855
1856
1857
1858
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
666547ff5   Al Viro   separate kernel- ...
1859
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1860
1861
1862
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
1863
  	struct socket *sock;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
1864
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1865
1866
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1867
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1868

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1869
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1870
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
1872
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
1873
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
1874
1875
1876
1877
1878
  {
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  	return __sys_sendmsg(fd, msg, flags);
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
  /*
   *	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...
1891
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
1892
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1893

98382f419   Anton Blanchard   net: Cap number o...
1894
1895
  	if (vlen > UIO_MAXIOV)
  		vlen = UIO_MAXIOV;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1896
1897
1898
1899
1900
1901
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
c71d8ebe7   Tetsuo Handa   net: Fix security...
1902
  	used_address.name_len = UINT_MAX;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1903
1904
  	entry = mmsg;
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
728ffb86f   Anton Blanchard   net: sendmmsg sho...
1905
  	err = 0;
f092276d8   Tom Herbert   net: Add MSG_BATC...
1906
  	flags |= MSG_BATCH;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1907
1908
  
  	while (datagrams < vlen) {
f092276d8   Tom Herbert   net: Add MSG_BATC...
1909
1910
  		if (datagrams == vlen - 1)
  			flags = oflags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1911
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
1912
  			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1913
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1914
1915
1916
1917
1918
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
1919
  			err = ___sys_sendmsg(sock,
666547ff5   Al Viro   separate kernel- ...
1920
  					     (struct user_msghdr __user *)entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
1921
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
1922
1923
1924
1925
1926
1927
1928
1929
1930
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
  
  		if (err)
  			break;
  		++datagrams;
3023898b7   Soheil Hassas Yeganeh   sock: fix sendmms...
1931
1932
  		if (msg_data_left(&msg_sys))
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
1933
  		cond_resched();
228e548e6   Anton Blanchard   net: Add sendmmsg...
1934
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
1935
  	fput_light(sock->file, fput_needed);
728ffb86f   Anton Blanchard   net: sendmmsg sho...
1936
1937
  	/* We only return an error if no datagrams were able to be sent */
  	if (datagrams != 0)
228e548e6   Anton Blanchard   net: Add sendmmsg...
1938
  		return datagrams;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1939
1940
1941
1942
1943
1944
  	return err;
  }
  
  SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags)
  {
1be374a05   Andy Lutomirski   net: Block MSG_CM...
1945
1946
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
228e548e6   Anton Blanchard   net: Add sendmmsg...
1947
1948
  	return __sys_sendmmsg(fd, mmsg, vlen, flags);
  }
666547ff5   Al Viro   separate kernel- ...
1949
  static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
95c961747   Eric Dumazet   net: cleanup unsi...
1950
  			 struct msghdr *msg_sys, unsigned int flags, int nosec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1952
1953
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1954
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
1955
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1956
  	unsigned long cmsg_ptr;
2da62906b   Al Viro   [net] drop 'size'...
1957
  	int len;
08adb7dab   Al Viro   fold verify_iovec...
1958
  	ssize_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1959
1960
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1961
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1962
1963
1964
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
08adb7dab   Al Viro   fold verify_iovec...
1965
  	int __user *uaddr_len = COMPAT_NAMELEN(msg);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1966

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

f3d334260   Hannes Frederic Sowa   net: rework recvm...
1969
  	if (MSG_CMSG_COMPAT & flags)
08adb7dab   Al Viro   fold verify_iovec...
1970
  		err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov);
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1971
  	else
08adb7dab   Al Viro   fold verify_iovec...
1972
  		err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
1974
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1975

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1976
1977
  	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...
1978

f3d334260   Hannes Frederic Sowa   net: rework recvm...
1979
1980
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1981
1982
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1983
  	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1984
1985
1986
1987
1988
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Żenczykowski   net: get rid of s...
1989
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1990
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1991
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1992
1993
1994
  		if (err < 0)
  			goto out_freeiov;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1995
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
1996
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1997
1998
1999
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2000
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2001
2002
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2003
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2004
2005
2006
2007
2008
2009
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
da1842849   Al Viro   net: switch impor...
2010
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2011
2012
2013
2014
2015
2016
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
666547ff5   Al Viro   separate kernel- ...
2017
  long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2018
2019
2020
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2021
  	struct socket *sock;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2022
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2023
2024
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2025
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2026

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2027
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2028
2029
2030
  out:
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2031
  SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2032
2033
2034
2035
2036
2037
  		unsigned int, flags)
  {
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  	return __sys_recvmsg(fd, msg, flags);
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
  /*
   *     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...
2048
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2049
  	struct msghdr msg_sys;
766b9f928   Deepa Dinamani   fs: poll/select/r...
2050
2051
  	struct timespec64 end_time;
  	struct timespec64 timeout64;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
  
  	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);
  	if (err)
  		goto out_put;
  
  	entry = mmsg;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2069
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2070
2071
2072
2073
2074
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2075
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2076
  			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2077
2078
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2079
2080
2081
2082
2083
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2084
  			err = ___sys_recvmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2085
  					     (struct user_msghdr __user *)entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2086
2087
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2088
2089
2090
2091
2092
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2093
2094
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2095
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2096
2097
2098
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2099
  		if (timeout) {
766b9f928   Deepa Dinamani   fs: poll/select/r...
2100
2101
2102
  			ktime_get_ts64(&timeout64);
  			*timeout = timespec64_to_timespec(
  					timespec64_sub(end_time, timeout64));
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
  			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...
2116
  		cond_resched();
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2117
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2118
  	if (err == 0)
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2119
2120
2121
2122
2123
2124
  		goto out_put;
  
  	if (datagrams == 0) {
  		datagrams = err;
  		goto out_put;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2125

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2126
2127
2128
2129
2130
  	/*
  	 * 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...
2131
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2132
2133
2134
2135
  		 * ... 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...
2136
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2137
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2138
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2139
2140
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2141

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2142
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2143
2144
2145
2146
2147
2148
2149
2150
  }
  
  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...
2151
2152
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
  	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
2169
2170
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
228e548e6   Anton Blanchard   net: Add sendmmsg...
2171
  static const unsigned char nargs[21] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2172
2173
2174
  	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...
2175
  	AL(4), AL(5), AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2176
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2177
2178
2179
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2180
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2181
2182
2183
   *
   *	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...
2184
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2185
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2186
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2187
  {
2950fa9d3   Chen Gang   kernel: audit: be...
2188
  	unsigned long a[AUDITSC_ARGS];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2189
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2190
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2191
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2192

228e548e6   Anton Blanchard   net: Add sendmmsg...
2193
  	if (call < 1 || call > SYS_SENDMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2194
  		return -EINVAL;
47379052b   Arjan van de Ven   net: Add explicit...
2195
2196
2197
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2198
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2199
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2200
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2201

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
  	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
2223
2224
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
  		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- ...
2266
  		err = sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2267
  		break;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2268
2269
2270
  	case SYS_SENDMMSG:
  		err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2271
  	case SYS_RECVMSG:
666547ff5   Al Viro   separate kernel- ...
2272
  		err = sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2273
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2274
2275
2276
2277
  	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
2278
2279
2280
  	case SYS_ACCEPT4:
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2281
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2282
2283
2284
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285
2286
2287
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2288
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2289

55737fda0   Stephen Hemminger   [NET]: socket fam...
2290
2291
2292
2293
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2294
2295
   *	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...
2296
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2297
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2298
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2299
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2300
2301
2302
2303
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2304
2305
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2306
2307
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2308
2309
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2310
2311
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2312
2313
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2314
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2315
2316
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2317
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2318
2319
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2320
2321
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2322
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2323

55737fda0   Stephen Hemminger   [NET]: socket fam...
2324
2325
2326
2327
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2328
2329
   *	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...
2330
2331
2332
2333
2334
2335
   *	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
2336
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2337
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2338
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2339
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2340

55737fda0   Stephen Hemminger   [NET]: socket fam...
2341
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2342
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2343
2344
2345
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2346
2347
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2348
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2349
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2350

77d76ea31   Andi Kleen   [NET]: Small clea...
2351
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2352
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2353
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2354
2355
2356
2357
2358
2359
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2360

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2361
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2362
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2363
2364
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2365
2366
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2367
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2368
2369
2370
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2371
2372
2373
2374
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
  		goto out_fs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2375
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2376
2377
2378
2379
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2380
2381
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2382
2383
2384
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2385
2386
2387
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2388
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2389

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

b3e19d924   Nick Piggin   fs: scale mntget/...
2392
2393
2394
2395
2396
2397
2398
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
  out_fs:
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2399
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2400
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2401
2402
2403
2404
2405
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
  	int cpu;
  	int counter = 0;
6f9120422   KAMEZAWA Hiroyuki   [PATCH] for_each_...
2406
  	for_each_possible_cpu(cpu)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2407
  	    counter += per_cpu(sockets_in_use, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2408
2409
2410
2411
2412
2413
2414
2415
  
  	/* 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...
2416
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2418
  #ifdef CONFIG_COMPAT
6b96018b2   Arnd Bergmann   compat: move sock...
2419
  static int do_siocgstamp(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2420
  			 unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2421
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2422
2423
2424
2425
2426
  	mm_segment_t old_fs = get_fs();
  	struct timeval ktv;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2427
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
7a229387d   Arnd Bergmann   net: copy socket ...
2428
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2429
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2430
  		err = compat_put_timeval(&ktv, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2431

7a229387d   Arnd Bergmann   net: copy socket ...
2432
2433
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2434
  static int do_siocgstampns(struct net *net, struct socket *sock,
644595f89   H. Peter Anvin   compat: Handle CO...
2435
  			   unsigned int cmd, void __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2436
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2437
2438
2439
2440
2441
  	mm_segment_t old_fs = get_fs();
  	struct timespec kts;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2442
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
7a229387d   Arnd Bergmann   net: copy socket ...
2443
  	set_fs(old_fs);
644595f89   H. Peter Anvin   compat: Handle CO...
2444
  	if (!err)
ed6fe9d61   Mikulas Patocka   Fix order of argu...
2445
  		err = compat_put_timespec(&kts, up);
644595f89   H. Peter Anvin   compat: Handle CO...
2446

7a229387d   Arnd Bergmann   net: copy socket ...
2447
2448
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2449
  static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2450
2451
2452
2453
2454
  {
  	struct ifreq __user *uifr;
  	int err;
  
  	uifr = compat_alloc_user_space(sizeof(struct ifreq));
6b96018b2   Arnd Bergmann   compat: move sock...
2455
  	if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2456
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2457
  	err = dev_ioctl(net, SIOCGIFNAME, uifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2458
2459
  	if (err)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
2460
  	if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2461
2462
2463
2464
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2465
  static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2466
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2467
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2468
2469
  	struct ifconf ifc;
  	struct ifconf __user *uifc;
6b96018b2   Arnd Bergmann   compat: move sock...
2470
  	struct compat_ifreq __user *ifr32;
7a229387d   Arnd Bergmann   net: copy socket ...
2471
2472
2473
  	struct ifreq __user *ifr;
  	unsigned int i, j;
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2474
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2475
  		return -EFAULT;
43da5f2e0   Mathias Krause   net: fix info lea...
2476
  	memset(&ifc, 0, sizeof(ifc));
7a229387d   Arnd Bergmann   net: copy socket ...
2477
2478
2479
2480
2481
2482
  	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...
2483
2484
  		size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
  			sizeof(struct ifreq);
7a229387d   Arnd Bergmann   net: copy socket ...
2485
2486
2487
2488
  		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...
2489
  		for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
6b96018b2   Arnd Bergmann   compat: move sock...
2490
  			if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2491
2492
2493
2494
2495
2496
2497
  				return -EFAULT;
  			ifr++;
  			ifr32++;
  		}
  	}
  	if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2498
  	err = dev_ioctl(net, SIOCGIFCONF, uifc);
7a229387d   Arnd Bergmann   net: copy socket ...
2499
2500
2501
2502
2503
2504
2505
2506
2507
  	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...
2508
2509
2510
  	     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 ...
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
  			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...
2521
  		i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
7a229387d   Arnd Bergmann   net: copy socket ...
2522
2523
2524
2525
  		ifc32.ifc_len = i;
  	} else {
  		ifc32.ifc_len = i;
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
2526
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2527
2528
2529
2530
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2531
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2532
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2533
2534
2535
2536
  	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 ...
2537
  	struct ifreq __user *ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2538
2539
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2540
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2541
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2542

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

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2546
2547
2548
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2549
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
  	/* 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...
2567
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2568
2569
2570
  		convert_out = true;
  		/* fall through */
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2571
2572
2573
2574
2575
2576
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
  		break;
  	}
  
  	ifr = compat_alloc_user_space(buf_size);
954b12445   Stephen Hemminger   ethtool: fix spar...
2577
  	rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2578
2579
  
  	if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2580
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2581
2582
  	if (put_user(convert_in ? rxnfc : compat_ptr(data),
  		     &ifr->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2583
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2584
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2585
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2586
2587
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2588
2589
2590
2591
  		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...
2592
2593
2594
2595
2596
2597
2598
  		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...
2599
2600
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2601
2602
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2603
2604
  				 (void __user *)(&rxnfc->fs.location + 1) -
  				 (void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
  		    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...
2616
2617
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2618
2619
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2620
2621
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
  		    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 ...
2647
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2648
2649
2650
2651
2652
  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...
2653
  	uifr = compat_alloc_user_space(sizeof(*uifr));
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
  	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...
2667
2668
  static int bond_ioctl(struct net *net, unsigned int cmd,
  			 struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2669
2670
  {
  	struct ifreq kifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2671
2672
  	mm_segment_t old_fs;
  	int err;
7a229387d   Arnd Bergmann   net: copy socket ...
2673
2674
2675
2676
2677
2678
  
  	switch (cmd) {
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
6b96018b2   Arnd Bergmann   compat: move sock...
2679
  		if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2680
2681
2682
  			return -EFAULT;
  
  		old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2683
  		set_fs(KERNEL_DS);
c3f52ae6a   stephen hemminger   socket: suppress ...
2684
2685
  		err = dev_ioctl(net, cmd,
  				(struct ifreq __user __force *) &kifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2686
  		set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2687
2688
  
  		return err;
7a229387d   Arnd Bergmann   net: copy socket ...
2689
  	default:
07d106d0a   Linus Torvalds   vfs: fix up ENOIO...
2690
  		return -ENOIOCTLCMD;
ccbd6a5a4   Joe Perches   net: Remove unnec...
2691
  	}
7a229387d   Arnd Bergmann   net: copy socket ...
2692
  }
590d4693f   Ben Hutchings   net/compat: Merge...
2693
2694
  /* 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...
2695
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
2696
2697
  {
  	struct ifreq __user *u_ifreq64;
7a229387d   Arnd Bergmann   net: copy socket ...
2698
2699
2700
2701
2702
2703
2704
  	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...
2705
  	if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2706
2707
2708
2709
  		return -EFAULT;
  	data64 = compat_ptr(data32);
  
  	u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
7a229387d   Arnd Bergmann   net: copy socket ...
2710
2711
2712
  	if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
  			 IFNAMSIZ))
  		return -EFAULT;
417c3522b   Ben Hutchings   net/compat: Fix m...
2713
  	if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
7a229387d   Arnd Bergmann   net: copy socket ...
2714
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2715
  	return dev_ioctl(net, cmd, u_ifreq64);
7a229387d   Arnd Bergmann   net: copy socket ...
2716
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2717
2718
  static int dev_ifsioc(struct net *net, struct socket *sock,
  			 unsigned int cmd, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2719
  {
a2116ed22   Arnd Bergmann   net/compat: fix d...
2720
  	struct ifreq __user *uifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2721
  	int err;
a2116ed22   Arnd Bergmann   net/compat: fix d...
2722
2723
2724
2725
2726
  	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 ...
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
  	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...
2739
  		case SIOCGIFPFLAGS:
7a229387d   Arnd Bergmann   net: copy socket ...
2740
  		case SIOCGIFTXQLEN:
fab2532ba   Arnd Bergmann   net, compat_ioctl...
2741
2742
  		case SIOCGMIIPHY:
  		case SIOCGMIIREG:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2743
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
7a229387d   Arnd Bergmann   net: copy socket ...
2744
2745
2746
2747
2748
2749
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
  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 ...
2760
2761
2762
2763
2764
2765
  	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...
2766
2767
2768
2769
  	if (err)
  		return -EFAULT;
  
  	old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2770
  	set_fs(KERNEL_DS);
c3f52ae6a   stephen hemminger   socket: suppress ...
2771
  	err = dev_ioctl(net, cmd, (void  __user __force *)&ifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2772
  	set_fs(old_fs);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2773
2774
2775
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2776
2777
2778
2779
2780
2781
  		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...
2782
2783
2784
2785
2786
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2787
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2788
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
2789
2790
2791
  	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...
2792
2793
2794
2795
2796
2797
2798
  	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 ...
2799
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2800
2801
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
  	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...
2817
2818
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2819
2820
2821
2822
2823
2824
2825
2826
  {
  	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...
2827
2828
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2829
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2830
  			3 * sizeof(struct in6_addr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2831
2832
2833
2834
2835
2836
2837
  		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 ...
2838
2839
2840
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
2841
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2842
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2843
  					3 * sizeof(struct sockaddr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
2844
2845
2846
2847
2848
2849
  		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 ...
2850
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2851
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
c3f52ae6a   stephen hemminger   socket: suppress ...
2852
2853
  			r4.rt_dev = (char __user __force *)devname;
  			devname[15] = 0;
7a229387d   Arnd Bergmann   net: copy socket ...
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2864
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2865
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2866
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2867
2868
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
2869
2870
2871
2872
2873
  	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...
2874
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
2875
   */
6b96018b2   Arnd Bergmann   compat: move sock...
2876
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2877
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2878
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
2879

6b96018b2   Arnd Bergmann   compat: move sock...
2880
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
2881
2882
2883
2884
2885
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2886
2887
2888
2889
2890
2891
  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 ...
2892

6b96018b2   Arnd Bergmann   compat: move sock...
2893
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
2894
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
  
  	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:...
2906
2907
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2908
2909
2910
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2911
2912
2913
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
2914
2915
2916
2917
2918
2919
2920
2921
2922
  	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...
2923
2924
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2925
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
2926
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
2927
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
  
  	case FIOSETOWN:
  	case SIOCSPGRP:
  	case FIOGETOWN:
  	case SIOCGPGRP:
  	case SIOCBRADDBR:
  	case SIOCBRDELBR:
  	case SIOCGIFVLAN:
  	case SIOCSIFVLAN:
  	case SIOCADDDLCI:
  	case SIOCDELDLCI:
  		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...
2954
2955
2956
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
2957
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
  	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...
2970
2971
2972
2973
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
6b96018b2   Arnd Bergmann   compat: move sock...
2974
  		return dev_ifsioc(net, sock, cmd, argp);
9177efd39   Arnd Bergmann   net, compat_ioctl...
2975

6b96018b2   Arnd Bergmann   compat: move sock...
2976
2977
2978
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
6b96018b2   Arnd Bergmann   compat: move sock...
2979
  	case SIOCATMARK:
9177efd39   Arnd Bergmann   net, compat_ioctl...
2980
2981
  		return sock_do_ioctl(net, sock, cmd, arg);
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
2982
2983
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2984

95c961747   Eric Dumazet   net: cleanup unsi...
2985
  static long compat_sock_ioctl(struct file *file, unsigned int cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2986
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2987
2988
2989
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
2990
2991
2992
2993
2994
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2995
2996
2997
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
2998
2999
3000
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
3001
3002
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3003
3004
3005
  	return ret;
  }
  #endif
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3006
3007
3008
3009
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3010
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3011
3012
3013
3014
3015
  
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3016
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
  
  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;
  
  	err = sock->ops->accept(sock, *newsock, flags);
  	if (err < 0) {
  		sock_release(*newsock);
fa8705b00   Tony Battersby   [NET]: sanitize k...
3031
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3032
3033
3034
3035
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
3036
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3037
3038
3039
3040
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3041
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3042
3043
  
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
3044
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3045
3046
3047
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3048
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3049
3050
3051
3052
3053
3054
  
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 0);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3055
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3056
3057
3058
3059
3060
3061
  
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 1);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3062
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3063
3064
3065
3066
3067
  
  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...
3068
3069
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3070
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3071
3072
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3073
3074
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3075
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3076
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3077
3078
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3079
3080
3081
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3082
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3083
3084
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
3085
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3086
3087
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3088
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3089
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3090
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3091
3092
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3093
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3094
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3095
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3096
3097
3098
3099
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3100
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3101
3102
3103
3104
3105
3106
3107
3108
3109
  
  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...
3110
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
  
  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...
3123
  EXPORT_SYMBOL(kernel_sock_ioctl);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3124

91cf45f02   Trond Myklebust   [NET]: Add the he...
3125
3126
3127
3128
  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...
3129
  EXPORT_SYMBOL(kernel_sock_shutdown);