Blame view

net/socket.c 74.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   * NET		An implementation of the SOCKET network access protocol.
   *
   * Version:	@(#)socket.c	1.1.93	18/02/95
   *
   * Authors:	Orest Zborowski, <obz@Kodak.COM>
02c30a84e   Jesper Juhl   [PATCH] update Ro...
7
   *		Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
   *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   *
   * Fixes:
   *		Anonymous	:	NOTSOCK/BADF cleanup. Error fix in
   *					shutdown()
   *		Alan Cox	:	verify_area() fixes
   *		Alan Cox	:	Removed DDI
   *		Jonathan Kamens	:	SOCK_DGRAM reconnect bug
   *		Alan Cox	:	Moved a load of checks to the very
   *					top level.
   *		Alan Cox	:	Move address structures to/from user
   *					mode above the protocol layers.
   *		Rob Janssen	:	Allow 0 length sends.
   *		Alan Cox	:	Asynchronous I/O support (cribbed from the
   *					tty drivers).
   *		Niibe Yutaka	:	Asynchronous I/O for writes (4.4BSD style)
   *		Jeff Uphoff	:	Made max number of sockets command-line
   *					configurable.
   *		Matti Aarnio	:	Made the number of sockets dynamic,
   *					to be allocated when needed, and mr.
   *					Uphoff's max is used as max to be
   *					allowed to allocate.
   *		Linus		:	Argh. removed all the socket allocation
   *					altogether: it's in the inode now.
   *		Alan Cox	:	Made sock_alloc()/sock_release() public
   *					for NetROM and future kernel nfsd type
   *					stuff.
   *		Alan Cox	:	sendmsg/recvmsg basics.
   *		Tom Dyas	:	Export net symbols.
   *		Marcin Dalecki	:	Fixed problems with CONFIG_NET="n".
   *		Alan Cox	:	Added thread locking to sys_* calls
   *					for sockets. May have errors at the
   *					moment.
   *		Kevin Buhr	:	Fixed the dumb errors in the above.
   *		Andi Kleen	:	Some small cleanups, optimizations,
   *					and fixed a copy_from_user() bug.
   *		Tigran Aivazian	:	sys_send(args) calls sys_sendto(args, NULL, 0)
89bddce58   Stephen Hemminger   [NET] socket: cod...
45
   *		Tigran Aivazian	:	Made listen(2) backlog sanity checks
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
47
48
49
50
51
52
53
54
55
   *					protocol-independent
   *
   *
   *		This program is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   *
   *
   *	This module is effectively the top level interface to the BSD socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
56
   *	paradigm.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
   *
   *	Based upon Swansea University Computer Society NET3.039
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
  #include <linux/socket.h>
  #include <linux/file.h>
  #include <linux/net.h>
  #include <linux/interrupt.h>
aaca0bdca   Ulrich Drepper   flag parameters: ...
65
  #include <linux/thread_info.h>
55737fda0   Stephen Hemminger   [NET]: socket fam...
66
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
  #include <linux/netdevice.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
70
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
  #include <linux/wanrouter.h>
  #include <linux/if_bridge.h>
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
73
74
  #include <linux/if_frad.h>
  #include <linux/if_vlan.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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
91
92
93
94
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
  
  #include <net/compat.h>
87de87d5e   David S. Miller   wext: Dispatch an...
95
  #include <net/wext.h>
f84517253   Herbert Xu   cls_cgroup: Store...
96
  #include <net/cls_cgroup.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  
  #include <net/sock.h>
  #include <linux/netfilter.h>
6b96018b2   Arnd Bergmann   compat: move sock...
100
101
102
  #include <linux/if_tun.h>
  #include <linux/ipv6_route.h>
  #include <linux/route.h>
6b96018b2   Arnd Bergmann   compat: move sock...
103
104
  #include <linux/sockios.h>
  #include <linux/atalk.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
027445c37   Badari Pulavarty   [PATCH] Vectorize...
106
107
108
109
  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
  			 unsigned long nr_segs, loff_t pos);
  static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
  			  unsigned long nr_segs, loff_t pos);
89bddce58   Stephen Hemminger   [NET] socket: cod...
110
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
  
  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...
115
  static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
116
117
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file,
89bddce58   Stephen Hemminger   [NET] socket: cod...
118
  			      unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
119
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  static int sock_fasync(int fd, struct file *filp, int on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  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...
123
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
124
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
125
  				unsigned int flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
  /*
   *	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...
131
  static const struct file_operations socket_file_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
136
137
  	.owner =	THIS_MODULE,
  	.llseek =	no_llseek,
  	.aio_read =	sock_aio_read,
  	.aio_write =	sock_aio_write,
  	.poll =		sock_poll,
  	.unlocked_ioctl = sock_ioctl,
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
138
139
140
  #ifdef CONFIG_COMPAT
  	.compat_ioctl = compat_sock_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
  	.mmap =		sock_mmap,
  	.open =		sock_no_open,	/* special open code to disallow open via /proc */
  	.release =	sock_close,
  	.fasync =	sock_fasync,
5274f052e   Jens Axboe   [PATCH] Introduce...
145
146
  	.sendpage =	sock_sendpage,
  	.splice_write = generic_splice_sendpage,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
147
  	.splice_read =	sock_splice_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
150
151
152
  };
  
  /*
   *	The protocol list. Each protocol is registered in here.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  static DEFINE_SPINLOCK(net_family_lock);
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
154
  static const struct net_proto_family *net_families[NPROTO] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155

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

11165f145   stephen hemminger   socket: localize ...
204
205
  static int move_addr_to_user(struct sockaddr *kaddr, int klen,
  			     void __user *uaddr, int __user *ulen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
208
  {
  	int err;
  	int len;
89bddce58   Stephen Hemminger   [NET] socket: cod...
209
210
  	err = get_user(len, ulen);
  	if (err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
212
213
  	if (len > klen)
  		len = klen;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
214
  	if (len < 0 || len > sizeof(struct sockaddr_storage))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
216
  	if (len) {
d6fe3945b   Steve Grubb   [PATCH] sockaddr ...
217
218
  		if (audit_sockaddr(klen, kaddr))
  			return -ENOMEM;
89bddce58   Stephen Hemminger   [NET] socket: cod...
219
  		if (copy_to_user(uaddr, kaddr, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
221
222
  			return -EFAULT;
  	}
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
223
224
  	 *      "fromlen shall refer to the value before truncation.."
  	 *                      1003.1g
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
227
  	 */
  	return __put_user(klen, ulen);
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
228
  static struct kmem_cache *sock_inode_cachep __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
  
  static struct inode *sock_alloc_inode(struct super_block *sb)
  {
  	struct socket_alloc *ei;
89bddce58   Stephen Hemminger   [NET] socket: cod...
233

e94b17660   Christoph Lameter   [PATCH] slab: rem...
234
  	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
  	if (!ei)
  		return NULL;
438154823   Eric Dumazet   net: sock_def_rea...
237
238
239
240
241
242
243
  	ei->socket.wq = kmalloc(sizeof(struct socket_wq), GFP_KERNEL);
  	if (!ei->socket.wq) {
  		kmem_cache_free(sock_inode_cachep, ei);
  		return NULL;
  	}
  	init_waitqueue_head(&ei->socket.wq->wait);
  	ei->socket.wq->fasync_list = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
244

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
  	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
250
251
252
  
  	return &ei->vfs_inode;
  }
