Blame view

net/socket.c 57.9 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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
  
  #include <net/compat.h>
87de87d5e   David S. Miller   wext: Dispatch an...
93
  #include <net/wext.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
  
  #include <net/sock.h>
  #include <linux/netfilter.h>
  
  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
027445c37   Badari Pulavarty   [PATCH] Vectorize...
99
100
101
102
  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...
103
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
  
  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...
108
  static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
109
110
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file,
89bddce58   Stephen Hemminger   [NET] socket: cod...
111
  			      unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
112
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  static int sock_fasync(int fd, struct file *filp, int on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
  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...
116
117
118
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
  			        struct pipe_inode_info *pipe, size_t len,
  				unsigned int flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
  /*
   *	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...
124
  static const struct file_operations socket_file_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
130
  	.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...
131
132
133
  #ifdef CONFIG_COMPAT
  	.compat_ioctl = compat_sock_ioctl,
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  	.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...
138
139
  	.sendpage =	sock_sendpage,
  	.splice_write = generic_splice_sendpage,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
140
  	.splice_read =	sock_splice_read,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
145
  };
  
  /*
   *	The protocol list. Each protocol is registered in here.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  static DEFINE_SPINLOCK(net_family_lock);
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
147
  static const struct net_proto_family *net_families[NPROTO] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
153
154
155
  /*
   *	Statistics counters of the socket lists
   */
  
  static DEFINE_PER_CPU(int, sockets_in_use) = 0;
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
156
157
158
   * 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
159
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
160
  #define MAX_SOCK_ADDR	128		/* 108 for Unix domain -
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
  					   16 for IP, 16 for IPX,
  					   24 for IPv6,
89bddce58   Stephen Hemminger   [NET] socket: cod...
163
  					   about 80 for AX.25
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
  					   must be at least one bigger than
  					   the AF_UNIX size (see net/unix/af_unix.c
89bddce58   Stephen Hemminger   [NET] socket: cod...
166
  					   :unix_mkname()).
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
  					 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
168

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

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

e94b17660   Christoph Lameter   [PATCH] slab: rem...
239
  	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
242
  	if (!ei)
  		return NULL;
  	init_waitqueue_head(&ei->socket.wait);
89bddce58   Stephen Hemminger   [NET] socket: cod...
243

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
246
247
248
249
  	ei->socket.fasync_list = NULL;
  	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
253
254
255
256
257
258
  
  	return &ei->vfs_inode;
  }
  
  static void sock_destroy_inode(struct inode *inode)
  {
  	kmem_cache_free(sock_inode_cachep,
  			container_of(inode, struct socket_alloc, vfs_inode));
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
259
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
261
  	struct socket_alloc *ei = (struct socket_alloc *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
  static int init_inodecache(void)
  {
  	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
89bddce58   Stephen Hemminger   [NET] socket: cod...
269
270
271
272
273
  					      sizeof(struct socket_alloc),
  					      0,
  					      (SLAB_HWCACHE_ALIGN |
  					       SLAB_RECLAIM_ACCOUNT |
  					       SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
274
  					      init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
280
281
282
283
284
  	if (sock_inode_cachep == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  static struct super_operations sockfs_ops = {
  	.alloc_inode =	sock_alloc_inode,
  	.destroy_inode =sock_destroy_inode,
  	.statfs =	simple_statfs,
  };
454e2398b   David Howells   [PATCH] VFS: Perm...
285
  static int sockfs_get_sb(struct file_system_type *fs_type,
89bddce58   Stephen Hemminger   [NET] socket: cod...
286
287
  			 int flags, const char *dev_name, void *data,
  			 struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  {
454e2398b   David Howells   [PATCH] VFS: Perm...
289
290
  	return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC,
  			     mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  }
ba89966c1   Eric Dumazet   [NET]: use __read...
292
  static struct vfsmount *sock_mnt __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
297
298
  
  static struct file_system_type sock_fs_type = {
  	.name =		"sockfs",
  	.get_sb =	sockfs_get_sb,
  	.kill_sb =	kill_anon_super,
  };
89bddce58   Stephen Hemminger   [NET] socket: cod...
299

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
301
  static int sockfs_delete_dentry(struct dentry *dentry)
  {
304e61e6f   Eric Dumazet   [PATCH] net: don'...
302
303
304
305
306
307
308
309
  	/*
  	 * At creation time, we pretended this dentry was hashed
  	 * (by clearing DCACHE_UNHASHED bit in d_flags)
  	 * At delete time, we restore the truth : not hashed.
  	 * (so that dput() can proceed correctly)
  	 */
  	dentry->d_flags |= DCACHE_UNHASHED;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  }
c23fbb6bc   Eric Dumazet   VFS: delay the de...
311
312
313
314
315
316
317
318
319
  
  /*
   * 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...
320
  static const struct dentry_operations sockfs_dentry_operations = {
89bddce58   Stephen Hemminger   [NET] socket: cod...
321
  	.d_delete = sockfs_delete_dentry,
c23fbb6bc   Eric Dumazet   VFS: delay the de...
322
  	.d_dname  = sockfs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
325
326
327
  };
  
  /*
   *	Obtains the first available file descriptor and sets it up for use.
   *
39d8c1b6f   David S. Miller   [NET]: Do not los...
328
329
   *	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
330
331
332
333
334
335
336
337
338
339
340
   *	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.
   */
a677a039b   Ulrich Drepper   flag parameters: ...
341
  static int sock_alloc_fd(struct file **filep, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
  {
  	int fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344

a677a039b   Ulrich Drepper   flag parameters: ...
345
  	fd = get_unused_fd_flags(flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
346
  	if (likely(fd >= 0)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  		struct file *file = get_empty_filp();
39d8c1b6f   David S. Miller   [NET]: Do not los...
348
349
  		*filep = file;
  		if (unlikely(!file)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  			put_unused_fd(fd);
39d8c1b6f   David S. Miller   [NET]: Do not los...
351
  			return -ENFILE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
  		}
39d8c1b6f   David S. Miller   [NET]: Do not los...
353
354
355
356
  	} else
  		*filep = NULL;
  	return fd;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357

77d272005   Ulrich Drepper   flag parameters: ...
358
  static int sock_attach_fd(struct socket *sock, struct file *file, int flags)
39d8c1b6f   David S. Miller   [NET]: Do not los...
359
  {
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
360
  	struct dentry *dentry;
c23fbb6bc   Eric Dumazet   VFS: delay the de...
361
  	struct qstr name = { .name = "" };
39d8c1b6f   David S. Miller   [NET]: Do not los...
362

ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
363
364
  	dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
  	if (unlikely(!dentry))
39d8c1b6f   David S. Miller   [NET]: Do not los...
365
  		return -ENOMEM;
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
366
  	dentry->d_op = &sockfs_dentry_operations;
304e61e6f   Eric Dumazet   [PATCH] net: don'...
367
368
369
370
371
  	/*
  	 * We dont want to push this dentry into global dentry hash table.
  	 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
  	 * This permits a working /proc/$pid/fd/XXX on sockets
  	 */
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
372
373
  	dentry->d_flags &= ~DCACHE_UNHASHED;
  	d_instantiate(dentry, SOCK_INODE(sock));
39d8c1b6f   David S. Miller   [NET]: Do not los...
374
375
  
  	sock->file = file;
ce8d2cdf3   Dave Hansen   r/o bind mounts: ...
376
377
378
  	init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
  		  &socket_file_ops);
  	SOCK_INODE(sock)->i_fop = &socket_file_ops;
77d272005   Ulrich Drepper   flag parameters: ...
379
  	file->f_flags = O_RDWR | (flags & O_NONBLOCK);
39d8c1b6f   David S. Miller   [NET]: Do not los...
380
381
  	file->f_pos = 0;
  	file->private_data = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382

39d8c1b6f   David S. Miller   [NET]: Do not los...
383
384
  	return 0;
  }
a677a039b   Ulrich Drepper   flag parameters: ...
385
  int sock_map_fd(struct socket *sock, int flags)
39d8c1b6f   David S. Miller   [NET]: Do not los...
386
387
  {
  	struct file *newfile;
a677a039b   Ulrich Drepper   flag parameters: ...
388
  	int fd = sock_alloc_fd(&newfile, flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
389
390
  
  	if (likely(fd >= 0)) {
77d272005   Ulrich Drepper   flag parameters: ...
391
  		int err = sock_attach_fd(sock, newfile, flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
392
393
394
  
  		if (unlikely(err < 0)) {
  			put_filp(newfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  			put_unused_fd(fd);
39d8c1b6f   David S. Miller   [NET]: Do not los...
396
  			return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  		}
39d8c1b6f   David S. Miller   [NET]: Do not los...
398
  		fd_install(fd, newfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
401
  	return fd;
  }
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
402
403
  static struct socket *sock_from_file(struct file *file, int *err)
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
404
405
  	if (file->f_op == &socket_file_ops)
  		return file->private_data;	/* set in sock_map_fd */
23bb80d21   Eric Dumazet   [NET]: cleanup so...
406
407
  	*err = -ENOTSOCK;
  	return NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
408
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  /**
   *	sockfd_lookup	- 	Go from a file number to its socket slot
   *	@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
425
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
426
427
  	file = fget(fd);
  	if (!file) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
430
  		*err = -EBADF;
  		return NULL;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
431

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
432
433
  	sock = sock_from_file(file, err);
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  		fput(file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
435
436
  	return sock;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
438
439
440
441
  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...
442
  	*err = -EBADF;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
443
444
445
446
447
448
  	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
449
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
450
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
454
  }
  
  /**
   *	sock_alloc	-	allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
455
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
459
460
461
462
   *	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...
463
464
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
469
470
  
  	inode = new_inode(sock_mnt->mnt_sb);
  	if (!inode)
  		return NULL;
  
  	sock = SOCKET_I(inode);
89bddce58   Stephen Hemminger   [NET] socket: cod...
471
  	inode->i_mode = S_IFSOCK | S_IRWXUGO;
8192b0c48   David Howells   CRED: Wrap task c...
472
473
  	inode->i_uid = current_fsuid();
  	inode->i_gid = current_fsgid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474

4e69489a0   Eric Dumazet   socket: use percp...
475
  	percpu_add(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476
477
478
479
480
481
482
483
  	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...
484

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
488
  static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
  {
  	return -ENXIO;
  }
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
489
  const struct file_operations bad_sock_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
492
493
494
495
496
497
498
499
  	.owner = THIS_MODULE,
  	.open = sock_no_open,
  };
  
  /**
   *	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...
500
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
502

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
505
506
507
508
509
510
511
512
513
514
515
  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);
  	}
  
  	if (sock->fasync_list)
  		printk(KERN_ERR "sock_release: fasync list not empty!
  ");
4e69489a0   Eric Dumazet   socket: use percp...
516
  	percpu_sub(sockets_in_use, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
519
520
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
521
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
  }
20d494735   Patrick Ohly   net: socket infra...
523
524
525
526
527
528
529
530
531
532
533
  int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,
  		      union skb_shared_tx *shtx)
  {
  	shtx->flags = 0;
  	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
  		shtx->hardware = 1;
  	if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
  		shtx->software = 1;
  	return 0;
  }
  EXPORT_SYMBOL(sock_tx_timestamp);
89bddce58   Stephen Hemminger   [NET] socket: cod...
534
  static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  				 struct msghdr *msg, size_t size)
  {
  	struct sock_iocb *si = kiocb_to_siocb(iocb);
  	int err;
  
  	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;
  }
  
  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...
577
  	msg->msg_iov = (struct iovec *)vec;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
580
581
582
  	msg->msg_iovlen = num;
  	result = sock_sendmsg(sock, msg, size);
  	set_fs(oldfs);
  	return result;
  }
20d494735   Patrick Ohly   net: socket infra...
583
584
585
586
587
588
589
590
591
  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_...
592
593
594
595
596
597
  /*
   * 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...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
  	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 {
  			struct timespec ts;
  			skb_get_timestampns(skb, &ts);
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
  				 sizeof(ts), &ts);
  		}
  	}
  
  
  	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_...
637
  	}
20d494735   Patrick Ohly   net: socket infra...
638
639
640
  	if (!empty)
  		put_cmsg(msg, SOL_SOCKET,
  			 SCM_TIMESTAMPING, sizeof(ts), &ts);
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
641
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
642
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
89bddce58   Stephen Hemminger   [NET] socket: cod...
643
  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
  				 struct msghdr *msg, size_t size, int flags)
  {
  	int err;
  	struct sock_iocb *si = kiocb_to_siocb(iocb);
  
  	si->sock = sock;
  	si->scm = NULL;
  	si->msg = msg;
  	si->size = size;
  	si->flags = flags;
  
  	err = security_socket_recvmsg(sock, msg, size, flags);
  	if (err)
  		return err;
  
  	return sock->ops->recvmsg(iocb, sock, msg, size, flags);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
661
  int sock_recvmsg(struct socket *sock, struct msghdr *msg,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
  		 size_t size, int flags)
  {
  	struct kiocb iocb;
  	struct sock_iocb siocb;
  	int ret;
89bddce58   Stephen Hemminger   [NET] socket: cod...
667
  	init_sync_kiocb(&iocb, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
670
671
672
673
  	iocb.private = &siocb;
  	ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
  	if (-EIOCBQUEUED == ret)
  		ret = wait_on_sync_kiocb(&iocb);
  	return ret;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
674
675
  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
676
677
678
679
680
681
682
683
684
  {
  	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...
685
  	msg->msg_iov = (struct iovec *)vec, msg->msg_iovlen = num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
688
689
690
691
692
693
694
  	result = sock_recvmsg(sock, msg, size, flags);
  	set_fs(oldfs);
  	return result;
  }
  
  static void sock_aio_dtor(struct kiocb *iocb)
  {
  	kfree(iocb->private);
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
695
696
  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
697
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
699
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
700
701
702
703
704
705
706
707
  	sock = file->private_data;
  
  	flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
  	if (more)
  		flags |= MSG_MORE;
  
  	return sock->ops->sendpage(sock, page, offset, size, flags);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
709
710
711
712
713
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
  			        struct pipe_inode_info *pipe, size_t len,
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
714
715
  	if (unlikely(!sock->ops->splice_read))
  		return -EINVAL;
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
716
717
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
718
  static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
89bddce58   Stephen Hemminger   [NET] socket: cod...
719
  					 struct sock_iocb *siocb)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
720
721
722
723
724
  {
  	if (!is_sync_kiocb(iocb)) {
  		siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
  		if (!siocb)
  			return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
725
726
  		iocb->ki_dtor = sock_aio_dtor;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
728
  	siocb->kiocb = iocb;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
729
730
  	iocb->private = siocb;
  	return siocb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
732
  static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
027445c37   Badari Pulavarty   [PATCH] Vectorize...
733
734
  		struct file *file, const struct iovec *iov,
  		unsigned long nr_segs)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
735
736
737
738
  {
  	struct socket *sock = file->private_data;
  	size_t size = 0;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739

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

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
743
744
745
746
  	msg->msg_name = NULL;
  	msg->msg_namelen = 0;
  	msg->msg_control = NULL;
  	msg->msg_controllen = 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
747
  	msg->msg_iov = (struct iovec *)iov;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
748
749
750
751
752
  	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...
753
754
  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...
755
756
  {
  	struct sock_iocb siocb, *x;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
  	if (pos != 0)
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
759
760
  
  	if (iocb->ki_left == 0)	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
  		return 0;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
762
763
  
  	x = alloc_sock_iocb(iocb, &siocb);
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
764
765
  	if (!x)
  		return -ENOMEM;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
766
  	return do_sock_read(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
  }
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
768
  static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
027445c37   Badari Pulavarty   [PATCH] Vectorize...
769
770
  			struct file *file, const struct iovec *iov,
  			unsigned long nr_segs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
  {
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
772
773
774
  	struct socket *sock = file->private_data;
  	size_t size = 0;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775

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

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
779
780
781
782
  	msg->msg_name = NULL;
  	msg->msg_namelen = 0;
  	msg->msg_control = NULL;
  	msg->msg_controllen = 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
783
  	msg->msg_iov = (struct iovec *)iov;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
784
785
786
787
  	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
788

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
789
  	return __sock_sendmsg(iocb, sock, msg, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
  }
027445c37   Badari Pulavarty   [PATCH] Vectorize...
791
792
  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...
793
794
  {
  	struct sock_iocb siocb, *x;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
795

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

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

027445c37   Badari Pulavarty   [PATCH] Vectorize...
803
  	return do_sock_write(&x->async_msg, iocb, iocb->ki_filp, iov, nr_segs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
808
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
809
  static DEFINE_MUTEX(br_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
810
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg) = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811

881d966b4   Eric W. Biederman   [NET]: Make the d...
812
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
814
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
816
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
818

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
820
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
821
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822

881d966b4   Eric W. Biederman   [NET]: Make the d...
823
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
825
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
827
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
829

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
831
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
832
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833

89bddce58   Stephen Hemminger   [NET] socket: cod...
834
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
836
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
838
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
840

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
844
845
846
847
848
849
850
  EXPORT_SYMBOL(dlci_ioctl_set);
  
  /*
   *	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...
851
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
854
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855

b69aee04f   Eric Dumazet   [NET]: Use file->...
856
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
857
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
858
  	net = sock_net(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
860
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
  	} else
d86b5e0e6   Adrian Bunk   [PATCH] net/: fix...
862
  #ifdef CONFIG_WIRELESS_EXT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
881d966b4   Eric W. Biederman   [NET]: Make the d...
864
  		err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
  	} else
89bddce58   Stephen Hemminger   [NET] socket: cod...
866
867
  #endif				/* CONFIG_WIRELESS_EXT */
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
869
870
871
872
873
874
875
876
  		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...
877
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
878
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
881
882
883
884
885
886
  			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: ...
887
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
888
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
889
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
890
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
892
893
894
895
896
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
897
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
898
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
899
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
900
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
904
905
906
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
907
908
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
910
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
911
912
913
  			break;
  		default:
  			err = sock->ops->ioctl(sock, cmd, arg);
b5e5fa5e0   Christoph Hellwig   [NET]: Add a dev_...
914
915
916
917
918
919
  
  			/*
  			 * If this ioctl is unknown try to hand it down
  			 * to the NIC driver.
  			 */
  			if (err == -ENOIOCTLCMD)
881d966b4   Eric W. Biederman   [NET]: Make the d...
920
  				err = dev_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
922
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923
924
925
926
927
928
929
  	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...
930

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
932
933
934
935
936
937
938
939
  	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
940
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
941
942
943
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
944
945
946
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
947
948
949
950
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
952
953
  }
  
  /* No kernel lock held - perfect */
89bddce58   Stephen Hemminger   [NET] socket: cod...
954
  static unsigned int sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
958
  {
  	struct socket *sock;
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
959
  	 *      We can't return errors to poll, so it's either yes or no.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
  	 */
b69aee04f   Eric Dumazet   [NET]: Use file->...
961
  	sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
  	return sock->ops->poll(file, sock, wait);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
964
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
966
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
968
969
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
970
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
972
  {
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
973
974
  	 *      It was possible the inode is NULL we were
  	 *      closing an unfinished socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
976
  	if (!inode) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
978
979
980
  		printk(KERN_DEBUG "sock_close: NULL inode
  ");
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  	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)
   *	   or under socket lock.
   *	3. fasync_list can be used from softirq context, so that
   *	   modification under socket lock have to be enhanced with
   *	   write_lock_bh(&sk->sk_callback_lock).
   *							--ANK (990710)
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1002
  	struct fasync_struct *fa, *fna = NULL, **prev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
  	struct socket *sock;
  	struct sock *sk;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1005
  	if (on) {
8b3a70058   Kris Katterjohn   [NET]: Remove mor...
1006
  		fna = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1007
  		if (fna == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1008
1009
  			return -ENOMEM;
  	}
b69aee04f   Eric Dumazet   [NET]: Use file->...
1010
  	sock = filp->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1011

89bddce58   Stephen Hemminger   [NET] socket: cod...
1012
1013
  	sk = sock->sk;
  	if (sk == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
1015
1016
1017
1018
  		kfree(fna);
  		return -EINVAL;
  	}
  
  	lock_sock(sk);
76398425b   Jonathan Corbet   Move FASYNC bit h...
1019
1020
1021
1022
1023
1024
  	spin_lock(&filp->f_lock);
  	if (on)
  		filp->f_flags |= FASYNC;
  	else
  		filp->f_flags &= ~FASYNC;
  	spin_unlock(&filp->f_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1025
  	prev = &(sock->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026

89bddce58   Stephen Hemminger   [NET] socket: cod...
1027
1028
  	for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
  		if (fa->fa_file == filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1029
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1030
1031
  	if (on) {
  		if (fa != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1032
  			write_lock_bh(&sk->sk_callback_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1033
  			fa->fa_fd = fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1034
1035
1036
1037
1038
  			write_unlock_bh(&sk->sk_callback_lock);
  
  			kfree(fna);
  			goto out;
  		}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1039
1040
1041
1042
  		fna->fa_file = filp;
  		fna->fa_fd = fd;
  		fna->magic = FASYNC_MAGIC;
  		fna->fa_next = sock->fasync_list;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
  		write_lock_bh(&sk->sk_callback_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1044
  		sock->fasync_list = fna;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  		write_unlock_bh(&sk->sk_callback_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1046
1047
  	} else {
  		if (fa != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1048
  			write_lock_bh(&sk->sk_callback_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1049
  			*prev = fa->fa_next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
  			write_unlock_bh(&sk->sk_callback_lock);
  			kfree(fa);
  		}
  	}
  
  out:
  	release_sock(sock->sk);
  	return 0;
  }
  
  /* This function may be called only under socket lock or callback_lock */
  
  int sock_wake_async(struct socket *sock, int how, int band)
  {
  	if (!sock || !sock->fasync_list)
  		return -1;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1066
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1067
  	case SOCK_WAKE_WAITD:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
1069
1070
  		if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1071
  	case SOCK_WAKE_SPACE:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072
1073
1074
  		if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags))
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1075
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1076
  call_kill:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1077
1078
  		__kill_fasync(sock->fasync_list, SIGIO, band);
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1079
  	case SOCK_WAKE_URG:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1080
1081
1082
1083
  		__kill_fasync(sock->fasync_list, SIGURG, band);
  	}
  	return 0;
  }
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1084
  static int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1085
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1086
1087
1088
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1089
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
1091
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1092
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
  	 */
  	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...
1105
  		static int warned;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
1107
  		if (!warned) {
  			warned = 1;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1108
1109
1110
  			printk(KERN_INFO "%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			       current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1111
1112
1113
1114
1115
1116
1117
  		}
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1118

55737fda0   Stephen Hemminger   [NET]: socket fam...
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
  	/*
  	 *	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...
1134
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1135
1136
1137
  	/* 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
1138
1139
1140
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1141
  	if (net_families[family] == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1142
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1143
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1144
1145
1146
1147
1148
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
1150
1151
1152
1153
  
  	/*
  	 * 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...
1154
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1156
1157
  	/* Now protected by module ref count */
  	rcu_read_unlock();
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1158
  	err = pf->create(net, sock, protocol);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1159
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1160
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1161

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

55737fda0   Stephen Hemminger   [NET]: socket fam...
1178
1179
1180
1181
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1182
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1183
1184
1185
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1187
1188
1189
1190
1191
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192
1193
1194
1195
  }
  
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1196
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
1198
1199
1200
  }
  
  int sock_create_kern(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1201
  	return __sock_create(&init_net, family, type, protocol, res, 1);
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;
a677a039b   Ulrich Drepper   flag parameters: ...
1270
  	fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC);
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

a677a039b   Ulrich Drepper   flag parameters: ...
1276
  	fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1277
  	if (unlikely(fd2 < 0)) {
bf3c23d17   David S. Miller   [NET]: Fix error ...
1278
  		err = fd2;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1279
1280
  		put_filp(newfile1);
  		put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1281
  		goto out_release_both;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1282
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283

77d272005   Ulrich Drepper   flag parameters: ...
1284
  	err = sock_attach_fd(sock1, newfile1, flags & O_NONBLOCK);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1285
1286
1287
  	if (unlikely(err < 0)) {
  		goto out_fd2;
  	}
77d272005   Ulrich Drepper   flag parameters: ...
1288
  	err = sock_attach_fd(sock2, newfile2, flags & O_NONBLOCK);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1289
1290
1291
1292
  	if (unlikely(err < 0)) {
  		fput(newfile1);
  		goto out_fd1;
  	}
157cf649a   Al Viro   sanitize audit_fd...
1293
  	audit_fd_pair(fd1, fd2);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1294
1295
  	fd_install(fd1, newfile1);
  	fd_install(fd2, newfile2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
1297
1298
  	/* fd1 and fd2 may be already another descriptors.
  	 * Not kernel problem.
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1299
  	err = put_user(fd1, &usockvec[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
1301
1302
1303
1304
1305
1306
1307
  	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
1308
  out_release_both:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1309
  	sock_release(sock2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310
  out_release_1:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1311
  	sock_release(sock1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
1313
  out:
  	return err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1314
1315
1316
1317
1318
1319
1320
  
  out_fd2:
  	put_filp(newfile1);
  	sock_release(sock1);
  out_fd1:
  	put_filp(newfile2);
  	sock_release(sock2);
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1321
1322
1323
  	put_unused_fd(fd1);
  	put_unused_fd(fd2);
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1324
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1325
1326
1327
1328
1329
1330
1331
  /*
   *	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...
1332
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1333
1334
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1335
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1336
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1337

89bddce58   Stephen Hemminger   [NET] socket: cod...
1338
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1339
  	if (sock) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1340
  		err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1341
1342
  		if (err >= 0) {
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1343
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1344
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1345
1346
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1347
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1348
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1349
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1350
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1351
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1352
1353
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
1355
1356
1357
1358
  /*
   *	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...
1359
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
1361
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1362
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1363
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1364
1365
1366
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1367
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1368
1369
  		if ((unsigned)backlog > somaxconn)
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370
1371
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1372
1373
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1375
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1376
1377
1378
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
  /*
   *	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...
1390
1391
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
1393
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1394
  	struct file *newfile;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1395
  	int err, len, newfd, fput_needed;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1396
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397

77d272005   Ulrich Drepper   flag parameters: ...
1398
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1399
1400
1401
1402
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1403
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1404
1405
1406
1407
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1408
  	if (!(newsock = sock_alloc()))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409
1410
1411
1412
  		goto out_put;
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
1414
1415
1416
1417
  	/*
  	 * 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);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1418
  	newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1419
1420
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1421
1422
  		sock_release(newsock);
  		goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1423
  	}
77d272005   Ulrich Drepper   flag parameters: ...
1424
  	err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1425
  	if (err < 0)
79f4f6428   Alexey Dobriyan   [NET]: Correct ac...
1426
  		goto out_fd_simple;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1427

a79af59ef   Frank Filz   [NET]: Fix module...
1428
1429
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1430
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1431

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1434
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
  
  	if (upeer_sockaddr) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1437
  		if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1438
  					  &len, 2) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1440
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
  		}
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1442
1443
  		err = move_addr_to_user((struct sockaddr *)&address,
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1445
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1446
1447
1448
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1449
1450
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1451

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1453
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1454
1455
  out:
  	return err;
79f4f6428   Alexey Dobriyan   [NET]: Correct ac...
1456
1457
1458
1459
1460
  out_fd_simple:
  	sock_release(newsock);
  	put_filp(newfile);
  	put_unused_fd(newfd);
  	goto out_put;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1461
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1462
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1463
  	put_unused_fd(newfd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
  	goto out_put;
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1466
1467
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1468
  {
de11defeb   Ulrich Drepper   reintroduce accept4
1469
  	return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1470
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
  /*
   *	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...
1482
1483
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
1485
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1486
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1487
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488

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

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1518
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1519
1520
1521
1522
1523
1524
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1525
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1526
1527
  	if (err)
  		goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1528
  	err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1529
1530
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1531
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
1533
1534
1535
1536
1537
1538
1539
  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...
1540
1541
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1542
1543
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1544
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1545
  	int len, err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546

89bddce58   Stephen Hemminger   [NET] socket: cod...
1547
1548
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
1550
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1551
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1552
1553
  			return err;
  		}
89bddce58   Stephen Hemminger   [NET] socket: cod...
1554
  		err =
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1555
  		    sock->ops->getname(sock, (struct sockaddr *)&address, &len,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1556
  				       1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1557
  		if (!err)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1558
  			err = move_addr_to_user((struct sockaddr *)&address, len, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1559
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1560
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
1562
1563
1564
1565
1566
1567
1568
1569
  	}
  	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...
1570
1571
1572
  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
1573
1574
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1575
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
1578
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1579
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1580

de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1581
1582
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1583
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1584

89bddce58   Stephen Hemminger   [NET] socket: cod...
1585
1586
1587
1588
1589
1590
1591
1592
  	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...
1593
  	if (addr) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1594
  		err = move_addr_to_kernel(addr, addr_len, (struct sockaddr *)&address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595
1596
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1597
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1598
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1599
1600
1601
1602
1603
  	}
  	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...
1604
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1605
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1606
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
1609
1610
  	return err;
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1611
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1613
1614
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
  		unsigned, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615
1616
1617
1618
1619
  {
  	return sys_sendto(fd, buff, len, flags, NULL, 0);
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1620
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621
1622
1623
   *	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...
1624
1625
1626
  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
1627
1628
1629
1630
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1631
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1632
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1633
  	int fput_needed;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1634
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1635
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1636
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637

89bddce58   Stephen Hemminger   [NET] socket: cod...
1638
1639
1640
1641
1642
1643
  	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...
1644
1645
  	msg.msg_name = (struct sockaddr *)&address;
  	msg.msg_namelen = sizeof(address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1646
1647
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1648
  	err = sock_recvmsg(sock, &msg, size, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1649

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1772
1773
1774
1775
  	err = -EFAULT;
  	if (MSG_CMSG_COMPAT & flags) {
  		if (get_compat_msghdr(&msg_sys, msg_compat))
  			return -EFAULT;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1776
1777
  	}
  	else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1778
  		return -EFAULT;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1779
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1780
  	if (!sock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781
1782
1783
1784
1785
1786
  		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...
1787
  	/* Check whether to allocate the iovec area */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
  	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...
1798
1799
1800
  		err = verify_compat_iovec(&msg_sys, iov,
  					  (struct sockaddr *)&address,
  					  VERIFY_READ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801
  	} else
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1802
1803
1804
  		err = verify_iovec(&msg_sys, iov,
  				   (struct sockaddr *)&address,
  				   VERIFY_READ);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1805
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806
1807
1808
1809
1810
1811
1812
  		goto out_freeiov;
  	total_len = err;
  
  	err = -ENOBUFS;
  
  	if (msg_sys.msg_controllen > INT_MAX)
  		goto out_freeiov;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1813
  	ctl_len = msg_sys.msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1814
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1815
1816
1817
  		err =
  		    cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl,
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
1819
1820
  		if (err)
  			goto out_freeiov;
  		ctl_buf = msg_sys.msg_control;
8920e8f94   Al Viro   [PATCH] Fix 32bit...
1821
  		ctl_len = msg_sys.msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1822
  	} else if (ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1823
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1824
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1825
  			if (ctl_buf == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
1827
1828
1829
1830
1831
1832
1833
  				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.
  		 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1834
1835
  		if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control,
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
  			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...
1846
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1847
1848
1849
1850
1851
  		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...
1852
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1853
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
1855
1856
1857
1858
1859
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1860
1861
  SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1863
1864
  	struct compat_msghdr __user *msg_compat =
  	    (struct compat_msghdr __user *)msg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
1866
  	struct socket *sock;
  	struct iovec iovstack[UIO_FASTIOV];
89bddce58   Stephen Hemminger   [NET] socket: cod...
1867
  	struct iovec *iov = iovstack;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868
1869
1870
  	struct msghdr msg_sys;
  	unsigned long cmsg_ptr;
  	int err, iov_size, total_len, len;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1871
  	int fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1872
1873
  
  	/* kernel mode address */
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1874
  	struct sockaddr_storage addr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
1876
1877
1878
  
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
  	int __user *uaddr_len;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1879

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
1881
1882
  	if (MSG_CMSG_COMPAT & flags) {
  		if (get_compat_msghdr(&msg_sys, msg_compat))
  			return -EFAULT;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1883
1884
1885
  	}
  	else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
  		return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1887
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1888
1889
1890
1891
1892
1893
  	if (!sock)
  		goto out;
  
  	err = -EMSGSIZE;
  	if (msg_sys.msg_iovlen > UIO_MAXIOV)
  		goto out_put;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1894
1895
  
  	/* Check whether to allocate the iovec area */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1896
1897
1898
1899
1900
1901
1902
1903
1904
  	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;
  	}
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1905
1906
  	 *      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
1907
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
1908

cfcabdcc2   Stephen Hemminger   [NET]: sparse war...
1909
  	uaddr = (__force void __user *)msg_sys.msg_name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1910
1911
  	uaddr_len = COMPAT_NAMELEN(msg);
  	if (MSG_CMSG_COMPAT & flags) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1912
1913
1914
  		err = verify_compat_iovec(&msg_sys, iov,
  					  (struct sockaddr *)&addr,
  					  VERIFY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
  	} else
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1916
1917
1918
  		err = verify_iovec(&msg_sys, iov,
  				   (struct sockaddr *)&addr,
  				   VERIFY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1919
1920
  	if (err < 0)
  		goto out_freeiov;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1921
  	total_len = err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
1923
  
  	cmsg_ptr = (unsigned long)msg_sys.msg_control;
4a19542e5   Ulrich Drepper   O_CLOEXEC for SCM...
1924
  	msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1925

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1926
1927
1928
1929
1930
1931
1932
1933
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	err = sock_recvmsg(sock, &msg_sys, total_len, flags);
  	if (err < 0)
  		goto out_freeiov;
  	len = err;
  
  	if (uaddr != NULL) {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1934
1935
  		err = move_addr_to_user((struct sockaddr *)&addr,
  					msg_sys.msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1936
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1937
1938
1939
  		if (err < 0)
  			goto out_freeiov;
  	}
37f7f421c   David S. Miller   [NET]: Do not lea...
1940
1941
  	err = __put_user((msg_sys.msg_flags & ~MSG_CMSG_COMPAT),
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1942
1943
1944
  	if (err)
  		goto out_freeiov;
  	if (MSG_CMSG_COMPAT & flags)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1945
  		err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1946
1947
  				 &msg_compat->msg_controllen);
  	else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1948
  		err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1949
1950
1951
1952
1953
1954
1955
1956
1957
  				 &msg->msg_controllen);
  	if (err)
  		goto out_freeiov;
  	err = len;
  
  out_freeiov:
  	if (iov != iovstack)
  		sock_kfree_s(sock->sk, iov, iov_size);
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1958
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1959
1960
1961
1962
1963
1964
1965
1966
  out:
  	return err;
  }
  
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
  
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1967
  static const unsigned char nargs[19]={
89bddce58   Stephen Hemminger   [NET] socket: cod...
1968
1969
  	AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
  	AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
aaca0bdca   Ulrich Drepper   flag parameters: ...
1970
  	AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
de11defeb   Ulrich Drepper   reintroduce accept4
1971
  	AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1972
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
1974
1975
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1976
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1977
1978
1979
   *
   *	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...
1980
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1981
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1982
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1983
1984
  {
  	unsigned long a[6];
89bddce58   Stephen Hemminger   [NET] socket: cod...
1985
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1986
  	int err;
de11defeb   Ulrich Drepper   reintroduce accept4
1987
  	if (call < 1 || call > SYS_ACCEPT4)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1988
1989
1990
1991
1992
  		return -EINVAL;
  
  	/* copy_from_user should be SMP safe. */
  	if (copy_from_user(a, args, nargs[call]))
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
1993

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
  	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
2013
2014
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2015
2016
2017
2018
2019
2020
2021
2022
2023
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
  		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;
de11defeb   Ulrich Drepper   reintroduce accept4
2061
2062
2063
  	case SYS_ACCEPT4:
  		err = sys_accept4(a0, (struct sockaddr __user *)a1,
  				  (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2064
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2065
2066
2067
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2068
2069
2070
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2071
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2072

55737fda0   Stephen Hemminger   [NET]: socket fam...
2073
2074
2075
2076
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2077
2078
   *	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...
2079
2080
   *	socket interface. The value ops->family coresponds to the
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2081
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2082
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2083
2084
2085
2086
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2087
2088
2089
  		printk(KERN_CRIT "protocol %d >= NPROTO(%d)
  ", ops->family,
  		       NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2090
2091
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2092
2093
2094
2095
2096
  
  	spin_lock(&net_family_lock);
  	if (net_families[ops->family])
  		err = -EEXIST;
  	else {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2097
  		net_families[ops->family] = ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2098
2099
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2100
  	spin_unlock(&net_family_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2101
2102
  	printk(KERN_INFO "NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2103
2104
  	return err;
  }
55737fda0   Stephen Hemminger   [NET]: socket fam...
2105
2106
2107
2108
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2109
2110
   *	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...
2111
2112
2113
2114
2115
2116
   *	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
2117
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2118
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2119
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2120
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2121

55737fda0   Stephen Hemminger   [NET]: socket fam...
2122
  	spin_lock(&net_family_lock);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2123
  	net_families[family] = NULL;
55737fda0   Stephen Hemminger   [NET]: socket fam...
2124
2125
2126
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
89bddce58   Stephen Hemminger   [NET] socket: cod...
2127
2128
  	printk(KERN_INFO "NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2129
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2130
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2131
2132
  {
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2133
  	 *      Initialize sock SLAB cache.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
  	 */
89bddce58   Stephen Hemminger   [NET] socket: cod...
2135

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2136
  	sk_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2137
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2138
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2139
2140
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2141
2142
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2143
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2144
2145
2146
2147
2148
  	 */
  
  	init_inodecache();
  	register_filesystem(&sock_fs_type);
  	sock_mnt = kern_mount(&sock_fs_type);
77d76ea31   Andi Kleen   [NET]: Small clea...
2149
2150
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2151
2152
2153
2154
2155
  	 */
  
  #ifdef CONFIG_NETFILTER
  	netfilter_init();
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2156
2157
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2158
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2159
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
2161
2162
2163
2164
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
  	int cpu;
  	int counter = 0;
6f9120422   KAMEZAWA Hiroyuki   [PATCH] for_each_...
2165
  	for_each_possible_cpu(cpu)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2166
  	    counter += per_cpu(sockets_in_use, cpu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2167
2168
2169
2170
2171
2172
2173
2174
  
  	/* 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...
2175
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2176

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2177
2178
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file, unsigned cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2179
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2180
2181
2182
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
2183
2184
2185
2186
2187
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2188
2189
2190
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
2191
2192
2193
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2194
2195
2196
  	return ret;
  }
  #endif
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
  
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
  
  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...
2220
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2221
2222
2223
2224
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
2225
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2226
2227
2228
2229
2230
2231
  
  done:
  	return err;
  }
  
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
2232
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
  
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 0);
  }
  
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
  			 int *addrlen)
  {
  	return sock->ops->getname(sock, addr, addrlen, 1);
  }
  
  int kernel_getsockopt(struct socket *sock, int level, int optname,
  			char *optval, int *optlen)
  {
  	mm_segment_t oldfs = get_fs();
  	int err;
  
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
  		err = sock_getsockopt(sock, level, optname, optval, optlen);
  	else
  		err = sock->ops->getsockopt(sock, level, optname, optval,
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
  
  int kernel_setsockopt(struct socket *sock, int level, int optname,
  			char *optval, int optlen)
  {
  	mm_segment_t oldfs = get_fs();
  	int err;
  
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
  		err = sock_setsockopt(sock, level, optname, optval, optlen);
  	else
  		err = sock->ops->setsockopt(sock, level, optname, optval,
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
  
  int kernel_sendpage(struct socket *sock, struct page *page, int offset,
  		    size_t size, int flags)
  {
  	if (sock->ops->sendpage)
  		return sock->ops->sendpage(sock, page, offset, size, flags);
  
  	return sock_no_sendpage(sock, page, offset, size, flags);
  }
  
  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;
  }
91cf45f02   Trond Myklebust   [NET]: Add the he...
2301
2302
2303
2304
  int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
  {
  	return sock->ops->shutdown(sock, how);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
  EXPORT_SYMBOL(sock_create);
  EXPORT_SYMBOL(sock_create_kern);
  EXPORT_SYMBOL(sock_create_lite);
  EXPORT_SYMBOL(sock_map_fd);
  EXPORT_SYMBOL(sock_recvmsg);
  EXPORT_SYMBOL(sock_register);
  EXPORT_SYMBOL(sock_release);
  EXPORT_SYMBOL(sock_sendmsg);
  EXPORT_SYMBOL(sock_unregister);
  EXPORT_SYMBOL(sock_wake_async);
  EXPORT_SYMBOL(sockfd_lookup);
  EXPORT_SYMBOL(kernel_sendmsg);
  EXPORT_SYMBOL(kernel_recvmsg);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
  EXPORT_SYMBOL(kernel_bind);
  EXPORT_SYMBOL(kernel_listen);
  EXPORT_SYMBOL(kernel_accept);
  EXPORT_SYMBOL(kernel_connect);
  EXPORT_SYMBOL(kernel_getsockname);
  EXPORT_SYMBOL(kernel_getpeername);
  EXPORT_SYMBOL(kernel_getsockopt);
  EXPORT_SYMBOL(kernel_setsockopt);
  EXPORT_SYMBOL(kernel_sendpage);
  EXPORT_SYMBOL(kernel_sock_ioctl);
91cf45f02   Trond Myklebust   [NET]: Add the he...
2328
  EXPORT_SYMBOL(kernel_sock_shutdown);