438154823   Eric Dumazet   net: sock_def_rea...
253
254
255
256
257
258
259
  
  static void wq_free_rcu(struct rcu_head *head)
  {
  	struct socket_wq *wq = container_of(head, struct socket_wq, rcu);
  
  	kfree(wq);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
  static void sock_destroy_inode(struct inode *inode)
  {
438154823   Eric Dumazet   net: sock_def_rea...
262
263
264
265
266
  	struct socket_alloc *ei;
  
  	ei = container_of(inode, struct socket_alloc, vfs_inode);
  	call_rcu(&ei->socket.wq->rcu, wq_free_rcu);
  	kmem_cache_free(sock_inode_cachep, ei);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
268
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
270
  	struct socket_alloc *ei = (struct socket_alloc *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
  static int init_inodecache(void)
  {
  	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
89bddce58   Stephen Hemminger   [NET] socket: cod...
278
279
280
281
282
  					      sizeof(struct socket_alloc),
  					      0,
  					      (SLAB_HWCACHE_ALIGN |
  					       SLAB_RECLAIM_ACCOUNT |
  					       SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
283
  					      init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
287
  	if (sock_inode_cachep == NULL)
  		return -ENOMEM;
  	return 0;
  }
b87221de6   Alexey Dobriyan   const: mark remai...
288
  static const struct super_operations sockfs_ops = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
289
290
291
  	.alloc_inode	= sock_alloc_inode,
  	.destroy_inode	= sock_destroy_inode,
  	.statfs		= simple_statfs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  };
51139adac   Al Viro   convert get_sb_ps...
293
294
  static struct dentry *sockfs_mount(struct file_system_type *fs_type,
  			 int flags, const char *dev_name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  {
51139adac   Al Viro   convert get_sb_ps...
296
  	return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  }
ba89966c1   Eric Dumazet   [NET]: use __read...
298
  static struct vfsmount *sock_mnt __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
300
301
  
  static struct file_system_type sock_fs_type = {
  	.name =		"sockfs",
51139adac   Al Viro   convert get_sb_ps...
302
  	.mount =	sockfs_mount,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
  	.kill_sb =	kill_anon_super,
  };
89bddce58   Stephen Hemminger   [NET] socket: cod...
305

c23fbb6bc   Eric Dumazet   VFS: delay the de...
306
307
308
309
310
311
312
313
  /*
   * 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]",
  				dentry->d_inode->i_ino);
  }
3ba13d179   Al Viro   constify dentry_o...
314
  static const struct dentry_operations sockfs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
315
  	.d_dname  = sockfs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
318
319
320
  };
  
  /*
   *	Obtains the first available file descriptor and sets it up for use.
   *
39d8c1b6f   David S. Miller   [NET]: Do not los...
321
322
   *	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
323
324
325
326
327
328
329
330
331
332
333
   *	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.
   */
7cbe66b6b   Al Viro   merge sock_alloc_...
334
  static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  {
7cbe66b6b   Al Viro   merge sock_alloc_...
336
  	struct qstr name = { .name = "" };
2c48b9c45   Al Viro   switch alloc_file...
337
  	struct path path;
7cbe66b6b   Al Viro   merge sock_alloc_...
338
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  	int fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340

a677a039b   Ulrich Drepper   flag parameters: ...
341
  	fd = get_unused_fd_flags(flags);
7cbe66b6b   Al Viro   merge sock_alloc_...
342
343
  	if (unlikely(fd < 0))
  		return fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344

2c48b9c45   Al Viro   switch alloc_file...
345
346
  	path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
  	if (unlikely(!path.dentry)) {
7cbe66b6b   Al Viro   merge sock_alloc_...
347
  		put_unused_fd(fd);
39d8c1b6f   David S. Miller   [NET]: Do not los...
348
  		return -ENOMEM;
7cbe66b6b   Al Viro   merge sock_alloc_...
349
  	}
2c48b9c45   Al Viro   switch alloc_file...
350
  	path.mnt = mntget(sock_mnt);
39d8c1b6f   David S. Miller   [NET]: Do not los...
351

2c48b9c45   Al Viro   switch alloc_file...
352
  	path.dentry->d_op = &sockfs_dentry_operations;
2c48b9c45   Al Viro   switch alloc_file...
353
  	d_instantiate(path.dentry, SOCK_INODE(sock));
cc3808f8c   Al Viro   switch sock_alloc...
354
  	SOCK_INODE(sock)->i_fop = &socket_file_ops;
39d8c1b6f   David S. Miller   [NET]: Do not los...
355

2c48b9c45   Al Viro   switch alloc_file...
356
  	file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
357
  		  &socket_file_ops);
cc3808f8c   Al Viro   switch sock_alloc...
358
359
  	if (unlikely(!file)) {
  		/* drop dentry, keep inode */
7de9c6ee3   Al Viro   new helper: ihold()
360
  		ihold(path.dentry->d_inode);
2c48b9c45   Al Viro   switch alloc_file...
361
  		path_put(&path);
cc3808f8c   Al Viro   switch sock_alloc...
362
363
364
365
366
  		put_unused_fd(fd);
  		return -ENFILE;
  	}
  
  	sock->file = file;
77d272005   Ulrich Drepper   flag parameters: ...
367
  	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
39d8c1b6f   David S. Miller   [NET]: Do not los...
368
369
  	file->f_pos = 0;
  	file->private_data = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370

7cbe66b6b   Al Viro   merge sock_alloc_...
371
372
  	*f = file;
  	return fd;
39d8c1b6f   David S. Miller   [NET]: Do not los...
373
  }
a677a039b   Ulrich Drepper   flag parameters: ...
374
  int sock_map_fd(struct socket *sock, int flags)
39d8c1b6f   David S. Miller   [NET]: Do not los...
375
376
  {
  	struct file *newfile;
7cbe66b6b   Al Viro   merge sock_alloc_...
377
  	int fd = sock_alloc_file(sock, &newfile, flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
378

7cbe66b6b   Al Viro   merge sock_alloc_...
379
  	if (likely(fd >= 0))
39d8c1b6f   David S. Miller   [NET]: Do not los...
380
  		fd_install(fd, newfile);
7cbe66b6b   Al Viro   merge sock_alloc_...
381

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
383
  	return fd;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
384
  EXPORT_SYMBOL(sock_map_fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
386
387
  static struct socket *sock_from_file(struct file *file, int *err)
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
388
389
  	if (file->f_op == &socket_file_ops)
  		return file->private_data;	/* set in sock_map_fd */
23bb80d21   Eric Dumazet   [NET]: cleanup so...
390
391
  	*err = -ENOTSOCK;
  	return NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
392
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  /**
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
394
   *	sockfd_lookup - Go from a file number to its socket slot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
398
399
400
401
402
403
404
405
406
407
408
   *	@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
409
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
410
411
  	file = fget(fd);
  	if (!file) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
  		*err = -EBADF;
  		return NULL;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
415

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
416
417
  	sock = sock_from_file(file, err);
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
  		fput(file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
419
420
  	return sock;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
421
  EXPORT_SYMBOL(sockfd_lookup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
423
424
425
426
  static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
  {
  	struct file *file;
  	struct socket *sock;
3672558c6   Hua Zhong   [NET]: sockfd_loo...
427
  	*err = -EBADF;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
428
429
430
431
432
433
  	file = fget_light(fd, fput_needed);
  	if (file) {
  		sock = sock_from_file(file, err);
  		if (sock)
  			return sock;
  		fput_light(file, *fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
435
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
437
438
439
  }
  
  /**
   *	sock_alloc	-	allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
440
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
445
446
447
   *	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.
   */
  
  static struct socket *sock_alloc(void)
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
448
449
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
451
452
453
454
455
  
  	inode = new_inode(sock_mnt->mnt_sb);
  	if (!inode)
  		return NULL;
  
  	sock = SOCKET_I(inode);
29a020d35   Eric Dumazet   [PATCH] net: kmem...
456
  	kmemcheck_annotate_bitfield(sock, type);
85fe4025c   Christoph Hellwig   fs: do not assign...
457
  	inode->i_ino = get_next_ino();
89bddce58   Stephen Hemminger   [NET] socket: cod...
458
  	inode->i_mode = S_IFSOCK | S_IRWXUGO;
8192b0c48   David Howells   CRED: Wrap task c...
459
460
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461

4e69489a0   Eric Dumazet   socket: use percp...
462
  	percpu_add(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
465
466
467
468
469
470
  	return sock;
  }
  
  /*
   *	In theory you can't get an open on this inode, but /proc provides
   *	a back door. Remember to keep it shut otherwise you'll let the
   *	creepy crawlies in.
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
471

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
  static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
  {
  	return -ENXIO;
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
476
  const struct file_operations bad_sock_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
  	.owner = THIS_MODULE,
  	.open = sock_no_open,
6038f373a   Arnd Bergmann   llseek: automatic...
479
  	.llseek = noop_llseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
482
483
484
485
486
487
  };
  
  /**
   *	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...
488
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
490

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
494
495
496
497
498
499
  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);
  	}
438154823   Eric Dumazet   net: sock_def_rea...
500
  	if (sock->wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
502
  		printk(KERN_ERR "sock_release: fasync list not empty!
  ");
4e69489a0   Eric Dumazet   socket: use percp...
503
  	percpu_sub(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
506
507
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
508
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
510
  EXPORT_SYMBOL(sock_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511

2244d07bf   Oliver Hartkopp   net: simplify fla...
512
  int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
20d494735   Patrick Ohly   net: socket infra...
513
  {
2244d07bf   Oliver Hartkopp   net: simplify fla...
514
  	*tx_flags = 0;
20d494735   Patrick Ohly   net: socket infra...
515
  	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
2244d07bf   Oliver Hartkopp   net: simplify fla...
516
  		*tx_flags |= SKBTX_HW_TSTAMP;
20d494735   Patrick Ohly   net: socket infra...
517
  	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
2244d07bf   Oliver Hartkopp   net: simplify fla...
518
  		*tx_flags |= SKBTX_SW_TSTAMP;
20d494735   Patrick Ohly   net: socket infra...
519
520
521
  	return 0;
  }
  EXPORT_SYMBOL(sock_tx_timestamp);
89bddce58   Stephen Hemminger   [NET] socket: cod...
522
  static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
525
526
  				 struct msghdr *msg, size_t size)
  {
  	struct sock_iocb *si = kiocb_to_siocb(iocb);
  	int err;
f84517253   Herbert Xu   cls_cgroup: Store...
527
  	sock_update_classid(sock->sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
  	si->sock = sock;
  	si->scm = NULL;
  	si->msg = msg;
  	si->size = size;
  
  	err = security_socket_sendmsg(sock, msg, size);
  	if (err)
  		return err;
  
  	return sock->ops->sendmsg(iocb, sock, msg, size);
  }
  
  int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
  {
  	struct kiocb iocb;
  	struct sock_iocb siocb;
  	int ret;
  
  	init_sync_kiocb(&iocb, NULL);
  	iocb.private = &siocb;
  	ret = __sock_sendmsg(&iocb, sock, msg, size);
  	if (-EIOCBQUEUED == ret)
  		ret = wait_on_sync_kiocb(&iocb);
  	return ret;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
553
  EXPORT_SYMBOL(sock_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
556
557
558
559
560
561
562
563
564
565
  
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size)
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
  
  	set_fs(KERNEL_DS);
  	/*
  	 * the following is safe, since for compiler definitions of kvec and
  	 * iovec are identical, yielding the same in-core layout and alignment
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
566
  	msg->msg_iov = (struct iovec *)vec;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
568
569
570
571
  	msg->msg_iovlen = num;
  	result = sock_sendmsg(sock, msg, size);
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
572
  EXPORT_SYMBOL(kernel_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573

20d494735   Patrick Ohly   net: socket infra...
574
575
576
577
578
579
580
581
582
  static int ktime2ts(ktime_t kt, struct timespec *ts)
  {
  	if (kt.tv64) {
  		*ts = ktime_to_timespec(kt);
  		return 1;
  	} else {
  		return 0;
  	}
  }
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
583
584
585
586
587
588
  /*
   * 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...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
  	struct timespec ts[3];
  	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 {
842509b85   Hagen Paul Pfeifer   socket: remove du...
607
  			skb_get_timestampns(skb, &ts[0]);
20d494735   Patrick Ohly   net: socket infra...
608
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
842509b85   Hagen Paul Pfeifer   socket: remove du...
609
  				 sizeof(ts[0]), &ts[0]);
20d494735   Patrick Ohly   net: socket infra...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  		}
  	}
  
  
  	memset(ts, 0, sizeof(ts));
  	if (skb->tstamp.tv64 &&
  	    sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) {
  		skb_get_timestampns(skb, ts + 0);
  		empty = 0;
  	}
  	if (shhwtstamps) {
  		if (sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE) &&
  		    ktime2ts(shhwtstamps->syststamp, ts + 1))
  			empty = 0;
  		if (sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE) &&
  		    ktime2ts(shhwtstamps->hwtstamp, ts + 2))
  			empty = 0;
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
627
  	}
20d494735   Patrick Ohly   net: socket infra...
628
629
630
  	if (!empty)
  		put_cmsg(msg, SOL_SOCKET,
  			 SCM_TIMESTAMPING, sizeof(ts), &ts);
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
631
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
632
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
11165f145   stephen hemminger   socket: localize ...
633
634
  static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
  				   struct sk_buff *skb)
3b885787e   Neil Horman   net: Generalize s...
635
636
637
638
639
  {
  	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount)
  		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
  			sizeof(__u32), &skb->dropcount);
  }
767dd0336   Eric Dumazet   net: speedup sock...
640
  void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
3b885787e   Neil Horman   net: Generalize s...
641
642
643
644
645
  	struct sk_buff *skb)
  {
  	sock_recv_timestamp(msg, sk, skb);
  	sock_recv_drops(msg, sk, skb);
  }
767dd0336   Eric Dumazet   net: speedup sock...
646
  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
3b885787e   Neil Horman   net: Generalize s...
647

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
648
649
  static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,
  				       struct msghdr *msg, size_t size, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  	struct sock_iocb *si = kiocb_to_siocb(iocb);
f84517253   Herbert Xu   cls_cgroup: Store...
652
  	sock_update_classid(sock->sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
654
655
656
657
  	si->sock = sock;
  	si->scm = NULL;
  	si->msg = msg;
  	si->size = size;
  	si->flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
  	return sock->ops->recvmsg(iocb, sock, msg, size, flags);
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
660
661
662
663
664
665
666
  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
  				 struct msghdr *msg, size_t size, int flags)
  {
  	int err = security_socket_recvmsg(sock, msg, size, flags);
  
  	return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
667
  int sock_recvmsg(struct socket *sock, struct msghdr *msg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
670
671
672
  		 size_t size, int flags)
  {
  	struct kiocb iocb;
  	struct sock_iocb siocb;
  	int ret;
89bddce58   Stephen Hemminger   [NET] socket: cod...
673
  	init_sync_kiocb(&iocb, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
676
677
678
679
  	iocb.private = &siocb;
  	ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
  	if (-EIOCBQUEUED == ret)
  		ret = wait_on_sync_kiocb(&iocb);
  	return ret;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
680
  EXPORT_SYMBOL(sock_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
  static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
  			      size_t size, int flags)
  {
  	struct kiocb iocb;
  	struct sock_iocb siocb;
  	int ret;
  
  	init_sync_kiocb(&iocb, NULL);
  	iocb.private = &siocb;
  	ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags);
  	if (-EIOCBQUEUED == ret)
  		ret = wait_on_sync_kiocb(&iocb);
  	return ret;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
696
697
  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
698
699
700
701
702
703
704
705
706
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
  
  	set_fs(KERNEL_DS);
  	/*
  	 * the following is safe, since for compiler definitions of kvec and
  	 * iovec are identical, yielding the same in-core layout and alignment
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
707
  	msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
709
710
711
  	result = sock_recvmsg(sock, msg, size, flags);
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
712
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
714
715
716
717
  
  static void sock_aio_dtor(struct kiocb *iocb)
  {
  	kfree(iocb->private);
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
718
719
  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
720
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
722
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
723
724
725
726
727
  	sock = file->private_data;
  
  	flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
  	if (more)
  		flags |= MSG_MORE;
e69495838   Linus Torvalds   Make sock_sendpag...
728
  	return kernel_sendpage(sock, page, offset, size, flags);
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
729
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
731
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
732
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
733
734
735
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
736
737
  	if (unlikely(!sock->ops->splice_read))
  		return -EINVAL;
f84517253   Herbert Xu   cls_cgroup: Store...
738
  	sock_update_classid(sock->sk);
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
739
740
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
741
  static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
89bddce58   Stephen Hemminger   [NET] socket: cod...
742
  					 struct sock_iocb *siocb)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
743
744
745
746
747
  {
  	if (!is_sync_kiocb(iocb)) {
  		siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
  		if (!siocb)
  			return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
  		iocb->ki_dtor = sock_aio_dtor;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
751
  	siocb->kiocb = iocb;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
752
753
  	iocb->private = siocb;
  	return siocb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
755
  static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
027445c37   Badari Pulavarty   [PATCH] Vectorize...
756
757
  		struct file *file, const struct iovec *iov,
  		unsigned long nr_segs)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
758
759
760
761
  {
  	struct socket *sock = file->private_data;
  	size_t size = 0;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762

89bddce58   Stephen Hemminger   [NET] socket: cod...
763
764
  	for (i = 0; i < nr_segs; i++)
  		size += iov[i].iov_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
766
767
768
769
  	msg->msg_name = NULL;
  	msg->msg_namelen = 0;
  	msg->msg_control = NULL;
  	msg->msg_controllen = 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
770
  	msg->msg_iov = (struct iovec *)iov;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
771
772
773
774
775
  	msg->msg_iovlen = nr_segs;
  	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
  
  	return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
  }
027445c37   Badari Pulavarty   [PATCH] Vectorize...
776
777
  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
  				unsigned long nr_segs, loff_t pos)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
778
779
  {
  	struct sock_iocb siocb, *x;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
  	if (pos != 0)
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
782
783
  
  	if (iocb->ki_left == 0)	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  		return 0;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
785
786
  
  	x = alloc_sock_iocb(iocb, &siocb);
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
787
788
  	if (!x)
  		return -ENOMEM;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
789
  	return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
791
  static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
027445c37   Badari Pulavarty   [PATCH] Vectorize...
792
793
  			struct file *file, const struct iovec *iov,
  			unsigned long nr_segs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
  {
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
795
796
797
  	struct socket *sock = file->private_data;
  	size_t size = 0;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798

89bddce58   Stephen Hemminger   [NET] socket: cod...
799
800
  	for (i = 0; i < nr_segs; i++)
  		size += iov[i].iov_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
802
803
804
805
  	msg->msg_name = NULL;
  	msg->msg_namelen = 0;
  	msg->msg_control = NULL;
  	msg->msg_controllen = 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
806
  	msg->msg_iov = (struct iovec *)iov;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
807
808
809
810
  	msg->msg_iovlen = nr_segs;
  	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
  	if (sock->type == SOCK_SEQPACKET)
  		msg->msg_flags |= MSG_EOR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
812
  	return __sock_sendmsg(iocb, sock, msg, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
  }
027445c37   Badari Pulavarty   [PATCH] Vectorize...
814
815
  static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
  			  unsigned long nr_segs, loff_t pos)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
816
817
  {
  	struct sock_iocb siocb, *x;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
819
820
  	if (pos != 0)
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
821

027445c37   Badari Pulavarty   [PATCH] Vectorize...
822
  	x = alloc_sock_iocb(iocb, &siocb);
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
823
824
  	if (!x)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825

027445c37   Badari Pulavarty   [PATCH] Vectorize...
826
  	return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
830
831
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
832
  static DEFINE_MUTEX(br_ioctl_mutex);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
833
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834

881d966b4   Eric W. Biederman   [NET]: Make the d...
835
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
837
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
839
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
841
  }
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
842
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
843
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844

881d966b4   Eric W. Biederman   [NET]: Make the d...
845
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
847
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
849
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
851
  }
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
852
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
853
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854

89bddce58   Stephen Hemminger   [NET] socket: cod...
855
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
857
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
859
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  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
879
880
881
882
883
884
885
886
  /*
   *	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...
887
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
889
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
890
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891

b69aee04f   Eric Dumazet   [NET]: Use file->...
892
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
893
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
894
  	net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
896
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
  	} else
3d23e349d   Johannes Berg   wext: refactor
898
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
900
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  	} else
3d23e349d   Johannes Berg   wext: refactor
902
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
903
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904
905
906
907
908
909
910
911
912
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
  			err = f_setown(sock->file, pid, 1);
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
913
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
914
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
916
917
918
919
920
921
922
  			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: ...
923
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
924
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
925
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
926
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
928
929
930
931
932
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
933
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
935
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
936
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
939
940
941
942
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
943
944
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
946
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947
948
  			break;
  		default:
6b96018b2   Arnd Bergmann   compat: move sock...
949
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
951
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
953
954
955
956
957
958
  	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...
959

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
961
962
963
964
965
966
967
968
  	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
969
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
970
971
972
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
974
975
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
976
977
978
979
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
980
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
981
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982
983
  
  /* No kernel lock held - perfect */
89bddce58   Stephen Hemminger   [NET] socket: cod...
984
  static unsigned int sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
986
987
988
  {
  	struct socket *sock;
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
989
  	 *      We can't return errors to poll, so it's either yes or no.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
  	 */
b69aee04f   Eric Dumazet   [NET]: Use file->...
991
  	sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
993
  	return sock->ops->poll(file, sock, wait);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
994
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
996
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
999
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1000
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1001
1002
  {
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1003
1004
  	 *      It was possible the inode is NULL we were
  	 *      closing an unfinished socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1006
  	if (!inode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
1008
1009
1010
  		printk(KERN_DEBUG "sock_close: NULL inode
  ");
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
  	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...
1023
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1024
1025
1026
1027
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1028
1029
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030

989a29792   Eric Dumazet   fasync: RCU and f...
1031
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1032
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
  
  	lock_sock(sk);
438154823   Eric Dumazet   net: sock_def_rea...
1035
  	fasync_helper(fd, filp, on, &sock->wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036

438154823   Eric Dumazet   net: sock_def_rea...
1037
  	if (!sock->wq->fasync_list)
989a29792   Eric Dumazet   fasync: RCU and f...
1038
1039
  		sock_reset_flag(sk, SOCK_FASYNC);
  	else
bcdce7195   Eric Dumazet   net: speedup sk_w...
1040
  		sock_set_flag(sk, SOCK_FASYNC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041

989a29792   Eric Dumazet   fasync: RCU and f...
1042
  	release_sock(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
1044
  	return 0;
  }
438154823   Eric Dumazet   net: sock_def_rea...
1045
  /* This function may be called only under socket lock or callback_lock or rcu_lock */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1046
1047
1048
  
  int sock_wake_async(struct socket *sock, int how, int band)
  {
438154823   Eric Dumazet   net: sock_def_rea...
1049
1050
1051
1052
1053
1054
1055
1056
  	struct socket_wq *wq;
  
  	if (!sock)
  		return -1;
  	rcu_read_lock();
  	wq = rcu_dereference(sock->wq);
  	if (!wq || !wq->fasync_list) {
  		rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1057
  		return -1;
438154823   Eric Dumazet   net: sock_def_rea...
1058
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1059
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1060
  	case SOCK_WAKE_WAITD:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
1062
1063
  		if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1064
  	case SOCK_WAKE_SPACE:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
1066
1067
  		if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags))
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1068
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1069
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1070
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1072
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1073
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
  	}
438154823   Eric Dumazet   net: sock_def_rea...
1075
  	rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1076
1077
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1078
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079

721db93a5   Pavel Emelyanov   net: Export __soc...
1080
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1081
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1082
1083
1084
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1085
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1086
1087
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1088
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  	 */
  	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) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1101
  		static int warned;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1102
1103
  		if (!warned) {
  			warned = 1;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1104
1105
1106
  			printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			       current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1107
1108
1109
1110
1111
1112
1113
  		}
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1114

55737fda0   Stephen Hemminger   [NET]: socket fam...
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
  	/*
  	 *	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) {
  		if (net_ratelimit())
  			printk(KERN_WARNING "socket: no more sockets
  ");
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1130
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1131
1132
1133
  	/* 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
1134
1135
1136
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1137
  	if (net_families[family] == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1138
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1139
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1140
1141
1142
1143
1144
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1145
1146
1147
1148
1149
  
  	/*
  	 * 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...
1150
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1152
1153
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1154
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1155
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1156
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1157

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1158
1159
1160
1161
  	/*
  	 * 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...
1162
1163
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1164
1165
1166
1167
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1168
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1169
1170
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1171
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1172
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173

55737fda0   Stephen Hemminger   [NET]: socket fam...
1174
1175
1176
1177
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1179
1180
1181
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1182
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1183
1184
1185
1186
1187
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
  }
721db93a5   Pavel Emelyanov   net: Export __soc...
1189
  EXPORT_SYMBOL(__sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1190
1191
1192
  
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1193
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1194
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1195
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1196
1197
1198
  
  int sock_create_kern(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1199
  	return __sock_create(&init_net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1201
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1202

3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1203
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
1205
1206
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1207
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1208
1209
1210
1211
1212
  	/* 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: ...
1213
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1214
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1215
1216
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217

aaca0bdca   Ulrich Drepper   flag parameters: ...
1218
1219
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
1221
1222
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
  		goto out;
77d272005   Ulrich Drepper   flag parameters: ...
1223
  	retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
  	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...
1239
1240
  SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
  		int __user *, usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1241
1242
1243
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1244
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1245
1246
1247
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1248
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1249
1250
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251

aaca0bdca   Ulrich Drepper   flag parameters: ...
1252
1253
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
  	/*
  	 * 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...
1268
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1269
  		goto out_release_both;
7cbe66b6b   Al Viro   merge sock_alloc_...
1270
  	fd1 = sock_alloc_file(sock1, &newfile1, flags);
bf3c23d17   David S. Miller   [NET]: Fix error ...
1271
1272
  	if (unlikely(fd1 < 0)) {
  		err = fd1;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1273
  		goto out_release_both;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1274
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275

7cbe66b6b   Al Viro   merge sock_alloc_...
1276
  	fd2 = sock_alloc_file(sock2, &newfile2, flags);
198de4d7a   Al Viro   reorder alloc_fd/...
1277
1278
1279
1280
1281
1282
  	if (unlikely(fd2 < 0)) {
  		err = fd2;
  		fput(newfile1);
  		put_unused_fd(fd1);
  		sock_release(sock2);
  		goto out;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1283
  	}
157cf649a   Al Viro   sanitize audit_fd...
1284
  	audit_fd_pair(fd1, fd2);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1285
1286
  	fd_install(fd1, newfile1);
  	fd_install(fd2, newfile2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
1288
1289
  	/* fd1 and fd2 may be already another descriptors.
  	 * Not kernel problem.
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1290
  	err = put_user(fd1, &usockvec[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
1292
1293
1294
1295
1296
1297
1298
  	if (!err)
  		err = put_user(fd2, &usockvec[1]);
  	if (!err)
  		return 0;
  
  	sys_close(fd2);
  	sys_close(fd1);
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1299
  out_release_both:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1300
  	sock_release(sock2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
  out_release_1:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1302
  	sock_release(sock1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
1304
1305
  out:
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306
1307
1308
1309
1310
1311
1312
  /*
   *	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...
1313
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
1315
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1316
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1317
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1318

89bddce58   Stephen Hemminger   [NET] socket: cod...
1319
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1320
  	if (sock) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1321
  		err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1322
1323
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1324
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1325
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1326
1327
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1328
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1329
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1330
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1331
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1332
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
1334
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1335
1336
1337
1338
1339
  /*
   *	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...
1340
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1341
1342
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1343
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1344
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1345
1346
1347
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1348
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1349
1350
  		if ((unsigned)backlog > somaxconn)
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
1352
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1353
1354
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1356
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357
1358
1359
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
  /*
   *	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...
1371
1372
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1373
1374
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1375
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1376
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1377
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1378

77d272005   Ulrich Drepper   flag parameters: ...
1379
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1380
1381
1382
1383
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1384
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1385
1386
1387
1388
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1389
1390
  	newsock = sock_alloc();
  	if (!newsock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1391
1392
1393
1394
  		goto out_put;
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395
1396
1397
1398
1399
  	/*
  	 * 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);
7cbe66b6b   Al Viro   merge sock_alloc_...
1400
  	newfd = sock_alloc_file(newsock, &newfile, flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1401
1402
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1403
1404
  		sock_release(newsock);
  		goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1405
  	}
a79af59ef   Frank Filz   [NET]: Fix module...
1406
1407
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1408
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1409

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410
1411
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1412
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
1414
  
  	if (upeer_sockaddr) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1415
  		if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1416
  					  &len, 2) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1417
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1418
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
  		}
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1420
1421
  		err = move_addr_to_user((struct sockaddr *)&address,
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1423
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1424
1425
1426
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1427
1428
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1430
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1431
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1434
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1435
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1436
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1437
1438
  	goto out_put;
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1439
1440
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1441
  {
de11defeb   Ulrich Drepper   reintroduce accept4
1442
  	return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1443
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
  /*
   *	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...
1455
1456
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1457
1458
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1459
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1460
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1461

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1462
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463
1464
  	if (!sock)
  		goto out;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1465
  	err = move_addr_to_kernel(uservaddr, addrlen, (struct sockaddr *)&address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466
1467
  	if (err < 0)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1468
  	err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1469
  	    security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
1471
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1472
  	err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1473
1474
  				 sock->file->f_flags);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1475
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1476
1477
1478
1479
1480
1481
1482
1483
  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...
1484
1485
  SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1486
1487
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1488
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1489
  	int len, err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1490

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1491
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1492
1493
1494
1495
1496
1497
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1498
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
1500
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1501
  	err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502
1503
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1504
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505
1506
1507
1508
1509
1510
1511
1512
  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...
1513
1514
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1517
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1518
  	int len, err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1519

89bddce58   Stephen Hemminger   [NET] socket: cod...
1520
1521
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1522
1523
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1524
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1525
1526
  			return err;
  		}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1527
  		err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1528
  		    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1529
  				       1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530
  		if (!err)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1531
  			err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1532
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1533
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1534
1535
1536
1537
1538
1539
1540
1541
1542
  	}
  	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...
1543
1544
1545
  SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
  		unsigned, flags, struct sockaddr __user *, addr,
  		int, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546
1547
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1548
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
1550
1551
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1552
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1553

253eacc07   Linus Torvalds   net: Truncate rec...
1554
1555
  	if (len > INT_MAX)
  		len = INT_MAX;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1556
1557
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1558
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1559

89bddce58   Stephen Hemminger   [NET] socket: cod...
1560
1561
1562
1563
1564
1565
1566
1567
  	iov.iov_base = buff;
  	iov.iov_len = len;
  	msg.msg_name = NULL;
  	msg.msg_iov = &iov;
  	msg.msg_iovlen = 1;
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1568
  	if (addr) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1569
  		err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1570
1571
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1572
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1573
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1574
1575
1576
1577
1578
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
  	err = sock_sendmsg(sock, &msg, len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1579
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1580
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1581
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1582
1583
1584
1585
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1586
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1587
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1588
1589
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
  		unsigned, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1590
1591
1592
1593
1594
  {
  	return sys_sendto(fd, buff, len, flags, NULL, 0);
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1595
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1596
1597
1598
   *	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...
1599
1600
1601
  SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
  		unsigned, flags, struct sockaddr __user *, addr,
  		int __user *, addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1602
1603
1604
1605
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1606
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1607
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1608
  	int fput_needed;
253eacc07   Linus Torvalds   net: Truncate rec...
1609
1610
  	if (size > INT_MAX)
  		size = INT_MAX;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1611
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1613
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1614

89bddce58   Stephen Hemminger   [NET] socket: cod...
1615
1616
1617
1618
1619
1620
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_iovlen = 1;
  	msg.msg_iov = &iov;
  	iov.iov_len = size;
  	iov.iov_base = ubuf;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1621
1622
  	msg.msg_name = (struct sockaddr *)&address;
  	msg.msg_namelen = sizeof(address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1623
1624
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1625
  	err = sock_recvmsg(sock, &msg, size, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1626

89bddce58   Stephen Hemminger   [NET] socket: cod...
1627
  	if (err >= 0 && addr != NULL) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1628
1629
  		err2 = move_addr_to_user((struct sockaddr *)&address,
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1630
1631
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1633
1634
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1635
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1636
1637
1638
1639
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1640
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1642
1643
  asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size,
  			 unsigned flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1644
1645
1646
1647
1648
1649
1650
1651
  {
  	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...
1652
1653
  SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1655
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1656
1657
1658
1659
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1660
1661
1662
1663
  
  	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...
1664
1665
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1666
1667
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1668
1669
1670
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1671
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1672
1673
1674
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1675
1676
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1677
1678
1679
1680
1681
1682
1683
1684
  	}
  	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...
1685
1686
  SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int __user *, optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1688
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1690
1691
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1692
1693
1694
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1695
1696
  
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1697
1698
1699
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1700
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1701
1702
1703
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1704
1705
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
1707
1708
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
1710
1711
  /*
   *	Shutdown a socket.
   */
754fe8d29   Heiko Carstens   [CVE-2009-0029] S...
1712
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1714
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1716
1717
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1718
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1719
1720
1721
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
1723
1724
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1725
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1726
1727
1728
1729
1730
   * 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)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
1732
1733
  /*
   *	BSD sendmsg interface
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1734
  SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1735
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1736
1737
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1739
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1740
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
b9d717a7b   Alex Williamson   [NET]: Make sure ...
1741
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
89bddce58   Stephen Hemminger   [NET] socket: cod...
1742
1743
  	    __attribute__ ((aligned(sizeof(__kernel_size_t))));
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1744
1745
1746
  	unsigned char *ctl_buf = ctl;
  	struct msghdr msg_sys;
  	int err, ctl_len, iov_size, total_len;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1747
  	int fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1748

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1749
1750
1751
1752
  	err = -EFAULT;
  	if (MSG_CMSG_COMPAT & flags) {
  		if (get_compat_msghdr(&msg_sys, msg_compat))
  			return -EFAULT;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1753
  	} else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1754
  		return -EFAULT;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1755
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1756
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1757
1758
1759
1760
1761
1762
  		goto out;
  
  	/* do not move before msg_sys is valid */
  	err = -EMSGSIZE;
  	if (msg_sys.msg_iovlen > UIO_MAXIOV)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1763
  	/* Check whether to allocate the iovec area */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
  	err = -ENOMEM;
  	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
  	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
  		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
  		if (!iov)
  			goto out_put;
  	}
  
  	/* This will also move the address data into kernel space */
  	if (MSG_CMSG_COMPAT & flags) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1774
1775
1776
  		err = verify_compat_iovec(&msg_sys, iov,
  					  (struct sockaddr *)&address,
  					  VERIFY_READ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1777
  	} else
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1778
1779
1780
  		err = verify_iovec(&msg_sys, iov,
  				   (struct sockaddr *)&address,
  				   VERIFY_READ);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1781
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
1783
1784
1785
1786
1787
1788
  		goto out_freeiov;
  	total_len = err;
  
  	err = -ENOBUFS;
  
  	if (msg_sys.msg_controllen > INT_MAX)
  		goto out_freeiov;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1789
  	ctl_len = msg_sys.msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1790
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1791
1792
1793
  		err =
  		    cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl,
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1794
1795
1796
  		if (err)
  			goto out_freeiov;
  		ctl_buf = msg_sys.msg_control;
8920e8f94   Al Viro   [PATCH] Fix 32bit...
1797
  		ctl_len = msg_sys.msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1798
  	} else if (ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1799
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1800
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1801
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1802
1803
1804
1805
1806
1807
1808
1809
  				goto out_freeiov;
  		}
  		err = -EFAULT;
  		/*
  		 * Careful! Before this, msg_sys.msg_control contains a user pointer.
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
1810
1811
  		if (copy_from_user(ctl_buf,
  				   (void __user __force *)msg_sys.msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1812
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
  			goto out_freectl;
  		msg_sys.msg_control = ctl_buf;
  	}
  	msg_sys.msg_flags = flags;
  
  	if (sock->file->f_flags & O_NONBLOCK)
  		msg_sys.msg_flags |= MSG_DONTWAIT;
  	err = sock_sendmsg(sock, &msg_sys, total_len);
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1823
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1824
1825
1826
1827
1828
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
  out_freeiov:
  	if (iov != iovstack)
  		sock_kfree_s(sock->sk, iov, iov_size);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1829
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1830
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1831
1832
  	return err;
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1833
1834
  static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
  			 struct msghdr *msg_sys, unsigned flags, int nosec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1835
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1836
1837
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1838
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
1839
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1840
1841
1842
1843
  	unsigned long cmsg_ptr;
  	int err, iov_size, total_len, len;
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1844
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1845
1846
1847
1848
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
  	int __user *uaddr_len;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1849

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1850
  	if (MSG_CMSG_COMPAT & flags) {
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1851
  		if (get_compat_msghdr(msg_sys, msg_compat))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1852
  			return -EFAULT;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1853
  	} else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
89bddce58   Stephen Hemminger   [NET] socket: cod...
1854
  		return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1855

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1856
  	err = -EMSGSIZE;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1857
1858
  	if (msg_sys->msg_iovlen > UIO_MAXIOV)
  		goto out;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1859
1860
  
  	/* Check whether to allocate the iovec area */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1861
  	err = -ENOMEM;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1862
1863
  	iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
  	if (msg_sys->msg_iovlen > UIO_FASTIOV) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1864
1865
  		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
  		if (!iov)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1866
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1867
1868
1869
  	}
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1870
1871
  	 *      Save the user-mode address (verify_iovec will change the
  	 *      kernel msghdr to use the kernel address space)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1872
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1873

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1874
  	uaddr = (__force void __user *)msg_sys->msg_name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
1876
  	uaddr_len = COMPAT_NAMELEN(msg);
  	if (MSG_CMSG_COMPAT & flags) {
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1877
  		err = verify_compat_iovec(msg_sys, iov,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1878
1879
  					  (struct sockaddr *)&addr,
  					  VERIFY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
  	} else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1881
  		err = verify_iovec(msg_sys, iov,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1882
1883
  				   (struct sockaddr *)&addr,
  				   VERIFY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1884
1885
  	if (err < 0)
  		goto out_freeiov;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1886
  	total_len = err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1887

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1888
1889
  	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...
1890

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1891
1892
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1893
1894
  	err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
  							  total_len, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
1896
1897
1898
1899
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1900
  		err = move_addr_to_user((struct sockaddr *)&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1901
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1902
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
1904
1905
  		if (err < 0)
  			goto out_freeiov;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1906
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
1907
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1908
1909
1910
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1911
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1912
1913
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1914
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
1916
1917
1918
1919
1920
1921
1922
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
  	if (iov != iovstack)
  		sock_kfree_s(sock->sk, iov, iov_size);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
  out:
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
  
  SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
  		unsigned int, flags)
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
  	struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
  
  	if (!sock)
  		goto out;
  
  	err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1942
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1943
1944
1945
  out:
  	return err;
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
  /*
   *     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...
1956
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
  	struct msghdr msg_sys;
  	struct timespec end_time;
  
  	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...
1976
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1977
1978
1979
1980
1981
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
  		if (MSG_CMSG_COMPAT & flags) {
  			err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
  					    &msg_sys, flags, datagrams);
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
  			err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
  					    &msg_sys, flags, datagrams);
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1997
1998
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
1999
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2000
2001
2002
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
  		if (timeout) {
  			ktime_get_ts(timeout);
  			*timeout = timespec_sub(end_time, *timeout);
  			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;
  	}
  
  out_put:
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
  	if (err == 0)
  		return datagrams;
  
  	if (datagrams != 0) {
  		/*
  		 * We may return less entries than requested (vlen) if the
  		 * sock is non block and there aren't enough datagrams...
  		 */
  		if (err != -EAGAIN) {
  			/*
  			 * ... 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).
  			 */
  			sock->sk->sk_err = -err;
  		}
  
  		return datagrams;
  	}
  
  	return err;
  }
  
  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;
  
  	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
2071
2072
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2073
  static const unsigned char nargs[20] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2074
2075
2076
2077
  	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),
  	AL(4), AL(5)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2078
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2079
2080
2081
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2082
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2083
2084
2085
   *
   *	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...
2086
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2087
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2088
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2089
2090
  {
  	unsigned long a[6];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2091
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2092
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2093
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2094

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2095
  	if (call < 1 || call > SYS_RECVMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2096
  		return -EINVAL;
47379052b   Arjan van de Ven   net: Add explicit...
2097
2098
2099
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2100
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2101
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2102
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2103

f3298dc4f   Al Viro   sanitize audit_so...
2104
  	audit_socketcall(nargs[call] / sizeof(unsigned long), a);
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2105

89bddce58   Stephen Hemminger   [NET] socket: cod...
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
  	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
2123
2124
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
  		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:
  		err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
  		break;
  	case SYS_RECVMSG:
  		err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2171
2172
2173
2174
  	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
2175
2176
2177
  	case SYS_ACCEPT4:
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2178
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2179
2180
2181
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2182
2183
2184
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2185
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2186

55737fda0   Stephen Hemminger   [NET]: socket fam...
2187
2188
2189
2190
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2191
2192
   *	This function is called by a protocol handler that wants to
   *	advertise its address family, and have it linked into the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2193
2194
   *	socket interface. The value ops->family coresponds to the
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2195
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2196
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2197
2198
2199
2200
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2201
2202
2203
  		printk(KERN_CRIT "protocol %d >= NPROTO(%d)
  ", ops->family,
  		       NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2204
2205
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2206
2207
2208
2209
2210
  
  	spin_lock(&net_family_lock);
  	if (net_families[ops->family])
  		err = -EEXIST;
  	else {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2211
  		net_families[ops->family] = ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2212
2213
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2214
  	spin_unlock(&net_family_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2215
2216
  	printk(KERN_INFO "NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2217
2218
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2219
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2220

55737fda0   Stephen Hemminger   [NET]: socket fam...
2221
2222
2223
2224
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2225
2226
   *	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...
2227
2228
2229
2230
2231
2232
   *	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
2233
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2234
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2235
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2236
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2237

55737fda0   Stephen Hemminger   [NET]: socket fam...
2238
  	spin_lock(&net_family_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2239
  	net_families[family] = NULL;
55737fda0   Stephen Hemminger   [NET]: socket fam...
2240
2241
2242
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
89bddce58   Stephen Hemminger   [NET] socket: cod...
2243
2244
  	printk(KERN_INFO "NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2245
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2246
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2247

77d76ea31   Andi Kleen   [NET]: Small clea...
2248
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
  {
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2251
  	 *      Initialize sock SLAB cache.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
2253

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2254
  	sk_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2255
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2256
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2257
2258
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2259
2260
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2261
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2262
2263
2264
2265
2266
  	 */
  
  	init_inodecache();
  	register_filesystem(&sock_fs_type);
  	sock_mnt = kern_mount(&sock_fs_type);
77d76ea31   Andi Kleen   [NET]: Small clea...
2267
2268
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2269
2270
2271
2272
2273
  	 */
  
  #ifdef CONFIG_NETFILTER
  	netfilter_init();
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2274

c1f19b51d   Richard Cochran   net: support time...
2275
2276
2277
  #ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
  	skb_timestamping_init();
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2278
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2279
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2280
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2281
2282
2283
2284
2285
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
  	int cpu;
  	int counter = 0;
6f9120422   KAMEZAWA Hiroyuki   [PATCH] for_each_...
2286
  	for_each_possible_cpu(cpu)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2287
  	    counter += per_cpu(sockets_in_use, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2288
2289
2290
2291
2292
2293
2294
2295
  
  	/* 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...
2296
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2297

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2298
  #ifdef CONFIG_COMPAT
6b96018b2   Arnd Bergmann   compat: move sock...
2299
2300
  static int do_siocgstamp(struct net *net, struct socket *sock,
  			 unsigned int cmd, struct compat_timeval __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2301
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2302
2303
2304
2305
2306
  	mm_segment_t old_fs = get_fs();
  	struct timeval ktv;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2307
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
7a229387d   Arnd Bergmann   net: copy socket ...
2308
2309
2310
2311
2312
2313
2314
  	set_fs(old_fs);
  	if (!err) {
  		err = put_user(ktv.tv_sec, &up->tv_sec);
  		err |= __put_user(ktv.tv_usec, &up->tv_usec);
  	}
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2315
2316
  static int do_siocgstampns(struct net *net, struct socket *sock,
  			 unsigned int cmd, struct compat_timespec __user *up)
7a229387d   Arnd Bergmann   net: copy socket ...
2317
  {
7a229387d   Arnd Bergmann   net: copy socket ...
2318
2319
2320
2321
2322
  	mm_segment_t old_fs = get_fs();
  	struct timespec kts;
  	int err;
  
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2323
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
7a229387d   Arnd Bergmann   net: copy socket ...
2324
2325
2326
2327
2328
2329
2330
  	set_fs(old_fs);
  	if (!err) {
  		err = put_user(kts.tv_sec, &up->tv_sec);
  		err |= __put_user(kts.tv_nsec, &up->tv_nsec);
  	}
  	return err;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2331
  static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2332
2333
2334
2335
2336
  {
  	struct ifreq __user *uifr;
  	int err;
  
  	uifr = compat_alloc_user_space(sizeof(struct ifreq));
6b96018b2   Arnd Bergmann   compat: move sock...
2337
  	if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2338
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2339
  	err = dev_ioctl(net, SIOCGIFNAME, uifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2340
2341
  	if (err)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
2342
  	if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2343
2344
2345
2346
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2347
  static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2348
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2349
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2350
2351
  	struct ifconf ifc;
  	struct ifconf __user *uifc;
6b96018b2   Arnd Bergmann   compat: move sock...
2352
  	struct compat_ifreq __user *ifr32;
7a229387d   Arnd Bergmann   net: copy socket ...
2353
2354
2355
  	struct ifreq __user *ifr;
  	unsigned int i, j;
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2356
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2357
2358
2359
2360
2361
2362
2363
2364
  		return -EFAULT;
  
  	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...
2365
2366
  		size_t len = ((ifc32.ifc_len / sizeof(struct compat_ifreq)) + 1) *
  			sizeof(struct ifreq);
7a229387d   Arnd Bergmann   net: copy socket ...
2367
2368
2369
2370
  		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...
2371
  		for (i = 0; i < ifc32.ifc_len; i += sizeof(struct compat_ifreq)) {
6b96018b2   Arnd Bergmann   compat: move sock...
2372
  			if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2373
2374
2375
2376
2377
2378
2379
  				return -EFAULT;
  			ifr++;
  			ifr32++;
  		}
  	}
  	if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2380
  	err = dev_ioctl(net, SIOCGIFCONF, uifc);
7a229387d   Arnd Bergmann   net: copy socket ...
2381
2382
2383
2384
2385
2386
2387
2388
2389
  	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...
2390
2391
2392
  	     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 ...
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
  			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...
2403
  		i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
7a229387d   Arnd Bergmann   net: copy socket ...
2404
2405
2406
2407
  		ifc32.ifc_len = i;
  	} else {
  		ifc32.ifc_len = i;
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
2408
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2409
2410
2411
2412
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2413
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2414
2415
  {
  	struct ifreq __user *ifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2416
2417
2418
2419
  	u32 data;
  	void __user *datap;
  
  	ifr = compat_alloc_user_space(sizeof(*ifr));
7a229387d   Arnd Bergmann   net: copy socket ...
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
  
  	if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
  		return -EFAULT;
  
  	if (get_user(data, &ifr32->ifr_ifru.ifru_data))
  		return -EFAULT;
  
  	datap = compat_ptr(data);
  	if (put_user(datap, &ifr->ifr_ifru.ifru_data))
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2430
  	return dev_ioctl(net, SIOCETHTOOL, ifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2431
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2432
2433
2434
2435
2436
  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...
2437
  	uifr = compat_alloc_user_space(sizeof(*uifr));
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
  	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...
2451
2452
  static int bond_ioctl(struct net *net, unsigned int cmd,
  			 struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2453
2454
2455
  {
  	struct ifreq kifr;
  	struct ifreq __user *uifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
  	mm_segment_t old_fs;
  	int err;
  	u32 data;
  	void __user *datap;
  
  	switch (cmd) {
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
6b96018b2   Arnd Bergmann   compat: move sock...
2466
  		if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
7a229387d   Arnd Bergmann   net: copy socket ...
2467
2468
2469
  			return -EFAULT;
  
  		old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2470
  		set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2471
  		err = dev_ioctl(net, cmd, &kifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2472
  		set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
  
  		return err;
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
  		uifr = compat_alloc_user_space(sizeof(*uifr));
  		if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
  			return -EFAULT;
  
  		if (get_user(data, &ifr32->ifr_ifru.ifru_data))
  			return -EFAULT;
  
  		datap = compat_ptr(data);
  		if (put_user(datap, &uifr->ifr_ifru.ifru_data))
  			return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2487
  		return dev_ioctl(net, cmd, uifr);
7a229387d   Arnd Bergmann   net: copy socket ...
2488
2489
  	default:
  		return -EINVAL;
ccbd6a5a4   Joe Perches   net: Remove unnec...
2490
  	}
7a229387d   Arnd Bergmann   net: copy socket ...
2491
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2492
2493
  static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
2494
2495
  {
  	struct ifreq __user *u_ifreq64;
7a229387d   Arnd Bergmann   net: copy socket ...
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
  	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;
  	if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
  		return -EFAULT;
  	data64 = compat_ptr(data32);
  
  	u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
  
  	/* Don't check these user accesses, just let that get trapped
  	 * in the ioctl handler instead.
  	 */
  	if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
  			 IFNAMSIZ))
  		return -EFAULT;
  	if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
  		return -EFAULT;
6b96018b2   Arnd Bergmann   compat: move sock...
2517
  	return dev_ioctl(net, cmd, u_ifreq64);
7a229387d   Arnd Bergmann   net: copy socket ...
2518
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2519
2520
  static int dev_ifsioc(struct net *net, struct socket *sock,
  			 unsigned int cmd, struct compat_ifreq __user *uifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2521
  {
a2116ed22   Arnd Bergmann   net/compat: fix d...
2522
  	struct ifreq __user *uifr;
7a229387d   Arnd Bergmann   net: copy socket ...
2523
  	int err;
a2116ed22   Arnd Bergmann   net/compat: fix d...
2524
2525
2526
2527
2528
  	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 ...
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
  	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...
2541
  		case SIOCGIFPFLAGS:
7a229387d   Arnd Bergmann   net: copy socket ...
2542
  		case SIOCGIFTXQLEN:
fab2532ba   Arnd Bergmann   net, compat_ioctl...
2543
2544
  		case SIOCGMIIPHY:
  		case SIOCGMIIREG:
a2116ed22   Arnd Bergmann   net/compat: fix d...
2545
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
7a229387d   Arnd Bergmann   net: copy socket ...
2546
2547
2548
2549
2550
2551
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
  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));
  	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);
  	if (err)
  		return -EFAULT;
  
  	old_fs = get_fs();
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2572
  	set_fs(KERNEL_DS);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2573
  	err = dev_ioctl(net, cmd, (void __user *)&ifr);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2574
  	set_fs(old_fs);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
  		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);
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
  
  static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
  {
  	void __user *uptr;
  	compat_uptr_t uptr32;
  	struct ifreq __user *uifr;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2595
  	uifr = compat_alloc_user_space(sizeof(*uifr));
a2116ed22   Arnd Bergmann   net/compat: fix d...
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
  	if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_data))
  		return -EFAULT;
  
  	uptr = compat_ptr(uptr32);
  
  	if (put_user(uptr, &uifr->ifr_data))
  		return -EFAULT;
  
  	return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2609
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2610
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
2611
2612
2613
  	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...
2614
2615
2616
2617
2618
2619
2620
  	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 ...
2621
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2622
2623
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
  	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...
2639
2640
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2641
2642
2643
2644
2645
2646
2647
2648
  {
  	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...
2649
2650
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2651
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2652
  			3 * sizeof(struct in6_addr));
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2653
2654
2655
2656
2657
2658
2659
  		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 ...
2660
2661
2662
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
2663
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2664
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
2665
  					3 * sizeof(struct sockaddr));
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2666
2667
2668
2669
2670
2671
  		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 ...
2672
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2673
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
7a229387d   Arnd Bergmann   net: copy socket ...
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
  			r4.rt_dev = devname; devname[15] = 0;
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2685
  	set_fs(KERNEL_DS);
6b96018b2   Arnd Bergmann   compat: move sock...
2686
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2687
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
2688
2689
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
2690
2691
2692
2693
2694
2695
2696
  	return ret;
  }
  
  /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
   * for some operations; this forces use of the newer bridge-utils that
   * use compatiable ioctls
   */
6b96018b2   Arnd Bergmann   compat: move sock...
2697
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
2698
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2699
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
2700

6b96018b2   Arnd Bergmann   compat: move sock...
2701
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
2702
2703
2704
2705
2706
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2707
2708
2709
2710
2711
2712
  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 ...
2713

6b96018b2   Arnd Bergmann   compat: move sock...
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
  		return siocdevprivate_ioctl(net, cmd, argp);
  
  	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:...
2727
2728
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2729
2730
2731
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
  	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);
a2116ed22   Arnd Bergmann   net/compat: fix d...
2746
2747
  	case SIOCSHWTSTAMP:
  		return compat_siocshwtstamp(net, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
  
  	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...
2774
2775
2776
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
2777
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
  	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...
2790
2791
2792
2793
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
6b96018b2   Arnd Bergmann   compat: move sock...
2794
  		return dev_ifsioc(net, sock, cmd, argp);
9177efd39   Arnd Bergmann   net, compat_ioctl...
2795

6b96018b2   Arnd Bergmann   compat: move sock...
2796
2797
2798
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
6b96018b2   Arnd Bergmann   compat: move sock...
2799
  	case SIOCATMARK:
9177efd39   Arnd Bergmann   net, compat_ioctl...
2800
2801
2802
2803
2804
2805
2806
2807
  		return sock_do_ioctl(net, sock, cmd, arg);
  	}
  
  	/* Prevent warning from compat_sys_ioctl, these always
  	 * result in -EINVAL in the native case anyway. */
  	switch (cmd) {
  	case SIOCRTMSG:
  	case SIOCGIFCOUNT:
6b96018b2   Arnd Bergmann   compat: move sock...
2808
2809
2810
  	case SIOCSRARP:
  	case SIOCGRARP:
  	case SIOCDRARP:
9177efd39   Arnd Bergmann   net, compat_ioctl...
2811
2812
2813
2814
  	case SIOCSIFLINK:
  	case SIOCGIFSLAVE:
  	case SIOCSIFSLAVE:
  		return -EINVAL;
6b96018b2   Arnd Bergmann   compat: move sock...
2815
2816
2817
2818
  	}
  
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
2819

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2820
  static long compat_sock_ioctl(struct file *file, unsigned cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2821
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2822
2823
2824
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
2825
2826
2827
2828
2829
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2830
2831
2832
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
2833
2834
2835
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
2836
2837
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2838
2839
2840
  	return ret;
  }
  #endif
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2841
2842
2843
2844
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2845
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2846
2847
2848
2849
2850
  
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2851
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
  
  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...
2866
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2867
2868
2869
2870
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
2871
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2872
2873
2874
2875
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2876
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2877
2878
  
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
2879
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2880
2881
2882
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2883
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2884
2885
2886
2887
2888
2889
  
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 0);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2890
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2891
2892
2893
2894
2895
2896
  
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 1);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2897
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2898
2899
2900
2901
2902
  
  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...
2903
2904
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2905
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
2906
2907
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2908
2909
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
2910
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2911
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
2912
2913
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2914
2915
2916
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2917
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2918
2919
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
2920
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2921
2922
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
2923
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2924
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
2925
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2926
2927
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
2928
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2929
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
2930
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2931
2932
2933
2934
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2935
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2936
2937
2938
2939
  
  int kernel_sendpage(struct socket *sock, struct page *page, int offset,
  		    size_t size, int flags)
  {
f84517253   Herbert Xu   cls_cgroup: Store...
2940
  	sock_update_classid(sock->sk);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2941
2942
2943
2944
2945
  	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...
2946
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
  
  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...
2959
  EXPORT_SYMBOL(kernel_sock_ioctl);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2960

91cf45f02   Trond Myklebust   [NET]: Add the he...
2961
2962
2963
2964
  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...
2965
  EXPORT_SYMBOL(kernel_sock_shutdown);