Blame view

net/socket.c 95.2 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
  /*
   * 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...
8
   *		Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
45
   *		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...
46
   *		Tigran Aivazian	:	Made listen(2) backlog sanity checks
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
48
   *					protocol-independent
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
   *	This module is effectively the top level interface to the BSD socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
50
   *	paradigm.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
   *
   *	Based upon Swansea University Computer Society NET3.039
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
  #include <linux/socket.h>
  #include <linux/file.h>
  #include <linux/net.h>
  #include <linux/interrupt.h>
aaca0bdca   Ulrich Drepper   flag parameters: ...
59
  #include <linux/thread_info.h>
55737fda0   Stephen Hemminger   [NET]: socket fam...
60
  #include <linux/rcupdate.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
  #include <linux/netdevice.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
64
  #include <linux/mutex.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
  #include <linux/if_bridge.h>
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
66
67
  #include <linux/if_frad.h>
  #include <linux/if_vlan.h>
408eccce3   Daniel Borkmann   net: ptp: move PT...
68
  #include <linux/ptp_classify.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
72
73
  #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
74
  #include <linux/mount.h>
fba9be497   David Howells   vfs: Convert sock...
75
  #include <linux/pseudo_fs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
  #include <linux/security.h>
  #include <linux/syscalls.h>
  #include <linux/compat.h>
  #include <linux/kmod.h>
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
80
  #include <linux/audit.h>
d86b5e0e6   Adrian Bunk   [PATCH] net/: fix...
81
  #include <linux/wireless.h>
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
82
  #include <linux/nsproxy.h>
1fd7317d0   Nick Black   Move magic number...
83
  #include <linux/magic.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
84
  #include <linux/slab.h>
600e17792   Masatake YAMATO   net: Providing pr...
85
  #include <linux/xattr.h>
c8e8cd579   Jeremy Cline   net: socket: fix ...
86
  #include <linux/nospec.h>
8c3c447b3   Paolo Abeni   net: use indirect...
87
  #include <linux/indirect_call_wrapper.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88

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

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

8ae5e030f   Al Viro   net: switch socke...
111
112
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
89bddce58   Stephen Hemminger   [NET] socket: cod...
113
  static int sock_mmap(struct file *file, struct vm_area_struct *vma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
115
  
  static int sock_close(struct inode *inode, struct file *file);
a11e1d432   Linus Torvalds   Revert changes to...
116
117
  static __poll_t sock_poll(struct file *file,
  			      struct poll_table_struct *wait);
89bddce58   Stephen Hemminger   [NET] socket: cod...
118
  static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
119
120
  #ifdef CONFIG_COMPAT
  static long compat_sock_ioctl(struct file *file,
89bddce58   Stephen Hemminger   [NET] socket: cod...
121
  			      unsigned int cmd, unsigned long arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
122
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
  static int sock_fasync(int fd, struct file *filp, int on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
  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...
126
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
127
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
128
  				unsigned int flags);
542d3065f   Arnd Bergmann   socket: fix unuse...
129
130
131
132
133
134
135
136
137
138
139
140
  
  #ifdef CONFIG_PROC_FS
  static void sock_show_fdinfo(struct seq_file *m, struct file *f)
  {
  	struct socket *sock = f->private_data;
  
  	if (sock->ops->show_fdinfo)
  		sock->ops->show_fdinfo(m, sock);
  }
  #else
  #define sock_show_fdinfo NULL
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
172
173
174
   * 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
175
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
179
180
181
182
183
184
185
  /**
   *	move_addr_to_kernel	-	copy a socket address into kernel space
   *	@uaddr: Address in user space
   *	@kaddr: Address in kernel space
   *	@ulen: Length in user space
   *
   *	The address is copied into kernel space. If the provided address is
   *	too long an error code of -EINVAL is returned. If the copy gives
   *	invalid addresses -EFAULT is returned. On a success 0 is returned.
   */
43db362d3   Maciej Å»enczykowski   net: get rid of s...
186
  int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
  {
230b18392   YOSHIFUJI Hideaki   net: Use standard...
188
  	if (ulen < 0 || ulen > sizeof(struct sockaddr_storage))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
190
  	if (ulen == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  		return 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
192
  	if (copy_from_user(kaddr, uaddr, ulen))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
194
  	return audit_sockaddr(ulen, kaddr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  }
  
  /**
   *	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...
213

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

e94b17660   Christoph Lameter   [PATCH] slab: rem...
245
  	ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
  	if (!ei)
  		return NULL;
333f7909a   Al Viro   coallocate socket...
248
249
250
  	init_waitqueue_head(&ei->socket.wq.wait);
  	ei->socket.wq.fasync_list = NULL;
  	ei->socket.wq.flags = 0;
89bddce58   Stephen Hemminger   [NET] socket: cod...
251

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
  	ei->socket.state = SS_UNCONNECTED;
  	ei->socket.flags = 0;
  	ei->socket.ops = NULL;
  	ei->socket.sk = NULL;
  	ei->socket.file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
  
  	return &ei->vfs_inode;
  }
6d7855c54   Al Viro   sockfs: switch to...
260
  static void sock_free_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  {
438154823   Eric Dumazet   net: sock_def_rea...
262
263
264
  	struct socket_alloc *ei;
  
  	ei = container_of(inode, struct socket_alloc, vfs_inode);
438154823   Eric Dumazet   net: sock_def_rea...
265
  	kmem_cache_free(sock_inode_cachep, ei);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  }
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
267
  static void init_once(void *foo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
269
  	struct socket_alloc *ei = (struct socket_alloc *)foo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270

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

1e9116327   yuan linyu   net: change init_...
274
  static void init_inodecache(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
  {
  	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
89bddce58   Stephen Hemminger   [NET] socket: cod...
277
278
279
280
  					      sizeof(struct socket_alloc),
  					      0,
  					      (SLAB_HWCACHE_ALIGN |
  					       SLAB_RECLAIM_ACCOUNT |
5d097056c   Vladimir Davydov   kmemcg: account c...
281
  					       SLAB_MEM_SPREAD | SLAB_ACCOUNT),
20c2df83d   Paul Mundt   mm: Remove slab d...
282
  					      init_once);
1e9116327   yuan linyu   net: change init_...
283
  	BUG_ON(sock_inode_cachep == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  }
b87221de6   Alexey Dobriyan   const: mark remai...
285
  static const struct super_operations sockfs_ops = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
286
  	.alloc_inode	= sock_alloc_inode,
6d7855c54   Al Viro   sockfs: switch to...
287
  	.free_inode	= sock_free_inode,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
288
  	.statfs		= simple_statfs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  };
c23fbb6bc   Eric Dumazet   VFS: delay the de...
290
291
292
293
294
295
  /*
   * sockfs_dname() is called from d_path().
   */
  static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
  {
  	return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
c5ef60352   David Howells   VFS: net/: d_inod...
296
  				d_inode(dentry)->i_ino);
c23fbb6bc   Eric Dumazet   VFS: delay the de...
297
  }
3ba13d179   Al Viro   constify dentry_o...
298
  static const struct dentry_operations sockfs_dentry_operations = {
c23fbb6bc   Eric Dumazet   VFS: delay the de...
299
  	.d_dname  = sockfs_dname,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  };
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
  static int sockfs_xattr_get(const struct xattr_handler *handler,
  			    struct dentry *dentry, struct inode *inode,
  			    const char *suffix, void *value, size_t size)
  {
  	if (value) {
  		if (dentry->d_name.len + 1 > size)
  			return -ERANGE;
  		memcpy(value, dentry->d_name.name, dentry->d_name.len + 1);
  	}
  	return dentry->d_name.len + 1;
  }
  
  #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
  #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
  #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
  
  static const struct xattr_handler sockfs_xattr_handler = {
  	.name = XATTR_NAME_SOCKPROTONAME,
  	.get = sockfs_xattr_get,
  };
4a5901537   Andreas Gruenbacher   xattr: Fix settin...
321
322
323
324
325
326
327
328
329
330
331
332
333
  static int sockfs_security_xattr_set(const struct xattr_handler *handler,
  				     struct dentry *dentry, struct inode *inode,
  				     const char *suffix, const void *value,
  				     size_t size, int flags)
  {
  	/* Handled by LSM. */
  	return -EAGAIN;
  }
  
  static const struct xattr_handler sockfs_security_xattr_handler = {
  	.prefix = XATTR_SECURITY_PREFIX,
  	.set = sockfs_security_xattr_set,
  };
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
334
335
  static const struct xattr_handler *sockfs_xattr_handlers[] = {
  	&sockfs_xattr_handler,
4a5901537   Andreas Gruenbacher   xattr: Fix settin...
336
  	&sockfs_security_xattr_handler,
bba0bd31b   Andreas Gruenbacher   sockfs: Get rid o...
337
338
  	NULL
  };
fba9be497   David Howells   vfs: Convert sock...
339
  static int sockfs_init_fs_context(struct fs_context *fc)
c74a1cbb3   Al Viro   pass default dent...
340
  {
fba9be497   David Howells   vfs: Convert sock...
341
342
343
344
345
346
347
  	struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC);
  	if (!ctx)
  		return -ENOMEM;
  	ctx->ops = &sockfs_ops;
  	ctx->dops = &sockfs_dentry_operations;
  	ctx->xattr = sockfs_xattr_handlers;
  	return 0;
c74a1cbb3   Al Viro   pass default dent...
348
349
350
351
352
353
  }
  
  static struct vfsmount *sock_mnt __read_mostly;
  
  static struct file_system_type sock_fs_type = {
  	.name =		"sockfs",
fba9be497   David Howells   vfs: Convert sock...
354
  	.init_fs_context = sockfs_init_fs_context,
c74a1cbb3   Al Viro   pass default dent...
355
356
  	.kill_sb =	kill_anon_super,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
  /*
   *	Obtains the first available file descriptor and sets it up for use.
   *
39d8c1b6f   David S. Miller   [NET]: Do not los...
360
361
   *	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
362
363
364
365
366
367
368
369
370
371
372
   *	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.
   */
8a3c245c0   Pedro Tammela   net: add document...
373
374
375
376
377
378
379
380
381
382
383
  /**
   *	sock_alloc_file - Bind a &socket to a &file
   *	@sock: socket
   *	@flags: file status flags
   *	@dname: protocol name
   *
   *	Returns the &file bound with @sock, implicitly storing it
   *	in sock->file. If dname is %NULL, sets to "".
   *	On failure the return is a ERR pointer (see linux/err.h).
   *	This function uses GFP_KERNEL internally.
   */
aab174f0d   Linus Torvalds   Merge branch 'for...
384
  struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  {
7cbe66b6b   Al Viro   merge sock_alloc_...
386
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387

d93aa9d82   Al Viro   new wrapper: allo...
388
389
  	if (!dname)
  		dname = sock->sk ? sock->sk->sk_prot_creator->name : "";
39d8c1b6f   David S. Miller   [NET]: Do not los...
390

d93aa9d82   Al Viro   new wrapper: allo...
391
392
393
  	file = alloc_file_pseudo(SOCK_INODE(sock), sock_mnt, dname,
  				O_RDWR | (flags & O_NONBLOCK),
  				&socket_file_ops);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
394
  	if (IS_ERR(file)) {
8e1611e23   Al Viro   make sock_alloc_f...
395
  		sock_release(sock);
39b652527   Anatol Pomozov   fs: Preserve erro...
396
  		return file;
cc3808f8c   Al Viro   switch sock_alloc...
397
398
399
  	}
  
  	sock->file = file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
400
  	file->private_data = sock;
d8e464ecc   Linus Torvalds   vfs: mark pipes a...
401
  	stream_open(SOCK_INODE(sock), file);
284076305   Al Viro   take descriptor h...
402
  	return file;
39d8c1b6f   David S. Miller   [NET]: Do not los...
403
  }
56b31d1c9   Al Viro   unexport sock_map...
404
  EXPORT_SYMBOL(sock_alloc_file);
39d8c1b6f   David S. Miller   [NET]: Do not los...
405

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

aab174f0d   Linus Torvalds   Merge branch 'for...
415
  	newfile = sock_alloc_file(sock, flags, NULL);
4546e44ca   Enrico Weigelt   net: socket: drop...
416
  	if (!IS_ERR(newfile)) {
39d8c1b6f   David S. Miller   [NET]: Do not los...
417
  		fd_install(fd, newfile);
284076305   Al Viro   take descriptor h...
418
419
  		return fd;
  	}
7cbe66b6b   Al Viro   merge sock_alloc_...
420

284076305   Al Viro   take descriptor h...
421
422
  	put_unused_fd(fd);
  	return PTR_ERR(newfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
  }
8a3c245c0   Pedro Tammela   net: add document...
424
425
426
427
428
429
430
  /**
   *	sock_from_file - Return the &socket bounded to @file.
   *	@file: file
   *	@err: pointer to an error code return
   *
   *	On failure returns %NULL and assigns -ENOTSOCK to @err.
   */
406a3c638   John Fastabend   net: netprio_cgro...
431
  struct socket *sock_from_file(struct file *file, int *err)
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
432
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
433
434
  	if (file->f_op == &socket_file_ops)
  		return file->private_data;	/* set in sock_map_fd */
23bb80d21   Eric Dumazet   [NET]: cleanup so...
435
436
  	*err = -ENOTSOCK;
  	return NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
437
  }
406a3c638   John Fastabend   net: netprio_cgro...
438
  EXPORT_SYMBOL(sock_from_file);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
439

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  /**
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
441
   *	sockfd_lookup - Go from a file number to its socket slot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
445
   *	@fd: file handle
   *	@err: pointer to an error code return
   *
   *	The file handle passed in is locked and the socket it is bound
241c4667f   Rosen, Rami   net: socket: fix ...
446
   *	to is returned. If an error occurs the err pointer is overwritten
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
449
450
451
452
453
454
455
   *	with a negative errno code and NULL is returned. The function checks
   *	for both invalid handles and passing a handle which is not a socket.
   *
   *	On a success the socket object pointer is returned.
   */
  
  struct socket *sockfd_lookup(int fd, int *err)
  {
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
457
458
  	file = fget(fd);
  	if (!file) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
460
461
  		*err = -EBADF;
  		return NULL;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
462

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

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
470
471
  static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
  {
00e188ef6   Al Viro   sockfd_lookup_lig...
472
  	struct fd f = fdget(fd);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
473
  	struct socket *sock;
3672558c6   Hua Zhong   [NET]: sockfd_loo...
474
  	*err = -EBADF;
00e188ef6   Al Viro   sockfd_lookup_lig...
475
476
477
478
  	if (f.file) {
  		sock = sock_from_file(f.file, err);
  		if (likely(sock)) {
  			*fput_needed = f.flags;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
479
  			return sock;
00e188ef6   Al Viro   sockfd_lookup_lig...
480
481
  		}
  		fdput(f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
  	}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
483
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  }
600e17792   Masatake YAMATO   net: Providing pr...
485
486
487
488
489
  static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
  				size_t size)
  {
  	ssize_t len;
  	ssize_t used = 0;
c5ef60352   David Howells   VFS: net/: d_inod...
490
  	len = security_inode_listsecurity(d_inode(dentry), buffer, size);
600e17792   Masatake YAMATO   net: Providing pr...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  	if (len < 0)
  		return len;
  	used += len;
  	if (buffer) {
  		if (size < used)
  			return -ERANGE;
  		buffer += len;
  	}
  
  	len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
  	used += len;
  	if (buffer) {
  		if (size < used)
  			return -ERANGE;
  		memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
  		buffer += len;
  	}
  
  	return used;
  }
dc647ec88   Tobias Klauser   net: socket: Make...
511
  static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
86741ec25   Lorenzo Colitti   net: core: Add a ...
512
513
  {
  	int err = simple_setattr(dentry, iattr);
e1a3a60a2   Eric Biggers   net: socket: don'...
514
  	if (!err && (iattr->ia_valid & ATTR_UID)) {
86741ec25   Lorenzo Colitti   net: core: Add a ...
515
  		struct socket *sock = SOCKET_I(d_inode(dentry));
6d8c50dcb   Cong Wang   socket: close rac...
516
517
518
519
  		if (sock->sk)
  			sock->sk->sk_uid = iattr->ia_uid;
  		else
  			err = -ENOENT;
86741ec25   Lorenzo Colitti   net: core: Add a ...
520
521
522
523
  	}
  
  	return err;
  }
600e17792   Masatake YAMATO   net: Providing pr...
524
  static const struct inode_operations sockfs_inode_ops = {
600e17792   Masatake YAMATO   net: Providing pr...
525
  	.listxattr = sockfs_listxattr,
86741ec25   Lorenzo Colitti   net: core: Add a ...
526
  	.setattr = sockfs_setattr,
600e17792   Masatake YAMATO   net: Providing pr...
527
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  /**
8a3c245c0   Pedro Tammela   net: add document...
529
   *	sock_alloc - allocate a socket
89bddce58   Stephen Hemminger   [NET] socket: cod...
530
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
   *	Allocate a new inode and socket object. The two are bound together
   *	and initialised. The socket is then returned. If we are out of inodes
8a3c245c0   Pedro Tammela   net: add document...
533
   *	NULL is returned. This functions uses GFP_KERNEL internally.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
   */
f4a00aacd   Tom Herbert   net: Make sock_al...
535
  struct socket *sock_alloc(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
  {
89bddce58   Stephen Hemminger   [NET] socket: cod...
537
538
  	struct inode *inode;
  	struct socket *sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
  /**
8a3c245c0   Pedro Tammela   net: add document...
556
   *	sock_release - close a socket
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
557
558
559
560
   *	@sock: socket to close
   *
   *	The socket is released from the protocol stack if it has a release
   *	callback, and the inode is then released if the socket is bound to
89bddce58   Stephen Hemminger   [NET] socket: cod...
561
   *	an inode not a file.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
   */
89bddce58   Stephen Hemminger   [NET] socket: cod...
563

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

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

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

8c3c447b3   Paolo Abeni   net: use indirect...
607
608
  INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
  					   size_t));
a648a592d   Paolo Abeni   net: adjust socke...
609
610
  INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *,
  					    size_t));
d8725c86a   Al Viro   get rid of the si...
611
  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
  {
a648a592d   Paolo Abeni   net: adjust socke...
613
614
615
  	int ret = INDIRECT_CALL_INET(sock->ops->sendmsg, inet6_sendmsg,
  				     inet_sendmsg, sock, msg,
  				     msg_data_left(msg));
d8725c86a   Al Viro   get rid of the si...
616
617
  	BUG_ON(ret == -EIOCBQUEUED);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
  }
85806af0c   Randy Dunlap   net: fix kernel-d...
619
620
621
622
623
624
625
626
  /**
   *	sock_sendmsg - send a message through @sock
   *	@sock: socket
   *	@msg: message to send
   *
   *	Sends @msg through @sock, passing through LSM.
   *	Returns the number of bytes sent, or an error code.
   */
d8725c86a   Al Viro   get rid of the si...
627
  int sock_sendmsg(struct socket *sock, struct msghdr *msg)
228e548e6   Anton Blanchard   net: Add sendmmsg...
628
  {
d8725c86a   Al Viro   get rid of the si...
629
  	int err = security_socket_sendmsg(sock, msg,
01e97e651   Al Viro   new helper: msg_d...
630
  					  msg_data_left(msg));
228e548e6   Anton Blanchard   net: Add sendmmsg...
631

d8725c86a   Al Viro   get rid of the si...
632
  	return err ?: sock_sendmsg_nosec(sock, msg);
0cf00c6f3   Gu Zheng   net/socket.c : in...
633
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
634
  EXPORT_SYMBOL(sock_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635

8a3c245c0   Pedro Tammela   net: add document...
636
637
638
639
640
641
642
643
644
645
646
  /**
   *	kernel_sendmsg - send a message through @sock (kernel-space)
   *	@sock: socket
   *	@msg: message header
   *	@vec: kernel vec
   *	@num: vec array length
   *	@size: total message data size
   *
   *	Builds the message data with @vec and sends it through @sock.
   *	Returns the number of bytes sent, or an error code.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
648
649
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size)
  {
aa563d7bc   David Howells   iov_iter: Separat...
650
  	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
d8725c86a   Al Viro   get rid of the si...
651
  	return sock_sendmsg(sock, msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
653
  EXPORT_SYMBOL(kernel_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654

8a3c245c0   Pedro Tammela   net: add document...
655
656
657
658
659
660
661
662
663
664
665
666
  /**
   *	kernel_sendmsg_locked - send a message through @sock (kernel-space)
   *	@sk: sock
   *	@msg: message header
   *	@vec: output s/g array
   *	@num: output s/g array length
   *	@size: total message data size
   *
   *	Builds the message data with @vec and sends it through @sock.
   *	Returns the number of bytes sent, or an error code.
   *	Caller must hold @sk.
   */
306b13eb3   Tom Herbert   proto_ops: Add lo...
667
668
669
670
671
672
  int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,
  			  struct kvec *vec, size_t num, size_t size)
  {
  	struct socket *sock = sk->sk_socket;
  
  	if (!sock->ops->sendmsg_locked)
db5980d80   John Fastabend   net: fixes for sk...
673
  		return sock_no_sendmsg_locked(sk, msg, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
674

aa563d7bc   David Howells   iov_iter: Separat...
675
  	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
676
677
678
679
  
  	return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
  }
  EXPORT_SYMBOL(kernel_sendmsg_locked);
8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
680
681
682
683
684
685
686
687
688
  static bool skb_is_err_queue(const struct sk_buff *skb)
  {
  	/* pkt_type of skbs enqueued on the error queue are set to
  	 * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
  	 * in recvmsg, since skbs received on a local socket will never
  	 * have a pkt_type of PACKET_OUTGOING.
  	 */
  	return skb->pkt_type == PACKET_OUTGOING;
  }
b50a5c70f   Miroslav Lichvar   net: allow simult...
689
690
691
692
693
  /* On transmit, software and hardware timestamps are returned independently.
   * As the two skb clones share the hardware timestamp, which may be updated
   * before the software timestamp is received, a hardware TX timestamp may be
   * returned only if there is no software TX timestamp. Ignore false software
   * timestamps, which may be made in the __sock_recv_timestamp() call when the
7f1bc6e95   Deepa Dinamani   sockopt: Rename S...
694
   * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
b50a5c70f   Miroslav Lichvar   net: allow simult...
695
696
697
698
699
700
   * hardware timestamp.
   */
  static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
  {
  	return skb->tstamp && !false_tstamp && skb_is_err_queue(skb);
  }
aad9c8c47   Miroslav Lichvar   net: add new cont...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
  static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb)
  {
  	struct scm_ts_pktinfo ts_pktinfo;
  	struct net_device *orig_dev;
  
  	if (!skb_mac_header_was_set(skb))
  		return;
  
  	memset(&ts_pktinfo, 0, sizeof(ts_pktinfo));
  
  	rcu_read_lock();
  	orig_dev = dev_get_by_napi_id(skb_napi_id(skb));
  	if (orig_dev)
  		ts_pktinfo.if_index = orig_dev->ifindex;
  	rcu_read_unlock();
  
  	ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb);
  	put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
  		 sizeof(ts_pktinfo), &ts_pktinfo);
  }
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
721
722
723
724
725
726
  /*
   * 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...
727
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
887feae36   Deepa Dinamani   socket: Add SO_TI...
728
  	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
9718475e6   Deepa Dinamani   socket: Add SO_TI...
729
  	struct scm_timestamping_internal tss;
b50a5c70f   Miroslav Lichvar   net: allow simult...
730
  	int empty = 1, false_tstamp = 0;
20d494735   Patrick Ohly   net: socket infra...
731
732
733
734
735
  	struct skb_shared_hwtstamps *shhwtstamps =
  		skb_hwtstamps(skb);
  
  	/* Race occurred between timestamp enabling and packet
  	   receiving.  Fill in the current time for now. */
b50a5c70f   Miroslav Lichvar   net: allow simult...
736
  	if (need_software_tstamp && skb->tstamp == 0) {
20d494735   Patrick Ohly   net: socket infra...
737
  		__net_timestamp(skb);
b50a5c70f   Miroslav Lichvar   net: allow simult...
738
739
  		false_tstamp = 1;
  	}
20d494735   Patrick Ohly   net: socket infra...
740
741
742
  
  	if (need_software_tstamp) {
  		if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
887feae36   Deepa Dinamani   socket: Add SO_TI...
743
744
745
746
747
748
749
750
751
752
753
754
755
  			if (new_tstamp) {
  				struct __kernel_sock_timeval tv;
  
  				skb_get_new_timestamp(skb, &tv);
  				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
  					 sizeof(tv), &tv);
  			} else {
  				struct __kernel_old_timeval tv;
  
  				skb_get_timestamp(skb, &tv);
  				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
  					 sizeof(tv), &tv);
  			}
20d494735   Patrick Ohly   net: socket infra...
756
  		} else {
887feae36   Deepa Dinamani   socket: Add SO_TI...
757
758
759
760
761
762
763
  			if (new_tstamp) {
  				struct __kernel_timespec ts;
  
  				skb_get_new_timestampns(skb, &ts);
  				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
  					 sizeof(ts), &ts);
  			} else {
df1b4ba9d   Arnd Bergmann   y2038: socket: us...
764
  				struct __kernel_old_timespec ts;
887feae36   Deepa Dinamani   socket: Add SO_TI...
765
766
767
768
769
  
  				skb_get_timestampns(skb, &ts);
  				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
  					 sizeof(ts), &ts);
  			}
20d494735   Patrick Ohly   net: socket infra...
770
771
  		}
  	}
f24b9be59   Willem de Bruijn   net-timestamp: ex...
772
  	memset(&tss, 0, sizeof(tss));
c199105d1   Willem de Bruijn   net-timestamp: on...
773
  	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
9718475e6   Deepa Dinamani   socket: Add SO_TI...
774
  	    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
20d494735   Patrick Ohly   net: socket infra...
775
  		empty = 0;
4d276eb6a   Willem de Bruijn   net: remove depre...
776
  	if (shhwtstamps &&
b9f40e21e   Willem de Bruijn   net-timestamp: mo...
777
  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
b50a5c70f   Miroslav Lichvar   net: allow simult...
778
  	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
9718475e6   Deepa Dinamani   socket: Add SO_TI...
779
  	    ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
4d276eb6a   Willem de Bruijn   net: remove depre...
780
  		empty = 0;
aad9c8c47   Miroslav Lichvar   net: add new cont...
781
782
783
784
  		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
  		    !skb_is_err_queue(skb))
  			put_ts_pktinfo(msg, skb);
  	}
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
785
  	if (!empty) {
9718475e6   Deepa Dinamani   socket: Add SO_TI...
786
787
788
789
  		if (sock_flag(sk, SOCK_TSTAMP_NEW))
  			put_cmsg_scm_timestamping64(msg, &tss);
  		else
  			put_cmsg_scm_timestamping(msg, &tss);
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
790

8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
791
  		if (skb_is_err_queue(skb) && skb->len &&
4ef1b2869   Soheil Hassas Yeganeh   tcp: mark skbs wi...
792
  		    SKB_EXT_ERR(skb)->opt_stats)
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
793
794
795
  			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
  				 skb->len, skb->data);
  	}
92f37fd2e   Eric Dumazet   [NET]: Adding SO_...
796
  }
7c81fd8bf   Arnaldo Carvalho de Melo   [SOCKET]: Export ...
797
  EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
6e3e939f3   Johannes Berg   net: add wireless...
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
  void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,
  	struct sk_buff *skb)
  {
  	int ack;
  
  	if (!sock_flag(sk, SOCK_WIFI_STATUS))
  		return;
  	if (!skb->wifi_acked_valid)
  		return;
  
  	ack = skb->wifi_acked;
  
  	put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack);
  }
  EXPORT_SYMBOL_GPL(__sock_recv_wifi_status);
11165f145   stephen hemminger   socket: localize ...
813
814
  static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
  				   struct sk_buff *skb)
3b885787e   Neil Horman   net: Generalize s...
815
  {
744d5a3e9   Eyal Birger   net: move skb->dr...
816
  	if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount)
3b885787e   Neil Horman   net: Generalize s...
817
  		put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
744d5a3e9   Eyal Birger   net: move skb->dr...
818
  			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
3b885787e   Neil Horman   net: Generalize s...
819
  }
767dd0336   Eric Dumazet   net: speedup sock...
820
  void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
3b885787e   Neil Horman   net: Generalize s...
821
822
823
824
825
  	struct sk_buff *skb)
  {
  	sock_recv_timestamp(msg, sk, skb);
  	sock_recv_drops(msg, sk, skb);
  }
767dd0336   Eric Dumazet   net: speedup sock...
826
  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
3b885787e   Neil Horman   net: Generalize s...
827

8c3c447b3   Paolo Abeni   net: use indirect...
828
  INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
a648a592d   Paolo Abeni   net: adjust socke...
829
830
831
  					   size_t, int));
  INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *,
  					    size_t, int));
1b7841404   Ying Xue   net: Remove iocb ...
832
  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
2da62906b   Al Viro   [net] drop 'size'...
833
  				     int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
  {
a648a592d   Paolo Abeni   net: adjust socke...
835
836
837
  	return INDIRECT_CALL_INET(sock->ops->recvmsg, inet6_recvmsg,
  				  inet_recvmsg, sock, msg, msg_data_left(msg),
  				  flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  }
85806af0c   Randy Dunlap   net: fix kernel-d...
839
840
841
842
843
844
845
846
847
  /**
   *	sock_recvmsg - receive a message from @sock
   *	@sock: socket
   *	@msg: message to receive
   *	@flags: message flags
   *
   *	Receives @msg from @sock, passing through LSM. Returns the total number
   *	of bytes received, or an error.
   */
2da62906b   Al Viro   [net] drop 'size'...
848
  int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
849
  {
2da62906b   Al Viro   [net] drop 'size'...
850
  	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
851

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

c1249c0aa   Martin Lucina   net: Document the...
856
  /**
8a3c245c0   Pedro Tammela   net: add document...
857
858
859
860
861
862
863
   *	kernel_recvmsg - Receive a message from a socket (kernel space)
   *	@sock: The socket to receive the message from
   *	@msg: Received message
   *	@vec: Input s/g array for message data
   *	@num: Size of input s/g array
   *	@size: Number of bytes to read
   *	@flags: Message flags (MSG_DONTWAIT, etc...)
c1249c0aa   Martin Lucina   net: Document the...
864
   *
8a3c245c0   Pedro Tammela   net: add document...
865
866
867
   *	On return the msg structure contains the scatter/gather array passed in the
   *	vec argument. The array is modified so that it consists of the unfilled
   *	portion of the original array.
c1249c0aa   Martin Lucina   net: Document the...
868
   *
8a3c245c0   Pedro Tammela   net: add document...
869
   *	The returned value is the total number of bytes received, or an error.
c1249c0aa   Martin Lucina   net: Document the...
870
   */
8a3c245c0   Pedro Tammela   net: add document...
871

89bddce58   Stephen Hemminger   [NET] socket: cod...
872
873
  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
874
875
876
  {
  	mm_segment_t oldfs = get_fs();
  	int result;
aa563d7bc   David Howells   iov_iter: Separat...
877
  	iov_iter_kvec(&msg->msg_iter, READ, vec, num, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
  	set_fs(KERNEL_DS);
2da62906b   Al Viro   [net] drop 'size'...
879
  	result = sock_recvmsg(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880
881
882
  	set_fs(oldfs);
  	return result;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
883
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
885
886
  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
887
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
889
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
890
  	sock = file->private_data;
35f9c09fe   Eric Dumazet   tcp: tcp_sendpage...
891
892
893
  	flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
  	/* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */
  	flags |= more;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
894

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

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
898
  static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
899
  				struct pipe_inode_info *pipe, size_t len,
9c55e01c0   Jens Axboe   [TCP]: Splice rec...
900
901
902
  				unsigned int flags)
  {
  	struct socket *sock = file->private_data;
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
903
  	if (unlikely(!sock->ops->splice_read))
95506588d   Slavomir Kaslev   socket: do a gene...
904
  		return generic_file_splice_read(file, ppos, pipe, len, flags);
997b37da1   Rémi Denis-Courmont   [NET]: Make sure ...
905

9c55e01c0   Jens Axboe   [TCP]: Splice rec...
906
907
  	return sock->ops->splice_read(sock, ppos, pipe, len, flags);
  }
8ae5e030f   Al Viro   net: switch socke...
908
  static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
909
  {
6d6523302   Al Viro   net/socket.c: fol...
910
911
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
912
913
  	struct msghdr msg = {.msg_iter = *to,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
914
  	ssize_t res;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
915

ebfcd8955   Jens Axboe   net: make socket ...
916
  	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
8ae5e030f   Al Viro   net: switch socke...
917
918
919
  		msg.msg_flags = MSG_DONTWAIT;
  
  	if (iocb->ki_pos != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920
  		return -ESPIPE;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
921

66ee59af6   Christoph Hellwig   fs: remove ki_nbytes
922
  	if (!iov_iter_count(to))	/* Match SYS5 behaviour */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923
  		return 0;
2da62906b   Al Viro   [net] drop 'size'...
924
  	res = sock_recvmsg(sock, &msg, msg.msg_flags);
8ae5e030f   Al Viro   net: switch socke...
925
926
  	*to = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
  }
8ae5e030f   Al Viro   net: switch socke...
928
  static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from)
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
929
  {
6d6523302   Al Viro   net/socket.c: fol...
930
931
  	struct file *file = iocb->ki_filp;
  	struct socket *sock = file->private_data;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
932
933
  	struct msghdr msg = {.msg_iter = *from,
  			     .msg_iocb = iocb};
8ae5e030f   Al Viro   net: switch socke...
934
  	ssize_t res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
935

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

ebfcd8955   Jens Axboe   net: make socket ...
939
  	if (file->f_flags & O_NONBLOCK || (iocb->ki_flags & IOCB_NOWAIT))
8ae5e030f   Al Viro   net: switch socke...
940
  		msg.msg_flags = MSG_DONTWAIT;
6d6523302   Al Viro   net/socket.c: fol...
941
942
  	if (sock->type == SOCK_SEQPACKET)
  		msg.msg_flags |= MSG_EOR;
d8725c86a   Al Viro   get rid of the si...
943
  	res = sock_sendmsg(sock, &msg);
8ae5e030f   Al Viro   net: switch socke...
944
945
  	*from = msg.msg_iter;
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947
948
949
950
  /*
   * Atomic setting of ioctl hooks to avoid race
   * with module unload.
   */
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
951
  static DEFINE_MUTEX(br_ioctl_mutex);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
952
  static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
953

881d966b4   Eric W. Biederman   [NET]: Make the d...
954
  void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
956
  	mutex_lock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
957
  	br_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
958
  	mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
960
  }
  EXPORT_SYMBOL(brioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
961
  static DEFINE_MUTEX(vlan_ioctl_mutex);
881d966b4   Eric W. Biederman   [NET]: Make the d...
962
  static int (*vlan_ioctl_hook) (struct net *, void __user *arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963

881d966b4   Eric W. Biederman   [NET]: Make the d...
964
  void vlan_ioctl_set(int (*hook) (struct net *, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
966
  	mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
967
  	vlan_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
968
  	mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969
970
  }
  EXPORT_SYMBOL(vlan_ioctl_set);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
971
  static DEFINE_MUTEX(dlci_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
972
  static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973

89bddce58   Stephen Hemminger   [NET] socket: cod...
974
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
976
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
978
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
981
  static long sock_do_ioctl(struct net *net, struct socket *sock,
63ff03ab7   Johannes Berg   Revert "socket: f...
982
  			  unsigned int cmd, unsigned long arg)
6b96018b2   Arnd Bergmann   compat: move sock...
983
984
985
986
987
988
989
990
991
992
  {
  	int err;
  	void __user *argp = (void __user *)arg;
  
  	err = sock->ops->ioctl(sock, cmd, arg);
  
  	/*
  	 * If this ioctl is unknown try to hand it down
  	 * to the NIC driver.
  	 */
36fd633ec   Al Viro   net: separate SIO...
993
994
  	if (err != -ENOIOCTLCMD)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
995

36fd633ec   Al Viro   net: separate SIO...
996
997
998
999
1000
1001
1002
1003
1004
  	if (cmd == SIOCGIFCONF) {
  		struct ifconf ifc;
  		if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
  			return -EFAULT;
  		rtnl_lock();
  		err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
  		rtnl_unlock();
  		if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
  			err = -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
1005
1006
1007
  	} else {
  		struct ifreq ifr;
  		bool need_copyout;
63ff03ab7   Johannes Berg   Revert "socket: f...
1008
  		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
1009
1010
1011
  			return -EFAULT;
  		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
  		if (!err && need_copyout)
63ff03ab7   Johannes Berg   Revert "socket: f...
1012
  			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
1013
  				return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
1014
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
1015
1016
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
1019
1020
  /*
   *	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.
   */
8a3c245c0   Pedro Tammela   net: add document...
1021
1022
1023
1024
1025
1026
  /**
   *	get_net_ns - increment the refcount of the network namespace
   *	@ns: common namespace (net)
   *
   *	Returns the net's common namespace.
   */
d8d211a2a   Kirill Tkhai   net: Make extern ...
1027
  struct ns_common *get_net_ns(struct ns_common *ns)
c62cce2ca   Andrey Vagin   net: add an ioctl...
1028
1029
1030
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
d8d211a2a   Kirill Tkhai   net: Make extern ...
1031
  EXPORT_SYMBOL_GPL(get_net_ns);
c62cce2ca   Andrey Vagin   net: add an ioctl...
1032

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
1035
  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  {
  	struct socket *sock;
881d966b4   Eric W. Biederman   [NET]: Make the d...
1036
  	struct sock *sk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
  	void __user *argp = (void __user *)arg;
  	int pid, err;
881d966b4   Eric W. Biederman   [NET]: Make the d...
1039
  	struct net *net;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040

b69aee04f   Eric Dumazet   [NET]: Use file->...
1041
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
1042
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
1043
  	net = sock_net(sk);
44c02a2c3   Al Viro   dev_ioctl(): move...
1044
1045
1046
1047
1048
1049
1050
1051
1052
  	if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) {
  		struct ifreq ifr;
  		bool need_copyout;
  		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
  			return -EFAULT;
  		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
  		if (!err && need_copyout)
  			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
  				return -EFAULT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1053
  	} else
3d23e349d   Johannes Berg   wext: refactor
1054
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
b1b0c2450   Al Viro   lift handling of ...
1056
  		err = wext_handle_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1057
  	} else
3d23e349d   Johannes Berg   wext: refactor
1058
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
1059
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
1062
1063
1064
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
393cc3f51   Jiri Slaby   fs/fcntl: f_setow...
1065
  			err = f_setown(sock->file, pid, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
1067
1068
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
1069
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
1070
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
1072
1073
1074
1075
1076
1077
1078
  			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: ...
1079
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1080
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
1081
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1082
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083
1084
1085
1086
1087
1088
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1089
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
1091
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1092
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1094
1095
1096
1097
1098
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1099
1100
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1102
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1103
  			break;
c62cce2ca   Andrey Vagin   net: add an ioctl...
1104
1105
1106
1107
1108
1109
1110
  		case SIOCGSKNS:
  			err = -EPERM;
  			if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
  				break;
  
  			err = open_related_ns(&net->ns, get_net_ns);
  			break;
0768e1707   Arnd Bergmann   net: socket: impl...
1111
1112
  		case SIOCGSTAMP_OLD:
  		case SIOCGSTAMPNS_OLD:
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
1113
1114
1115
1116
1117
  			if (!sock->ops->gettstamp) {
  				err = -ENOIOCTLCMD;
  				break;
  			}
  			err = sock->ops->gettstamp(sock, argp,
0768e1707   Arnd Bergmann   net: socket: impl...
1118
1119
  						   cmd == SIOCGSTAMP_OLD,
  						   !IS_ENABLED(CONFIG_64BIT));
60747828e   Gustavo A. R. Silva   net: socket: Fix ...
1120
  			break;
0768e1707   Arnd Bergmann   net: socket: impl...
1121
1122
1123
1124
1125
1126
1127
1128
1129
  		case SIOCGSTAMP_NEW:
  		case SIOCGSTAMPNS_NEW:
  			if (!sock->ops->gettstamp) {
  				err = -ENOIOCTLCMD;
  				break;
  			}
  			err = sock->ops->gettstamp(sock, argp,
  						   cmd == SIOCGSTAMP_NEW,
  						   false);
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
1130
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
  		default:
63ff03ab7   Johannes Berg   Revert "socket: f...
1132
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1134
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
1136
  	return err;
  }
8a3c245c0   Pedro Tammela   net: add document...
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
  /**
   *	sock_create_lite - creates a socket
   *	@family: protocol family (AF_INET, ...)
   *	@type: communication type (SOCK_STREAM, ...)
   *	@protocol: protocol (0, ...)
   *	@res: new socket
   *
   *	Creates a new socket and assigns it to @res, passing through LSM.
   *	The new socket initialization is not complete, see kernel_accept().
   *	Returns 0 or an error. On failure @res is set to %NULL.
   *	This function internally uses GFP_KERNEL.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1149
1150
1151
1152
  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...
1153

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1154
1155
1156
1157
1158
1159
1160
1161
1162
  	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
1163
  	sock->type = type;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1164
1165
1166
  	err = security_socket_post_create(sock, family, type, protocol, 1);
  	if (err)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167
1168
1169
  out:
  	*res = sock;
  	return err;
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1170
1171
1172
1173
  out_release:
  	sock_release(sock);
  	sock = NULL;
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1175
  EXPORT_SYMBOL(sock_create_lite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
1177
  
  /* No kernel lock held - perfect */
ade994f4f   Al Viro   net: annotate ->p...
1178
  static __poll_t sock_poll(struct file *file, poll_table *wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1179
  {
3cafb3763   Christoph Hellwig   net: refactor soc...
1180
  	struct socket *sock = file->private_data;
a331de3bf   Christoph Hellwig   net: remove sock_...
1181
  	__poll_t events = poll_requested_events(wait), flag = 0;
2d48d67fa   Eliezer Tamir   net: poll/select ...
1182

e88958e63   Christoph Hellwig   net: handle NULL ...
1183
1184
  	if (!sock->ops->poll)
  		return 0;
f641f13b9   Christoph Hellwig   net: remove sock_...
1185

a331de3bf   Christoph Hellwig   net: remove sock_...
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
  	if (sk_can_busy_loop(sock->sk)) {
  		/* poll once if requested by the syscall */
  		if (events & POLL_BUSY_LOOP)
  			sk_busy_loop(sock->sk, 1);
  
  		/* if this socket can poll_ll, tell the system call */
  		flag = POLL_BUSY_LOOP;
  	}
  
  	return sock->ops->poll(file, sock, wait) | flag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1196
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1197
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
1199
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200
1201
1202
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1203
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
  {
6d8c50dcb   Cong Wang   socket: close rac...
1205
  	__sock_release(SOCKET_I(inode), inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
  	return 0;
  }
  
  /*
   *	Update the socket async list
   *
   *	Fasync_list locking strategy.
   *
   *	1. fasync_list is modified only under process context socket lock
   *	   i.e. under semaphore.
   *	2. fasync_list is used under read_lock(&sk->sk_callback_lock)
989a29792   Eric Dumazet   fasync: RCU and f...
1217
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218
1219
1220
1221
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1222
1223
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
333f7909a   Al Viro   coallocate socket...
1224
  	struct socket_wq *wq = &sock->wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1225

989a29792   Eric Dumazet   fasync: RCU and f...
1226
  	if (sk == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1227
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228
1229
  
  	lock_sock(sk);
eaefd1105   Eric Dumazet   net: add __rcu an...
1230
  	fasync_helper(fd, filp, on, &wq->fasync_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231

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

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

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1242
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1244
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1246

89bddce58   Stephen Hemminger   [NET] socket: cod...
1247
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1248
  	case SOCK_WAKE_WAITD:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1249
  		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1250
1251
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1252
  	case SOCK_WAKE_SPACE:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1253
  		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
1255
  			break;
  		/* fall through */
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1256
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1257
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1258
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1260
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1261
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262
  	}
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1263

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
1265
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1266
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1267

8a3c245c0   Pedro Tammela   net: add document...
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
  /**
   *	__sock_create - creates a socket
   *	@net: net namespace
   *	@family: protocol family (AF_INET, ...)
   *	@type: communication type (SOCK_STREAM, ...)
   *	@protocol: protocol (0, ...)
   *	@res: new socket
   *	@kern: boolean for kernel space sockets
   *
   *	Creates a new socket and assigns it to @res, passing through LSM.
   *	Returns 0 or an error. On failure @res is set to %NULL. @kern must
   *	be set to true if the socket resides in kernel space.
   *	This function internally uses GFP_KERNEL.
   */
721db93a5   Pavel Emelyanov   net: Export __soc...
1282
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1283
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
1285
1286
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1287
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1288
1289
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1290
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
  	 */
  	if (family < 0 || family >= NPROTO)
  		return -EAFNOSUPPORT;
  	if (type < 0 || type >= SOCK_MAX)
  		return -EINVAL;
  
  	/* Compatibility.
  
  	   This uglymoron is moved from INET layer to here to avoid
  	   deadlock in module load.
  	 */
  	if (family == PF_INET && type == SOCK_PACKET) {
f3c986908   liping.zhang   net: socket: use ...
1303
1304
1305
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306
1307
1308
1309
1310
1311
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1312

55737fda0   Stephen Hemminger   [NET]: socket fam...
1313
1314
1315
1316
1317
1318
1319
  	/*
  	 *	Allocate the socket and allow the family to set things up. if
  	 *	the protocol is 0, the family is instructed to select an appropriate
  	 *	default.
  	 */
  	sock = sock_alloc();
  	if (!sock) {
e87cc4728   Joe Perches   net: Convert net_...
1320
1321
  		net_warn_ratelimited("socket: no more sockets
  ");
55737fda0   Stephen Hemminger   [NET]: socket fam...
1322
1323
1324
1325
1326
  		return -ENFILE;	/* Not exactly a match, but its the
  				   closest posix thing */
  	}
  
  	sock->type = type;
95a5afca4   Johannes Berg   net: Remove CONFI...
1327
  #ifdef CONFIG_MODULES
89bddce58   Stephen Hemminger   [NET] socket: cod...
1328
1329
1330
  	/* 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
1331
1332
1333
  	 * requested real, full-featured networking support upon configuration.
  	 * Otherwise module support will break!
  	 */
190683a9d   Eric Dumazet   net: net_families...
1334
  	if (rcu_access_pointer(net_families[family]) == NULL)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1335
  		request_module("net-pf-%d", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
  #endif
55737fda0   Stephen Hemminger   [NET]: socket fam...
1337
1338
1339
1340
1341
  	rcu_read_lock();
  	pf = rcu_dereference(net_families[family]);
  	err = -EAFNOSUPPORT;
  	if (!pf)
  		goto out_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1342
1343
1344
1345
1346
  
  	/*
  	 * 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...
1347
  	if (!try_module_get(pf->owner))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1348
  		goto out_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1349
1350
  	/* Now protected by module ref count */
  	rcu_read_unlock();
3f378b684   Eric Paris   net: pass kern to...
1351
  	err = pf->create(net, sock, protocol, kern);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1352
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  		goto out_module_put;
a79af59ef   Frank Filz   [NET]: Fix module...
1354

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355
1356
1357
1358
  	/*
  	 * 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...
1359
1360
  	if (!try_module_get(sock->ops->owner))
  		goto out_module_busy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1361
1362
1363
1364
  	/*
  	 * Now that we're done with the ->create function, the [loadable]
  	 * module can have its refcnt decremented
  	 */
55737fda0   Stephen Hemminger   [NET]: socket fam...
1365
  	module_put(pf->owner);
7420ed23a   Venkat Yekkirala   [NetLabel]: SELin...
1366
1367
  	err = security_socket_post_create(sock, family, type, protocol, kern);
  	if (err)
3b1855255   Herbert Xu   [NET]: Fix unbala...
1368
  		goto out_sock_release;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1369
  	*res = sock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370

55737fda0   Stephen Hemminger   [NET]: socket fam...
1371
1372
1373
1374
  	return 0;
  
  out_module_busy:
  	err = -EAFNOSUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375
  out_module_put:
55737fda0   Stephen Hemminger   [NET]: socket fam...
1376
1377
1378
  	sock->ops = NULL;
  	module_put(pf->owner);
  out_sock_release:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1379
  	sock_release(sock);
55737fda0   Stephen Hemminger   [NET]: socket fam...
1380
1381
1382
1383
1384
  	return err;
  
  out_release:
  	rcu_read_unlock();
  	goto out_sock_release;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1385
  }
721db93a5   Pavel Emelyanov   net: Export __soc...
1386
  EXPORT_SYMBOL(__sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1387

8a3c245c0   Pedro Tammela   net: add document...
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
  /**
   *	sock_create - creates a socket
   *	@family: protocol family (AF_INET, ...)
   *	@type: communication type (SOCK_STREAM, ...)
   *	@protocol: protocol (0, ...)
   *	@res: new socket
   *
   *	A wrapper around __sock_create().
   *	Returns 0 or an error. This function internally uses GFP_KERNEL.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398
1399
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1400
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1402
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403

8a3c245c0   Pedro Tammela   net: add document...
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
  /**
   *	sock_create_kern - creates a socket (kernel space)
   *	@net: net namespace
   *	@family: protocol family (AF_INET, ...)
   *	@type: communication type (SOCK_STREAM, ...)
   *	@protocol: protocol (0, ...)
   *	@res: new socket
   *
   *	A wrapper around __sock_create().
   *	Returns 0 or an error. This function internally uses GFP_KERNEL.
   */
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1415
  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
  {
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1417
  	return __sock_create(net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1419
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1420

9d6a15c3f   Dominik Brodowski   net: socket: add ...
1421
  int __sys_socket(int family, int type, int protocol)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
1423
1424
  {
  	int retval;
  	struct socket *sock;
a677a039b   Ulrich Drepper   flag parameters: ...
1425
  	int flags;
e38b36f32   Ulrich Drepper   flag parameters: ...
1426
1427
1428
1429
1430
  	/* 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: ...
1431
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1432
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1433
1434
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435

aaca0bdca   Ulrich Drepper   flag parameters: ...
1436
1437
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1438
1439
  	retval = sock_create(family, type, protocol, &sock);
  	if (retval < 0)
8e1611e23   Al Viro   make sock_alloc_f...
1440
  		return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441

8e1611e23   Al Viro   make sock_alloc_f...
1442
  	return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443
  }
9d6a15c3f   Dominik Brodowski   net: socket: add ...
1444
1445
1446
1447
  SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
  {
  	return __sys_socket(family, type, protocol);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
1449
1450
  /*
   *	Create a pair of connected sockets.
   */
6debc8d83   Dominik Brodowski   net: socket: add ...
1451
  int __sys_socketpair(int family, int type, int protocol, int __user *usockvec)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
1454
  {
  	struct socket *sock1, *sock2;
  	int fd1, fd2, err;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1455
  	struct file *newfile1, *newfile2;
a677a039b   Ulrich Drepper   flag parameters: ...
1456
1457
1458
  	int flags;
  
  	flags = type & ~SOCK_TYPE_MASK;
77d272005   Ulrich Drepper   flag parameters: ...
1459
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
a677a039b   Ulrich Drepper   flag parameters: ...
1460
1461
  		return -EINVAL;
  	type &= SOCK_TYPE_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1462

aaca0bdca   Ulrich Drepper   flag parameters: ...
1463
1464
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1465
  	/*
016a266bd   Al Viro   socketpair(): all...
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
  	 * reserve descriptors and make sure we won't fail
  	 * to return them to userland.
  	 */
  	fd1 = get_unused_fd_flags(flags);
  	if (unlikely(fd1 < 0))
  		return fd1;
  
  	fd2 = get_unused_fd_flags(flags);
  	if (unlikely(fd2 < 0)) {
  		put_unused_fd(fd1);
  		return fd2;
  	}
  
  	err = put_user(fd1, &usockvec[0]);
  	if (err)
  		goto out;
  
  	err = put_user(fd2, &usockvec[1]);
  	if (err)
  		goto out;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
1489
1490
1491
1492
  	 * Obtain the first socket and check if the underlying protocol
  	 * supports the socketpair call.
  	 */
  
  	err = sock_create(family, type, protocol, &sock1);
016a266bd   Al Viro   socketpair(): all...
1493
  	if (unlikely(err < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1494
1495
1496
  		goto out;
  
  	err = sock_create(family, type, protocol, &sock2);
016a266bd   Al Viro   socketpair(): all...
1497
1498
1499
  	if (unlikely(err < 0)) {
  		sock_release(sock1);
  		goto out;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1500
  	}
d73aa2867   Yann Droneaud   net: handle error...
1501

d47cd9450   David Herrmann   net: hook socketp...
1502
1503
1504
1505
1506
1507
  	err = security_socket_socketpair(sock1, sock2);
  	if (unlikely(err)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
  	}
016a266bd   Al Viro   socketpair(): all...
1508
1509
1510
1511
1512
  	err = sock1->ops->socketpair(sock1, sock2);
  	if (unlikely(err < 0)) {
  		sock_release(sock2);
  		sock_release(sock1);
  		goto out;
284076305   Al Viro   take descriptor h...
1513
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1514
  	newfile1 = sock_alloc_file(sock1, flags, NULL);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1515
  	if (IS_ERR(newfile1)) {
284076305   Al Viro   take descriptor h...
1516
  		err = PTR_ERR(newfile1);
016a266bd   Al Viro   socketpair(): all...
1517
1518
  		sock_release(sock2);
  		goto out;
284076305   Al Viro   take descriptor h...
1519
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1520
  	newfile2 = sock_alloc_file(sock2, flags, NULL);
284076305   Al Viro   take descriptor h...
1521
1522
  	if (IS_ERR(newfile2)) {
  		err = PTR_ERR(newfile2);
016a266bd   Al Viro   socketpair(): all...
1523
1524
  		fput(newfile1);
  		goto out;
db3495099   Al Viro   [PATCH] AUDIT_FD_...
1525
  	}
157cf649a   Al Viro   sanitize audit_fd...
1526
  	audit_fd_pair(fd1, fd2);
d73aa2867   Yann Droneaud   net: handle error...
1527

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

016a266bd   Al Viro   socketpair(): all...
1532
  out:
d73aa2867   Yann Droneaud   net: handle error...
1533
  	put_unused_fd(fd2);
d73aa2867   Yann Droneaud   net: handle error...
1534
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
1536
  	return err;
  }
6debc8d83   Dominik Brodowski   net: socket: add ...
1537
1538
1539
1540
1541
  SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
  		int __user *, usockvec)
  {
  	return __sys_socketpair(family, type, protocol, usockvec);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1542
1543
1544
1545
1546
1547
1548
  /*
   *	Bind a name to a socket. Nothing much to do here since it's
   *	the protocol's responsibility to handle the local address.
   *
   *	We move the socket address to kernel space before we call
   *	the protocol layer (having also checked the address is ok).
   */
a87d35d87   Dominik Brodowski   net: socket: add ...
1549
  int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1550
1551
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1552
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1553
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554

89bddce58   Stephen Hemminger   [NET] socket: cod...
1555
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1556
  	if (sock) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1557
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
068b88cc1   Jakub Sitnicki   socket: Tighten n...
1558
  		if (!err) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1559
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1560
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1561
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1562
1563
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1564
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1565
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1567
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1568
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
  	return err;
  }
a87d35d87   Dominik Brodowski   net: socket: add ...
1571
1572
1573
1574
  SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
  {
  	return __sys_bind(fd, umyaddr, addrlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
1576
1577
1578
1579
  /*
   *	Perform a listen. Basically, we allow the protocol to do anything
   *	necessary for a listen, and if that works, we mark the socket as
   *	ready for listening.
   */
25e290eed   Dominik Brodowski   net: socket: add ...
1580
  int __sys_listen(int fd, int backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1581
1582
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1583
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1584
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1585
1586
1587
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1588
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1589
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1590
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591
1592
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1593
1594
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1596
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1597
1598
1599
  	}
  	return err;
  }
25e290eed   Dominik Brodowski   net: socket: add ...
1600
1601
1602
1603
  SYSCALL_DEFINE2(listen, int, fd, int, backlog)
  {
  	return __sys_listen(fd, backlog);
  }
de2ea4b64   Jens Axboe   net: add __sys_ac...
1604
1605
1606
  int __sys_accept4_file(struct file *file, unsigned file_flags,
  		       struct sockaddr __user *upeer_sockaddr,
  		       int __user *upeer_addrlen, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
  {
  	struct socket *sock, *newsock;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1609
  	struct file *newfile;
de2ea4b64   Jens Axboe   net: add __sys_ac...
1610
  	int err, len, newfd;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1611
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612

77d272005   Ulrich Drepper   flag parameters: ...
1613
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1614
1615
1616
1617
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
de2ea4b64   Jens Axboe   net: add __sys_ac...
1618
  	sock = sock_from_file(file, &err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1619
1620
1621
1622
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1623
1624
  	newsock = sock_alloc();
  	if (!newsock)
de2ea4b64   Jens Axboe   net: add __sys_ac...
1625
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1626
1627
1628
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1629
1630
1631
1632
1633
  	/*
  	 * We don't need try_module_get here, as the listening socket (sock)
  	 * has the protocol module (sock->ops->owner) held.
  	 */
  	__module_get(newsock->ops->owner);
284076305   Al Viro   take descriptor h...
1634
  	newfd = get_unused_fd_flags(flags);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1635
1636
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1637
  		sock_release(newsock);
de2ea4b64   Jens Axboe   net: add __sys_ac...
1638
  		goto out;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1639
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1640
  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1641
  	if (IS_ERR(newfile)) {
284076305   Al Viro   take descriptor h...
1642
1643
  		err = PTR_ERR(newfile);
  		put_unused_fd(newfd);
de2ea4b64   Jens Axboe   net: add __sys_ac...
1644
  		goto out;
284076305   Al Viro   take descriptor h...
1645
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
1646

a79af59ef   Frank Filz   [NET]: Fix module...
1647
1648
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1649
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1650

de2ea4b64   Jens Axboe   net: add __sys_ac...
1651
1652
  	err = sock->ops->accept(sock, newsock, sock->file->f_flags | file_flags,
  					false);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1653
  	if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1654
  		goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1655
1656
  
  	if (upeer_sockaddr) {
9b2c45d47   Denys Vlasenko   net: make getname...
1657
1658
1659
  		len = newsock->ops->getname(newsock,
  					(struct sockaddr *)&address, 2);
  		if (len < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1660
  			err = -ECONNABORTED;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1661
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
  		}
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1663
  		err = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1664
  					len, upeer_sockaddr, upeer_addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665
  		if (err < 0)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1666
  			goto out_fd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
1668
1669
  	}
  
  	/* File flags are not inherited via accept() unlike another OSes. */
39d8c1b6f   David S. Miller   [NET]: Do not los...
1670
1671
  	fd_install(newfd, newfile);
  	err = newfd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
1673
  out:
  	return err;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1674
  out_fd:
9606a2163   David S. Miller   [NET]: Fix dentry...
1675
  	fput(newfile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1676
  	put_unused_fd(newfd);
de2ea4b64   Jens Axboe   net: add __sys_ac...
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
  	goto out;
  
  }
  
  /*
   *	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 restructure accept also.
   */
  
  int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
  		  int __user *upeer_addrlen, int flags)
  {
  	int ret = -EBADF;
  	struct fd f;
  
  	f = fdget(fd);
  	if (f.file) {
  		ret = __sys_accept4_file(f.file, 0, upeer_sockaddr,
  						upeer_addrlen, flags);
  		if (f.flags)
  			fput(f.file);
  	}
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1708
  }
4541e8056   Dominik Brodowski   net: socket: add ...
1709
1710
1711
1712
1713
  SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen, int, flags)
  {
  	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags);
  }
20f37034f   Heiko Carstens   [CVE-2009-0029] S...
1714
1715
  SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr,
  		int __user *, upeer_addrlen)
aaca0bdca   Ulrich Drepper   flag parameters: ...
1716
  {
4541e8056   Dominik Brodowski   net: socket: add ...
1717
  	return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0);
aaca0bdca   Ulrich Drepper   flag parameters: ...
1718
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
  /*
   *	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.
   */
f499a021e   Jens Axboe   io_uring: ensure ...
1730
  int __sys_connect_file(struct file *file, struct sockaddr_storage *address,
bd3ded314   Jens Axboe   net: add __sys_co...
1731
  		       int addrlen, int file_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
1733
  {
  	struct socket *sock;
bd3ded314   Jens Axboe   net: add __sys_co...
1734
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1735

bd3ded314   Jens Axboe   net: add __sys_co...
1736
  	sock = sock_from_file(file, &err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
1738
  	if (!sock)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1739

89bddce58   Stephen Hemminger   [NET] socket: cod...
1740
  	err =
f499a021e   Jens Axboe   io_uring: ensure ...
1741
  	    security_socket_connect(sock, (struct sockaddr *)address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1742
  	if (err)
bd3ded314   Jens Axboe   net: add __sys_co...
1743
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1744

f499a021e   Jens Axboe   io_uring: ensure ...
1745
  	err = sock->ops->connect(sock, (struct sockaddr *)address, addrlen,
bd3ded314   Jens Axboe   net: add __sys_co...
1746
  				 sock->file->f_flags | file_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1747
1748
1749
  out:
  	return err;
  }
bd3ded314   Jens Axboe   net: add __sys_co...
1750
1751
1752
1753
1754
1755
1756
  int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen)
  {
  	int ret = -EBADF;
  	struct fd f;
  
  	f = fdget(fd);
  	if (f.file) {
f499a021e   Jens Axboe   io_uring: ensure ...
1757
1758
1759
1760
1761
  		struct sockaddr_storage address;
  
  		ret = move_addr_to_kernel(uservaddr, addrlen, &address);
  		if (!ret)
  			ret = __sys_connect_file(f.file, &address, addrlen, 0);
bd3ded314   Jens Axboe   net: add __sys_co...
1762
1763
1764
1765
1766
1767
  		if (f.flags)
  			fput(f.file);
  	}
  
  	return ret;
  }
1387c2c2f   Dominik Brodowski   net: socket: add ...
1768
1769
1770
1771
1772
  SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr,
  		int, addrlen)
  {
  	return __sys_connect(fd, uservaddr, addrlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1773
1774
1775
1776
  /*
   *	Get the local address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
8882a107b   Dominik Brodowski   net: socket: add ...
1777
1778
  int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1779
1780
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1781
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1782
  	int err, fput_needed;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1783

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1784
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1785
1786
1787
1788
1789
1790
  	if (!sock)
  		goto out;
  
  	err = security_socket_getsockname(sock);
  	if (err)
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1791
1792
  	err = sock->ops->getname(sock, (struct sockaddr *)&address, 0);
  	if (err < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
  		goto out_put;
9b2c45d47   Denys Vlasenko   net: make getname...
1794
1795
          /* "err" is actually length in this case */
  	err = move_addr_to_user(&address, err, usockaddr, usockaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
  
  out_put:
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1798
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1799
1800
1801
  out:
  	return err;
  }
8882a107b   Dominik Brodowski   net: socket: add ...
1802
1803
1804
1805
1806
  SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
  {
  	return __sys_getsockname(fd, usockaddr, usockaddr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1807
1808
1809
1810
  /*
   *	Get the remote address ('name') of a socket object. Move the obtained
   *	name to user space.
   */
b21c8f838   Dominik Brodowski   net: socket: add ...
1811
1812
  int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
  		      int __user *usockaddr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1813
1814
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1815
  	struct sockaddr_storage address;
9b2c45d47   Denys Vlasenko   net: make getname...
1816
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1817

89bddce58   Stephen Hemminger   [NET] socket: cod...
1818
1819
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1820
1821
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1822
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1823
1824
  			return err;
  		}
9b2c45d47   Denys Vlasenko   net: make getname...
1825
1826
1827
1828
  		err = sock->ops->getname(sock, (struct sockaddr *)&address, 1);
  		if (err >= 0)
  			/* "err" is actually length in this case */
  			err = move_addr_to_user(&address, err, usockaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1829
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1830
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1831
1832
1833
  	}
  	return err;
  }
b21c8f838   Dominik Brodowski   net: socket: add ...
1834
1835
1836
1837
1838
  SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
  		int __user *, usockaddr_len)
  {
  	return __sys_getpeername(fd, usockaddr, usockaddr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
1840
1841
1842
1843
  /*
   *	Send a datagram to a given address. We move the address into kernel
   *	space and check the user space data area is readable before invoking
   *	the protocol.
   */
211b634b7   Dominik Brodowski   net: socket: add ...
1844
1845
  int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags,
  		 struct sockaddr __user *addr,  int addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1846
1847
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1848
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1849
1850
1851
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1852
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1853

602bd0e90   Al Viro   net: switch sendt...
1854
1855
1856
  	err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1857
1858
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
4387ff75f   David S. Miller   [NET]: Fix net/so...
1859
  		goto out;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1860

89bddce58   Stephen Hemminger   [NET] socket: cod...
1861
  	msg.msg_name = NULL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1862
1863
1864
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
  	msg.msg_namelen = 0;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1865
  	if (addr) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1866
  		err = move_addr_to_kernel(addr, addr_len, &address);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1867
1868
  		if (err < 0)
  			goto out_put;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1869
  		msg.msg_name = (struct sockaddr *)&address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1870
  		msg.msg_namelen = addr_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
1872
1873
1874
  	}
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
  	msg.msg_flags = flags;
d8725c86a   Al Viro   get rid of the si...
1875
  	err = sock_sendmsg(sock, &msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1876

89bddce58   Stephen Hemminger   [NET] socket: cod...
1877
  out_put:
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1878
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1879
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1880
1881
  	return err;
  }
211b634b7   Dominik Brodowski   net: socket: add ...
1882
1883
1884
1885
1886
1887
  SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
  		unsigned int, flags, struct sockaddr __user *, addr,
  		int, addr_len)
  {
  	return __sys_sendto(fd, buff, len, flags, addr, addr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1888
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1889
   *	Send a datagram down a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
1891
  SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len,
95c961747   Eric Dumazet   net: cleanup unsi...
1892
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1893
  {
211b634b7   Dominik Brodowski   net: socket: add ...
1894
  	return __sys_sendto(fd, buff, len, flags, NULL, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
1896
1897
  }
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1898
   *	Receive a frame from the socket and optionally record the address of the
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1899
1900
1901
   *	sender. We verify the buffers are writable and if needed move the
   *	sender address from kernel to user space.
   */
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1902
1903
  int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags,
  		   struct sockaddr __user *addr, int __user *addr_len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1904
1905
1906
1907
  {
  	struct socket *sock;
  	struct iovec iov;
  	struct msghdr msg;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1908
  	struct sockaddr_storage address;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1909
  	int err, err2;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1910
  	int fput_needed;
602bd0e90   Al Viro   net: switch sendt...
1911
1912
1913
  	err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
  	if (unlikely(err))
  		return err;
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1914
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1915
  	if (!sock)
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1916
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1917

89bddce58   Stephen Hemminger   [NET] socket: cod...
1918
1919
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1920
1921
1922
1923
  	/* Save some cycles and don't copy the address if not needed */
  	msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg.msg_namelen = 0;
130ed5d10   tadeusz.struk@intel.com   net: fix uninitia...
1924
  	msg.msg_iocb = NULL;
9f138fa60   Alexander Potapenko   net: initialize m...
1925
  	msg.msg_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1926
1927
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1928
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1929

89bddce58   Stephen Hemminger   [NET] socket: cod...
1930
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1931
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1932
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1933
1934
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1935
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1936
1937
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1938
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1939
1940
  	return err;
  }
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1941
1942
1943
1944
1945
1946
  SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags, struct sockaddr __user *, addr,
  		int __user *, addr_len)
  {
  	return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1948
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1949
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1950
1951
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1952
  {
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1953
  	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1954
1955
1956
1957
1958
1959
  }
  
  /*
   *	Set a socket option. Because we don't know the option lengths we have
   *	to pass the user mode parameter for the protocols to sort out.
   */
cc36dca0d   Dominik Brodowski   net: socket: add ...
1960
1961
  static int __sys_setsockopt(int fd, int level, int optname,
  			    char __user *optval, int optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1962
  {
0d01da6af   Stanislav Fomichev   bpf: implement ge...
1963
1964
  	mm_segment_t oldfs = get_fs();
  	char *kernel_optval = NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1965
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
1968
1969
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1970
1971
1972
1973
  
  	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...
1974
1975
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1976

0d01da6af   Stanislav Fomichev   bpf: implement ge...
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
  		err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level,
  						     &optname, optval, &optlen,
  						     &kernel_optval);
  
  		if (err < 0) {
  			goto out_put;
  		} else if (err > 0) {
  			err = 0;
  			goto out_put;
  		}
  
  		if (kernel_optval) {
  			set_fs(KERNEL_DS);
  			optval = (char __user __force *)kernel_optval;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1992
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
1993
1994
1995
  			err =
  			    sock_setsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1996
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
1997
1998
1999
  			err =
  			    sock->ops->setsockopt(sock, level, optname, optval,
  						  optlen);
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2000
2001
2002
2003
2004
  
  		if (kernel_optval) {
  			set_fs(oldfs);
  			kfree(kernel_optval);
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2005
2006
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2007
2008
2009
  	}
  	return err;
  }
cc36dca0d   Dominik Brodowski   net: socket: add ...
2010
2011
2012
2013
2014
  SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int, optlen)
  {
  	return __sys_setsockopt(fd, level, optname, optval, optlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2015
2016
2017
2018
  /*
   *	Get a socket option. Because we don't know the option lengths we have
   *	to pass a user mode parameter for the protocols to sort out.
   */
13a2d70e2   Dominik Brodowski   net: socket: add ...
2019
2020
  static int __sys_getsockopt(int fd, int level, int optname,
  			    char __user *optval, int __user *optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2021
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2022
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023
  	struct socket *sock;
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2024
  	int max_optlen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2025

89bddce58   Stephen Hemminger   [NET] socket: cod...
2026
2027
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2028
2029
2030
  		err = security_socket_getsockopt(sock, level, optname);
  		if (err)
  			goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2031

0d01da6af   Stanislav Fomichev   bpf: implement ge...
2032
  		max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2033
  		if (level == SOL_SOCKET)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2034
2035
2036
  			err =
  			    sock_getsockopt(sock, level, optname, optval,
  					    optlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2037
  		else
89bddce58   Stephen Hemminger   [NET] socket: cod...
2038
2039
2040
  			err =
  			    sock->ops->getsockopt(sock, level, optname, optval,
  						  optlen);
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2041
2042
2043
2044
  
  		err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
  						     optval, optlen,
  						     max_optlen, err);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2045
2046
  out_put:
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2047
2048
2049
  	}
  	return err;
  }
13a2d70e2   Dominik Brodowski   net: socket: add ...
2050
2051
2052
2053
2054
  SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname,
  		char __user *, optval, int __user *, optlen)
  {
  	return __sys_getsockopt(fd, level, optname, optval, optlen);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055
2056
2057
  /*
   *	Shutdown a socket.
   */
005a1aeac   Dominik Brodowski   net: socket: add ...
2058
  int __sys_shutdown(int fd, int how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2059
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2060
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2061
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2062
2063
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2064
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2065
2066
2067
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2068
2069
2070
  	}
  	return err;
  }
005a1aeac   Dominik Brodowski   net: socket: add ...
2071
2072
2073
2074
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
  {
  	return __sys_shutdown(fd, how);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2075
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2076
2077
2078
2079
2080
   * fields which are the same type (int / unsigned) on our platforms.
   */
  #define COMPAT_MSG(msg, member)	((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member)
  #define COMPAT_NAMELEN(msg)	COMPAT_MSG(msg, msg_namelen)
  #define COMPAT_FLAGS(msg)	COMPAT_MSG(msg, msg_flags)
c71d8ebe7   Tetsuo Handa   net: Fix security...
2081
2082
2083
2084
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
da1842849   Al Viro   net: switch impor...
2085
2086
2087
2088
  static int copy_msghdr_from_user(struct msghdr *kmsg,
  				 struct user_msghdr __user *umsg,
  				 struct sockaddr __user **save_addr,
  				 struct iovec **iov)
1661bf364   Dan Carpenter   net: heap overflo...
2089
  {
ffb07550c   Al Viro   copy_msghdr_from_...
2090
  	struct user_msghdr msg;
08adb7dab   Al Viro   fold verify_iovec...
2091
  	ssize_t err;
ffb07550c   Al Viro   copy_msghdr_from_...
2092
  	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
1661bf364   Dan Carpenter   net: heap overflo...
2093
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
2094

864d96642   Paolo Abeni   net/socket: fix t...
2095
  	kmsg->msg_control = (void __force *)msg.msg_control;
ffb07550c   Al Viro   copy_msghdr_from_...
2096
2097
2098
2099
2100
  	kmsg->msg_controllen = msg.msg_controllen;
  	kmsg->msg_flags = msg.msg_flags;
  
  	kmsg->msg_namelen = msg.msg_namelen;
  	if (!msg.msg_name)
6a2a2b3ae   Ani Sinha   net:socket: set m...
2101
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
2102
2103
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
2104
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
2105
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
2106
2107
  
  	if (save_addr)
ffb07550c   Al Viro   copy_msghdr_from_...
2108
  		*save_addr = msg.msg_name;
08adb7dab   Al Viro   fold verify_iovec...
2109

ffb07550c   Al Viro   copy_msghdr_from_...
2110
  	if (msg.msg_name && kmsg->msg_namelen) {
08adb7dab   Al Viro   fold verify_iovec...
2111
  		if (!save_addr) {
864d96642   Paolo Abeni   net/socket: fix t...
2112
2113
  			err = move_addr_to_kernel(msg.msg_name,
  						  kmsg->msg_namelen,
08adb7dab   Al Viro   fold verify_iovec...
2114
2115
2116
2117
2118
2119
2120
2121
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
ffb07550c   Al Viro   copy_msghdr_from_...
2122
  	if (msg.msg_iovlen > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
2123
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
2124
  	kmsg->msg_iocb = NULL;
87e5e6dab   Jens Axboe   uio: make import_...
2125
  	err = import_iovec(save_addr ? READ : WRITE,
ffb07550c   Al Viro   copy_msghdr_from_...
2126
  			    msg.msg_iov, msg.msg_iovlen,
da1842849   Al Viro   net: switch impor...
2127
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
87e5e6dab   Jens Axboe   uio: make import_...
2128
  	return err < 0 ? err : 0;
1661bf364   Dan Carpenter   net: heap overflo...
2129
  }
4257c8ca1   Jens Axboe   net: separate out...
2130
2131
2132
  static int ____sys_sendmsg(struct socket *sock, struct msghdr *msg_sys,
  			   unsigned int flags, struct used_address *used_address,
  			   unsigned int allowed_msghdr_flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2133
  {
b9d717a7b   Alex Williamson   [NET]: Make sure ...
2134
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
846cc1231   Amit Kushwaha   net: socket: pref...
2135
  				__aligned(sizeof(__kernel_size_t));
89bddce58   Stephen Hemminger   [NET] socket: cod...
2136
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2137
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
2138
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
2139
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2140

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2141
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2142
  	if (msg_sys->msg_controllen > INT_MAX)
4257c8ca1   Jens Axboe   net: separate out...
2143
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2144
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2145
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2146
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2147
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
2148
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2149
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2150
  		if (err)
4257c8ca1   Jens Axboe   net: separate out...
2151
  			goto out;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2152
2153
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2154
  	} else if (ctl_len) {
ac4340fc3   David S. Miller   net: Assert at bu...
2155
2156
  		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
  			     CMSG_ALIGN(sizeof(struct cmsghdr)));
89bddce58   Stephen Hemminger   [NET] socket: cod...
2157
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2158
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2159
  			if (ctl_buf == NULL)
4257c8ca1   Jens Axboe   net: separate out...
2160
  				goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2161
2162
2163
  		}
  		err = -EFAULT;
  		/*
228e548e6   Anton Blanchard   net: Add sendmmsg...
2164
  		 * Careful! Before this, msg_sys->msg_control contains a user pointer.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2165
2166
2167
  		 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
  		 * checking falls down on this.
  		 */
fb8621bb6   Namhyung Kim   net: remove addre...
2168
  		if (copy_from_user(ctl_buf,
228e548e6   Anton Blanchard   net: Add sendmmsg...
2169
  				   (void __user __force *)msg_sys->msg_control,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2170
  				   ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2171
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2172
  		msg_sys->msg_control = ctl_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2173
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2174
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2175
2176
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2177
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2178
2179
2180
2181
2182
2183
  	/*
  	 * If this is sendmmsg() and current destination address is same as
  	 * previously succeeded address, omit asking LSM's decision.
  	 * used_address->name_len is initialized to UINT_MAX so that the first
  	 * destination address never matches.
  	 */
bc909d9dd   Mathieu Desnoyers   sendmmsg/sendmsg:...
2184
2185
2186
  	if (used_address && msg_sys->msg_name &&
  	    used_address->name_len == msg_sys->msg_namelen &&
  	    !memcmp(&used_address->name, msg_sys->msg_name,
c71d8ebe7   Tetsuo Handa   net: Fix security...
2187
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
2188
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2189
2190
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
2191
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2192
2193
2194
2195
2196
2197
  	/*
  	 * If this is sendmmsg() and sending to current destination address was
  	 * successful, remember it.
  	 */
  	if (used_address && err >= 0) {
  		used_address->name_len = msg_sys->msg_namelen;
bc909d9dd   Mathieu Desnoyers   sendmmsg/sendmsg:...
2198
2199
2200
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2201
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2202
2203
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
2204
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2205
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
4257c8ca1   Jens Axboe   net: separate out...
2206
2207
2208
  out:
  	return err;
  }
03b1230ca   Jens Axboe   io_uring: ensure ...
2209
2210
2211
  int sendmsg_copy_msghdr(struct msghdr *msg,
  			struct user_msghdr __user *umsg, unsigned flags,
  			struct iovec **iov)
4257c8ca1   Jens Axboe   net: separate out...
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
  {
  	int err;
  
  	if (flags & MSG_CMSG_COMPAT) {
  		struct compat_msghdr __user *msg_compat;
  
  		msg_compat = (struct compat_msghdr __user *) umsg;
  		err = get_compat_msghdr(msg, msg_compat, NULL, iov);
  	} else {
  		err = copy_msghdr_from_user(msg, umsg, NULL, iov);
  	}
  	if (err < 0)
  		return err;
  
  	return 0;
  }
  
  static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
  			 struct msghdr *msg_sys, unsigned int flags,
  			 struct used_address *used_address,
  			 unsigned int allowed_msghdr_flags)
  {
  	struct sockaddr_storage address;
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
  	ssize_t err;
  
  	msg_sys->msg_name = &address;
  
  	err = sendmsg_copy_msghdr(msg_sys, msg, flags, &iov);
  	if (err < 0)
  		return err;
  
  	err = ____sys_sendmsg(sock, msg_sys, flags, used_address,
  				allowed_msghdr_flags);
da1842849   Al Viro   net: switch impor...
2246
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2247
2248
2249
2250
2251
2252
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
03b1230ca   Jens Axboe   io_uring: ensure ...
2253
  long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
0fa03c624   Jens Axboe   io_uring: add sup...
2254
2255
  			unsigned int flags)
  {
d69e07793   Jens Axboe   net: disallow anc...
2256
  	/* disallow ancillary data requests from this path */
03b1230ca   Jens Axboe   io_uring: ensure ...
2257
2258
  	if (msg->msg_control || msg->msg_controllen)
  		return -EINVAL;
d69e07793   Jens Axboe   net: disallow anc...
2259

03b1230ca   Jens Axboe   io_uring: ensure ...
2260
  	return ____sys_sendmsg(sock, msg, flags, NULL, 0);
0fa03c624   Jens Axboe   io_uring: add sup...
2261
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
2262

e1834a329   Dominik Brodowski   net: socket: move...
2263
2264
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2265
2266
2267
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2268
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2269
2270
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2271
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2272
2273
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2274
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2275

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2276
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2277
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
2279
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2280
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2281
  {
e1834a329   Dominik Brodowski   net: socket: move...
2282
  	return __sys_sendmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2283
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
2284
2285
2286
2287
2288
  /*
   *	Linux sendmmsg interface
   */
  
  int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
e1834a329   Dominik Brodowski   net: socket: move...
2289
  		   unsigned int flags, bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2290
2291
2292
2293
2294
2295
  {
  	int fput_needed, err, datagrams;
  	struct socket *sock;
  	struct mmsghdr __user *entry;
  	struct compat_mmsghdr __user *compat_entry;
  	struct msghdr msg_sys;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2296
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2297
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2298

e1834a329   Dominik Brodowski   net: socket: move...
2299
2300
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
98382f419   Anton Blanchard   net: Cap number o...
2301
2302
  	if (vlen > UIO_MAXIOV)
  		vlen = UIO_MAXIOV;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2303
2304
2305
2306
2307
2308
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2309
  	used_address.name_len = UINT_MAX;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2310
2311
  	entry = mmsg;
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2312
  	err = 0;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2313
  	flags |= MSG_BATCH;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2314
2315
  
  	while (datagrams < vlen) {
f092276d8   Tom Herbert   net: Add MSG_BATC...
2316
2317
  		if (datagrams == vlen - 1)
  			flags = oflags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2318
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2319
  			err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2320
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2321
2322
2323
2324
2325
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2326
  			err = ___sys_sendmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2327
  					     (struct user_msghdr __user *)entry,
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2328
  					     &msg_sys, flags, &used_address, MSG_EOR);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2329
2330
2331
2332
2333
2334
2335
2336
2337
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
  
  		if (err)
  			break;
  		++datagrams;
3023898b7   Soheil Hassas Yeganeh   sock: fix sendmms...
2338
2339
  		if (msg_data_left(&msg_sys))
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2340
  		cond_resched();
228e548e6   Anton Blanchard   net: Add sendmmsg...
2341
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2342
  	fput_light(sock->file, fput_needed);
728ffb86f   Anton Blanchard   net: sendmmsg sho...
2343
2344
  	/* We only return an error if no datagrams were able to be sent */
  	if (datagrams != 0)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2345
  		return datagrams;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2346
2347
2348
2349
2350
2351
  	return err;
  }
  
  SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2352
  	return __sys_sendmmsg(fd, mmsg, vlen, flags, true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2353
  }
03b1230ca   Jens Axboe   io_uring: ensure ...
2354
2355
2356
2357
  int recvmsg_copy_msghdr(struct msghdr *msg,
  			struct user_msghdr __user *umsg, unsigned flags,
  			struct sockaddr __user **uaddr,
  			struct iovec **iov)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2358
  {
08adb7dab   Al Viro   fold verify_iovec...
2359
  	ssize_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2360

4257c8ca1   Jens Axboe   net: separate out...
2361
2362
  	if (MSG_CMSG_COMPAT & flags) {
  		struct compat_msghdr __user *msg_compat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2363

4257c8ca1   Jens Axboe   net: separate out...
2364
2365
2366
2367
2368
  		msg_compat = (struct compat_msghdr __user *) umsg;
  		err = get_compat_msghdr(msg, msg_compat, uaddr, iov);
  	} else {
  		err = copy_msghdr_from_user(msg, umsg, uaddr, iov);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2369
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
2370
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2371

4257c8ca1   Jens Axboe   net: separate out...
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
  	return 0;
  }
  
  static int ____sys_recvmsg(struct socket *sock, struct msghdr *msg_sys,
  			   struct user_msghdr __user *msg,
  			   struct sockaddr __user *uaddr,
  			   unsigned int flags, int nosec)
  {
  	struct compat_msghdr __user *msg_compat =
  					(struct compat_msghdr __user *) msg;
  	int __user *uaddr_len = COMPAT_NAMELEN(msg);
  	struct sockaddr_storage addr;
  	unsigned long cmsg_ptr;
  	int len;
  	ssize_t err;
  
  	msg_sys->msg_name = &addr;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2389
2390
  	cmsg_ptr = (unsigned long)msg_sys->msg_control;
  	msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2391

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2392
2393
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2394
2395
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
1af66221a   Eric Dumazet   net: avoid an ind...
2396
2397
2398
2399
2400
  
  	if (unlikely(nosec))
  		err = sock_recvmsg_nosec(sock, msg_sys, flags);
  	else
  		err = sock_recvmsg(sock, msg_sys, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2401
  	if (err < 0)
4257c8ca1   Jens Axboe   net: separate out...
2402
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2403
2404
2405
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
2406
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2407
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2408
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2409
  		if (err < 0)
4257c8ca1   Jens Axboe   net: separate out...
2410
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2411
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2412
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
2413
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2414
  	if (err)
4257c8ca1   Jens Axboe   net: separate out...
2415
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2416
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2417
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2418
2419
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2420
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2421
2422
  				 &msg->msg_controllen);
  	if (err)
4257c8ca1   Jens Axboe   net: separate out...
2423
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2424
  	err = len;
4257c8ca1   Jens Axboe   net: separate out...
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
  out:
  	return err;
  }
  
  static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
  			 struct msghdr *msg_sys, unsigned int flags, int nosec)
  {
  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
  	/* user mode address pointers */
  	struct sockaddr __user *uaddr;
  	ssize_t err;
  
  	err = recvmsg_copy_msghdr(msg_sys, msg, flags, &uaddr, &iov);
  	if (err < 0)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2440

4257c8ca1   Jens Axboe   net: separate out...
2441
  	err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
da1842849   Al Viro   net: switch impor...
2442
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2443
2444
2445
2446
2447
2448
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
03b1230ca   Jens Axboe   io_uring: ensure ...
2449
2450
2451
  long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
  			struct user_msghdr __user *umsg,
  			struct sockaddr __user *uaddr, unsigned int flags)
aa1fa28fc   Jens Axboe   io_uring: add sup...
2452
  {
d69e07793   Jens Axboe   net: disallow anc...
2453
  	/* disallow ancillary data requests from this path */
03b1230ca   Jens Axboe   io_uring: ensure ...
2454
2455
  	if (msg->msg_control || msg->msg_controllen)
  		return -EINVAL;
aa1fa28fc   Jens Axboe   io_uring: add sup...
2456

03b1230ca   Jens Axboe   io_uring: ensure ...
2457
  	return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
aa1fa28fc   Jens Axboe   io_uring: add sup...
2458
  }
e1834a329   Dominik Brodowski   net: socket: move...
2459
2460
  long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2461
2462
2463
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2464
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2465
2466
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2467
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2468
2469
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2470
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2471

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2472
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2473
2474
2475
  out:
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2476
  SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2477
2478
  		unsigned int, flags)
  {
e1834a329   Dominik Brodowski   net: socket: move...
2479
  	return __sys_recvmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2480
  }
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2481
2482
2483
  /*
   *     Linux recvmmsg interface
   */
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2484
2485
2486
  static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,
  			  unsigned int vlen, unsigned int flags,
  			  struct timespec64 *timeout)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2487
2488
2489
2490
  {
  	int fput_needed, err, datagrams;
  	struct socket *sock;
  	struct mmsghdr __user *entry;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2491
  	struct compat_mmsghdr __user *compat_entry;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2492
  	struct msghdr msg_sys;
766b9f928   Deepa Dinamani   fs: poll/select/r...
2493
2494
  	struct timespec64 end_time;
  	struct timespec64 timeout64;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
  
  	if (timeout &&
  	    poll_select_set_timeout(&end_time, timeout->tv_sec,
  				    timeout->tv_nsec))
  		return -EINVAL;
  
  	datagrams = 0;
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (!sock)
  		return err;
7797dc414   Soheil Hassas Yeganeh   socket: skip chec...
2506
2507
2508
2509
2510
2511
  	if (likely(!(flags & MSG_ERRQUEUE))) {
  		err = sock_error(sock->sk);
  		if (err) {
  			datagrams = err;
  			goto out_put;
  		}
e623a9e9d   Maxime Jayat   net: socket: fix ...
2512
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2513
2514
  
  	entry = mmsg;
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2515
  	compat_entry = (struct compat_mmsghdr __user *)mmsg;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2516
2517
2518
2519
2520
  
  	while (datagrams < vlen) {
  		/*
  		 * No need to ask LSM for more than the first datagram.
  		 */
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2521
  		if (MSG_CMSG_COMPAT & flags) {
666547ff5   Al Viro   separate kernel- ...
2522
  			err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2523
2524
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2525
2526
2527
2528
2529
  			if (err < 0)
  				break;
  			err = __put_user(err, &compat_entry->msg_len);
  			++compat_entry;
  		} else {
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2530
  			err = ___sys_recvmsg(sock,
666547ff5   Al Viro   separate kernel- ...
2531
  					     (struct user_msghdr __user *)entry,
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2532
2533
  					     &msg_sys, flags & ~MSG_WAITFORONE,
  					     datagrams);
d7256d0eb   Jean-Mickael Guerin   net: compat_mmsgh...
2534
2535
2536
2537
2538
  			if (err < 0)
  				break;
  			err = put_user(err, &entry->msg_len);
  			++entry;
  		}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2539
2540
  		if (err)
  			break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2541
  		++datagrams;
71c5c1595   Brandon L Black   net: Add MSG_WAIT...
2542
2543
2544
  		/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
  		if (flags & MSG_WAITFORONE)
  			flags |= MSG_DONTWAIT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2545
  		if (timeout) {
766b9f928   Deepa Dinamani   fs: poll/select/r...
2546
  			ktime_get_ts64(&timeout64);
c2e6c8567   Arnd Bergmann   y2038: socket: Ch...
2547
  			*timeout = timespec64_sub(end_time, timeout64);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
  			if (timeout->tv_sec < 0) {
  				timeout->tv_sec = timeout->tv_nsec = 0;
  				break;
  			}
  
  			/* Timeout, return less than vlen datagrams */
  			if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
  				break;
  		}
  
  		/* Out of band data, return right away */
  		if (msg_sys.msg_flags & MSG_OOB)
  			break;
a78cb84c6   Eric Dumazet   net: add scheduli...
2561
  		cond_resched();
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2562
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2563
  	if (err == 0)
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2564
2565
2566
2567
2568
2569
  		goto out_put;
  
  	if (datagrams == 0) {
  		datagrams = err;
  		goto out_put;
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2570

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2571
2572
2573
2574
2575
  	/*
  	 * We may return less entries than requested (vlen) if the
  	 * sock is non block and there aren't enough datagrams...
  	 */
  	if (err != -EAGAIN) {
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2576
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2577
2578
2579
2580
  		 * ... or  if recvmsg returns an error after we
  		 * received some datagrams, where we record the
  		 * error to return on the next call or if the
  		 * app asks about it using getsockopt(SO_ERROR).
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2581
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2582
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2583
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2584
2585
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2586

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2587
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2588
  }
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2589
2590
2591
2592
  int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
  		   unsigned int vlen, unsigned int flags,
  		   struct __kernel_timespec __user *timeout,
  		   struct old_timespec32 __user *timeout32)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2593
2594
  {
  	int datagrams;
c2e6c8567   Arnd Bergmann   y2038: socket: Ch...
2595
  	struct timespec64 timeout_sys;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2596

e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2597
2598
  	if (timeout && get_timespec64(&timeout_sys, timeout))
  		return -EFAULT;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2599

e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2600
  	if (timeout32 && get_old_timespec32(&timeout_sys, timeout32))
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2601
  		return -EFAULT;
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2602
2603
2604
2605
  	if (!timeout && !timeout32)
  		return do_recvmmsg(fd, mmsg, vlen, flags, NULL);
  
  	datagrams = do_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2606

e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2607
2608
2609
2610
2611
2612
2613
  	if (datagrams <= 0)
  		return datagrams;
  
  	if (timeout && put_timespec64(&timeout_sys, timeout))
  		datagrams = -EFAULT;
  
  	if (timeout32 && put_old_timespec32(&timeout_sys, timeout32))
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2614
2615
2616
2617
  		datagrams = -EFAULT;
  
  	return datagrams;
  }
1255e2690   Dominik Brodowski   net: socket: add ...
2618
2619
  SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags,
c2e6c8567   Arnd Bergmann   y2038: socket: Ch...
2620
  		struct __kernel_timespec __user *, timeout)
1255e2690   Dominik Brodowski   net: socket: add ...
2621
  {
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  
  	return __sys_recvmmsg(fd, mmsg, vlen, flags, timeout, NULL);
  }
  
  #ifdef CONFIG_COMPAT_32BIT_TIME
  SYSCALL_DEFINE5(recvmmsg_time32, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags,
  		struct old_timespec32 __user *, timeout)
  {
  	if (flags & MSG_CMSG_COMPAT)
  		return -EINVAL;
  
  	return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL, timeout);
1255e2690   Dominik Brodowski   net: socket: add ...
2637
  }
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2638
  #endif
1255e2690   Dominik Brodowski   net: socket: add ...
2639

a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2640
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2641
2642
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
228e548e6   Anton Blanchard   net: Add sendmmsg...
2643
  static const unsigned char nargs[21] = {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2644
2645
2646
  	AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
  	AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
  	AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
228e548e6   Anton Blanchard   net: Add sendmmsg...
2647
  	AL(4), AL(5), AL(4)
89bddce58   Stephen Hemminger   [NET] socket: cod...
2648
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2649
2650
2651
  #undef AL
  
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2652
   *	System call vectors.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2653
2654
2655
   *
   *	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...
2656
   *  it is set by the callees.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2657
   */
3e0fa65f8   Heiko Carstens   [CVE-2009-0029] S...
2658
  SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2659
  {
2950fa9d3   Chen Gang   kernel: audit: be...
2660
  	unsigned long a[AUDITSC_ARGS];
89bddce58   Stephen Hemminger   [NET] socket: cod...
2661
  	unsigned long a0, a1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2662
  	int err;
47379052b   Arjan van de Ven   net: Add explicit...
2663
  	unsigned int len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2664

228e548e6   Anton Blanchard   net: Add sendmmsg...
2665
  	if (call < 1 || call > SYS_SENDMMSG)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2666
  		return -EINVAL;
c8e8cd579   Jeremy Cline   net: socket: fix ...
2667
  	call = array_index_nospec(call, SYS_SENDMMSG + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2668

47379052b   Arjan van de Ven   net: Add explicit...
2669
2670
2671
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2672
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2673
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2674
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2675

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
2680
2681
2682
2683
2684
  	a0 = a[0];
  	a1 = a[1];
  
  	switch (call) {
  	case SYS_SOCKET:
9d6a15c3f   Dominik Brodowski   net: socket: add ...
2685
  		err = __sys_socket(a0, a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2686
2687
  		break;
  	case SYS_BIND:
a87d35d87   Dominik Brodowski   net: socket: add ...
2688
  		err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2689
2690
  		break;
  	case SYS_CONNECT:
1387c2c2f   Dominik Brodowski   net: socket: add ...
2691
  		err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2692
2693
  		break;
  	case SYS_LISTEN:
25e290eed   Dominik Brodowski   net: socket: add ...
2694
  		err = __sys_listen(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2695
2696
  		break;
  	case SYS_ACCEPT:
4541e8056   Dominik Brodowski   net: socket: add ...
2697
2698
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2699
2700
2701
  		break;
  	case SYS_GETSOCKNAME:
  		err =
8882a107b   Dominik Brodowski   net: socket: add ...
2702
2703
  		    __sys_getsockname(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2704
2705
2706
  		break;
  	case SYS_GETPEERNAME:
  		err =
b21c8f838   Dominik Brodowski   net: socket: add ...
2707
2708
  		    __sys_getpeername(a0, (struct sockaddr __user *)a1,
  				      (int __user *)a[2]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2709
2710
  		break;
  	case SYS_SOCKETPAIR:
6debc8d83   Dominik Brodowski   net: socket: add ...
2711
  		err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2712
2713
  		break;
  	case SYS_SEND:
f3bf896b1   Dominik Brodowski   net: socket: repl...
2714
2715
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   NULL, 0);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2716
2717
  		break;
  	case SYS_SENDTO:
211b634b7   Dominik Brodowski   net: socket: add ...
2718
2719
  		err = __sys_sendto(a0, (void __user *)a1, a[2], a[3],
  				   (struct sockaddr __user *)a[4], a[5]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2720
2721
  		break;
  	case SYS_RECV:
d27e9afc6   Dominik Brodowski   net: socket: repl...
2722
2723
  		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				     NULL, NULL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2724
2725
  		break;
  	case SYS_RECVFROM:
7a09e1eb9   Dominik Brodowski   net: socket: add ...
2726
2727
2728
  		err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3],
  				     (struct sockaddr __user *)a[4],
  				     (int __user *)a[5]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2729
2730
  		break;
  	case SYS_SHUTDOWN:
005a1aeac   Dominik Brodowski   net: socket: add ...
2731
  		err = __sys_shutdown(a0, a1);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2732
2733
  		break;
  	case SYS_SETSOCKOPT:
cc36dca0d   Dominik Brodowski   net: socket: add ...
2734
2735
  		err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3],
  				       a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2736
2737
2738
  		break;
  	case SYS_GETSOCKOPT:
  		err =
13a2d70e2   Dominik Brodowski   net: socket: add ...
2739
2740
  		    __sys_getsockopt(a0, a1, a[2], (char __user *)a[3],
  				     (int __user *)a[4]);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2741
2742
  		break;
  	case SYS_SENDMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2743
2744
  		err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2745
  		break;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2746
  	case SYS_SENDMMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2747
2748
  		err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2],
  				     a[3], true);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2749
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2750
  	case SYS_RECVMSG:
e1834a329   Dominik Brodowski   net: socket: move...
2751
2752
  		err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1,
  				    a[2], true);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2753
  		break;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2754
  	case SYS_RECVMMSG:
3ca47e958   Arnd Bergmann   y2038: remove CON...
2755
  		if (IS_ENABLED(CONFIG_64BIT))
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2756
2757
2758
2759
2760
2761
2762
2763
  			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
  					     a[2], a[3],
  					     (struct __kernel_timespec __user *)a[4],
  					     NULL);
  		else
  			err = __sys_recvmmsg(a0, (struct mmsghdr __user *)a1,
  					     a[2], a[3], NULL,
  					     (struct old_timespec32 __user *)a[4]);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2764
  		break;
de11defeb   Ulrich Drepper   reintroduce accept4
2765
  	case SYS_ACCEPT4:
4541e8056   Dominik Brodowski   net: socket: add ...
2766
2767
  		err = __sys_accept4(a0, (struct sockaddr __user *)a1,
  				    (int __user *)a[2], a[3]);
aaca0bdca   Ulrich Drepper   flag parameters: ...
2768
  		break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2769
2770
2771
  	default:
  		err = -EINVAL;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2772
2773
2774
  	}
  	return err;
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2775
  #endif				/* __ARCH_WANT_SYS_SOCKETCALL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2776

55737fda0   Stephen Hemminger   [NET]: socket fam...
2777
2778
2779
2780
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2781
2782
   *	This function is called by a protocol handler that wants to
   *	advertise its address family, and have it linked into the
e793c0f70   Masanari Iida   net: treewide: Fi...
2783
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2784
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2785
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2786
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2787
2788
2789
2790
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2791
2792
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2793
2794
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2795
2796
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2797
2798
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2799
2800
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2801
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2802
2803
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2804
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2805
2806
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2807
2808
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2809
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2810

55737fda0   Stephen Hemminger   [NET]: socket fam...
2811
2812
2813
2814
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2815
2816
   *	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...
2817
2818
2819
2820
2821
2822
   *	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
2823
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2824
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2825
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2826
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2827

55737fda0   Stephen Hemminger   [NET]: socket fam...
2828
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2829
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2830
2831
2832
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2833
2834
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2835
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2836
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2837

bf2ae2e4b   Xin Long   sock_diag: reques...
2838
2839
  bool sock_is_registered(int family)
  {
66b51b0a0   Jeremy Cline   net: sock_diag: F...
2840
  	return family < NPROTO && rcu_access_pointer(net_families[family]);
bf2ae2e4b   Xin Long   sock_diag: reques...
2841
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2842
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2843
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2844
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2845
2846
2847
2848
2849
2850
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2851

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2852
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2853
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2854
2855
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2856
2857
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2858
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2859
2860
2861
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2862
2863
2864
2865
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
  		goto out_fs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2866
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2867
2868
2869
2870
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2871
2872
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2873
2874
2875
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2876
2877
2878
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2879
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2880

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

b3e19d924   Nick Piggin   fs: scale mntget/...
2883
2884
2885
2886
2887
2888
2889
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
  out_fs:
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2890
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2891
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2892
2893
2894
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
648845ab7   Tonghao Zhang   sock: Move the so...
2895
2896
2897
  	seq_printf(seq, "sockets: used %d
  ",
  		   sock_inuse_get(seq->private));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2898
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2899
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2900

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2901
  #ifdef CONFIG_COMPAT
36fd633ec   Al Viro   net: separate SIO...
2902
  static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2903
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2904
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2905
  	struct ifconf ifc;
7a229387d   Arnd Bergmann   net: copy socket ...
2906
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2907
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2908
  		return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
2909
2910
  	ifc.ifc_len = ifc32.ifc_len;
  	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
7a229387d   Arnd Bergmann   net: copy socket ...
2911

36fd633ec   Al Viro   net: separate SIO...
2912
2913
2914
  	rtnl_lock();
  	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
  	rtnl_unlock();
7a229387d   Arnd Bergmann   net: copy socket ...
2915
2916
  	if (err)
  		return err;
36fd633ec   Al Viro   net: separate SIO...
2917
  	ifc32.ifc_len = ifc.ifc_len;
6b96018b2   Arnd Bergmann   compat: move sock...
2918
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2919
2920
2921
2922
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2923
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2924
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2925
2926
  	struct compat_ethtool_rxnfc __user *compat_rxnfc;
  	bool convert_in = false, convert_out = false;
44c02a2c3   Al Viro   dev_ioctl(): move...
2927
2928
2929
  	size_t buf_size = 0;
  	struct ethtool_rxnfc __user *rxnfc = NULL;
  	struct ifreq ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2930
2931
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2932
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2933
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2934

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

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2938
2939
2940
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2941
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
  	/* Most ethtool structures are defined without padding.
  	 * Unfortunately struct ethtool_rxnfc is an exception.
  	 */
  	switch (ethcmd) {
  	default:
  		break;
  	case ETHTOOL_GRXCLSRLALL:
  		/* Buffer size is variable */
  		if (get_user(rule_cnt, &compat_rxnfc->rule_cnt))
  			return -EFAULT;
  		if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32))
  			return -ENOMEM;
  		buf_size += rule_cnt * sizeof(u32);
  		/* fall through */
  	case ETHTOOL_GRXRINGS:
  	case ETHTOOL_GRXCLSRLCNT:
  	case ETHTOOL_GRXCLSRULE:
55664f324   Ben Hutchings   ethtool: Allow dr...
2959
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2960
2961
2962
  		convert_out = true;
  		/* fall through */
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2963
2964
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
44c02a2c3   Al Viro   dev_ioctl(): move...
2965
  		rxnfc = compat_alloc_user_space(buf_size);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2966
2967
  		break;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2968
  	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2969
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2970
  	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
7a229387d   Arnd Bergmann   net: copy socket ...
2971

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2972
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2973
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2974
2975
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2976
2977
2978
2979
  		BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
  			     sizeof(compat_rxnfc->fs.m_ext) !=
  			     offsetof(struct ethtool_rxnfc, fs.m_ext) +
  			     sizeof(rxnfc->fs.m_ext));
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2980
2981
2982
2983
2984
2985
2986
  		BUILD_BUG_ON(
  			offsetof(struct compat_ethtool_rxnfc, fs.location) -
  			offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
  			offsetof(struct ethtool_rxnfc, fs.location) -
  			offsetof(struct ethtool_rxnfc, fs.ring_cookie));
  
  		if (copy_in_user(rxnfc, compat_rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
2987
2988
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2989
2990
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
2991
  				 (void __user *)(&rxnfc->fs.location + 1) -
b6168562c   Wenwen Wang   net: socket: fix ...
2992
2993
2994
2995
2996
2997
2998
2999
  				 (void __user *)&rxnfc->fs.ring_cookie))
  			return -EFAULT;
  		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
  			if (put_user(rule_cnt, &rxnfc->rule_cnt))
  				return -EFAULT;
  		} else if (copy_in_user(&rxnfc->rule_cnt,
  					&compat_rxnfc->rule_cnt,
  					sizeof(rxnfc->rule_cnt)))
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3000
3001
  			return -EFAULT;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
3002
  	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3003
3004
3005
3006
3007
  	if (ret)
  		return ret;
  
  	if (convert_out) {
  		if (copy_in_user(compat_rxnfc, rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
3008
3009
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3010
3011
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
3012
3013
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
  		    copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
  				 sizeof(rxnfc->rule_cnt)))
  			return -EFAULT;
  
  		if (ethcmd == ETHTOOL_GRXCLSRLALL) {
  			/* As an optimisation, we only copy the actual
  			 * number of rules that the underlying
  			 * function returned.  Since Mallory might
  			 * change the rule count in user memory, we
  			 * check that it is less than the rule count
  			 * originally given (as the user buffer size),
  			 * which has been range-checked.
  			 */
  			if (get_user(actual_rule_cnt, &rxnfc->rule_cnt))
  				return -EFAULT;
  			if (actual_rule_cnt < rule_cnt)
  				rule_cnt = actual_rule_cnt;
  			if (copy_in_user(&compat_rxnfc->rule_locs[0],
  					 &rxnfc->rule_locs[0],
  					 rule_cnt * sizeof(u32)))
  				return -EFAULT;
  		}
  	}
  
  	return 0;
7a229387d   Arnd Bergmann   net: copy socket ...
3039
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3040
3041
  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
  {
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3042
  	compat_uptr_t uptr32;
44c02a2c3   Al Viro   dev_ioctl(): move...
3043
3044
3045
  	struct ifreq ifr;
  	void __user *saved;
  	int err;
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3046

44c02a2c3   Al Viro   dev_ioctl(): move...
3047
  	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3048
3049
3050
3051
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3052
3053
  	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
  	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
7a229387d   Arnd Bergmann   net: copy socket ...
3054

44c02a2c3   Al Viro   dev_ioctl(): move...
3055
3056
3057
3058
3059
  	err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
  	if (!err) {
  		ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
  		if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
  			err = -EFAULT;
ccbd6a5a4   Joe Perches   net: Remove unnec...
3060
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
3061
  	return err;
7a229387d   Arnd Bergmann   net: copy socket ...
3062
  }
590d4693f   Ben Hutchings   net/compat: Merge...
3063
3064
  /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */
  static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
6b96018b2   Arnd Bergmann   compat: move sock...
3065
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
3066
  {
44c02a2c3   Al Viro   dev_ioctl(): move...
3067
  	struct ifreq ifreq;
7a229387d   Arnd Bergmann   net: copy socket ...
3068
  	u32 data32;
44c02a2c3   Al Viro   dev_ioctl(): move...
3069
  	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
3070
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3071
  	if (get_user(data32, &u_ifreq32->ifr_data))
7a229387d   Arnd Bergmann   net: copy socket ...
3072
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3073
  	ifreq.ifr_data = compat_ptr(data32);
7a229387d   Arnd Bergmann   net: copy socket ...
3074

44c02a2c3   Al Viro   dev_ioctl(): move...
3075
  	return dev_ioctl(net, cmd, &ifreq, NULL);
7a229387d   Arnd Bergmann   net: copy socket ...
3076
  }
37ac39bdd   Johannes Berg   Revert "kill dev_...
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
  static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
  			      unsigned int cmd,
  			      struct compat_ifreq __user *uifr32)
  {
  	struct ifreq __user *uifr;
  	int err;
  
  	/* Handle the fact that while struct ifreq has the same *layout* on
  	 * 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
  	 * which are handled elsewhere, it still has different *size* due to
  	 * ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
  	 * resulting in struct ifreq being 32 and 40 bytes respectively).
  	 * As a result, if the struct happens to be at the end of a page and
  	 * the next page isn't readable/writable, we get a fault. To prevent
  	 * that, copy back and forth to the full size.
  	 */
  
  	uifr = compat_alloc_user_space(sizeof(*uifr));
  	if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
  		return -EFAULT;
  
  	err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
  
  	if (!err) {
  		switch (cmd) {
  		case SIOCGIFFLAGS:
  		case SIOCGIFMETRIC:
  		case SIOCGIFMTU:
  		case SIOCGIFMEM:
  		case SIOCGIFHWADDR:
  		case SIOCGIFINDEX:
  		case SIOCGIFADDR:
  		case SIOCGIFBRDADDR:
  		case SIOCGIFDSTADDR:
  		case SIOCGIFNETMASK:
  		case SIOCGIFPFLAGS:
  		case SIOCGIFTXQLEN:
  		case SIOCGMIIPHY:
  		case SIOCGMIIREG:
c6c9fee35   Johannes Berg   net: socket: fix ...
3116
  		case SIOCGIFNAME:
37ac39bdd   Johannes Berg   Revert "kill dev_...
3117
3118
3119
3120
3121
3122
3123
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
3124
3125
3126
3127
3128
  static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
  			struct compat_ifreq __user *uifr32)
  {
  	struct ifreq ifr;
  	struct compat_ifmap __user *uifmap32;
a2116ed22   Arnd Bergmann   net/compat: fix d...
3129
3130
3131
3132
  	int err;
  
  	uifmap32 = &uifr32->ifr_ifru.ifru_map;
  	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3133
3134
3135
3136
3137
3138
  	err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
  	err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
  	err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
  	err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
  	err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
  	err |= get_user(ifr.ifr_map.port, &uifmap32->port);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3139
3140
  	if (err)
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3141
  	err = dev_ioctl(net, cmd, &ifr, NULL);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3142
3143
3144
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3145
3146
3147
3148
3149
3150
  		err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
  		err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
  		err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
  		err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
  		err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
  		err |= put_user(ifr.ifr_map.port, &uifmap32->port);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3151
3152
3153
3154
3155
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3156
  struct rtentry32 {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3157
  	u32		rt_pad1;
7a229387d   Arnd Bergmann   net: copy socket ...
3158
3159
3160
  	struct sockaddr rt_dst;         /* target address               */
  	struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
  	struct sockaddr rt_genmask;     /* target network mask (IP)     */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3161
3162
3163
3164
3165
3166
3167
  	unsigned short	rt_flags;
  	short		rt_pad2;
  	u32		rt_pad3;
  	unsigned char	rt_tos;
  	unsigned char	rt_class;
  	short		rt_pad4;
  	short		rt_metric;      /* +1 for binary compatibility! */
7a229387d   Arnd Bergmann   net: copy socket ...
3168
  	/* char * */ u32 rt_dev;        /* forcing the device at add    */
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3169
3170
  	u32		rt_mtu;         /* per route MTU/Window         */
  	u32		rt_window;      /* Window clamping              */
7a229387d   Arnd Bergmann   net: copy socket ...
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
  	unsigned short  rt_irtt;        /* Initial RTT                  */
  };
  
  struct in6_rtmsg32 {
  	struct in6_addr		rtmsg_dst;
  	struct in6_addr		rtmsg_src;
  	struct in6_addr		rtmsg_gateway;
  	u32			rtmsg_type;
  	u16			rtmsg_dst_len;
  	u16			rtmsg_src_len;
  	u32			rtmsg_metric;
  	u32			rtmsg_info;
  	u32			rtmsg_flags;
  	s32			rtmsg_ifindex;
  };
6b96018b2   Arnd Bergmann   compat: move sock...
3186
3187
  static int routing_ioctl(struct net *net, struct socket *sock,
  			 unsigned int cmd, void __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
3188
3189
3190
3191
3192
3193
3194
3195
  {
  	int ret;
  	void *r = NULL;
  	struct in6_rtmsg r6;
  	struct rtentry r4;
  	char devname[16];
  	u32 rtdev;
  	mm_segment_t old_fs = get_fs();
6b96018b2   Arnd Bergmann   compat: move sock...
3196
3197
  	if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
  		struct in6_rtmsg32 __user *ur6 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3198
  		ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
3199
  			3 * sizeof(struct in6_addr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3200
3201
3202
3203
3204
3205
3206
  		ret |= get_user(r6.rtmsg_type, &(ur6->rtmsg_type));
  		ret |= get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
  		ret |= get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
  		ret |= get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric));
  		ret |= get_user(r6.rtmsg_info, &(ur6->rtmsg_info));
  		ret |= get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags));
  		ret |= get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
7a229387d   Arnd Bergmann   net: copy socket ...
3207
3208
3209
  
  		r = (void *) &r6;
  	} else { /* ipv4 */
6b96018b2   Arnd Bergmann   compat: move sock...
3210
  		struct rtentry32 __user *ur4 = argp;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3211
  		ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst),
7a229387d   Arnd Bergmann   net: copy socket ...
3212
  					3 * sizeof(struct sockaddr));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3213
3214
3215
3216
3217
3218
  		ret |= get_user(r4.rt_flags, &(ur4->rt_flags));
  		ret |= get_user(r4.rt_metric, &(ur4->rt_metric));
  		ret |= get_user(r4.rt_mtu, &(ur4->rt_mtu));
  		ret |= get_user(r4.rt_window, &(ur4->rt_window));
  		ret |= get_user(r4.rt_irtt, &(ur4->rt_irtt));
  		ret |= get_user(rtdev, &(ur4->rt_dev));
7a229387d   Arnd Bergmann   net: copy socket ...
3219
  		if (rtdev) {
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3220
  			ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
c3f52ae6a   stephen hemminger   socket: suppress ...
3221
3222
  			r4.rt_dev = (char __user __force *)devname;
  			devname[15] = 0;
7a229387d   Arnd Bergmann   net: copy socket ...
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
  		} else
  			r4.rt_dev = NULL;
  
  		r = (void *) &r4;
  	}
  
  	if (ret) {
  		ret = -EFAULT;
  		goto out;
  	}
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3233
  	set_fs(KERNEL_DS);
63ff03ab7   Johannes Berg   Revert "socket: f...
3234
  	ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3235
  	set_fs(old_fs);
7a229387d   Arnd Bergmann   net: copy socket ...
3236
3237
  
  out:
7a229387d   Arnd Bergmann   net: copy socket ...
3238
3239
3240
3241
3242
  	return ret;
  }
  
  /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
   * for some operations; this forces use of the newer bridge-utils that
25985edce   Lucas De Marchi   Fix common misspe...
3243
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
3244
   */
6b96018b2   Arnd Bergmann   compat: move sock...
3245
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
3246
  {
6b96018b2   Arnd Bergmann   compat: move sock...
3247
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
3248

6b96018b2   Arnd Bergmann   compat: move sock...
3249
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
3250
3251
3252
3253
3254
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
3255
3256
3257
3258
3259
3260
  static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
  			 unsigned int cmd, unsigned long arg)
  {
  	void __user *argp = compat_ptr(arg);
  	struct sock *sk = sock->sk;
  	struct net *net = sock_net(sk);
7a229387d   Arnd Bergmann   net: copy socket ...
3261

6b96018b2   Arnd Bergmann   compat: move sock...
3262
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
3263
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3264
3265
3266
3267
3268
  
  	switch (cmd) {
  	case SIOCSIFBR:
  	case SIOCGIFBR:
  		return old_bridge_ioctl(argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3269
  	case SIOCGIFCONF:
36fd633ec   Al Viro   net: separate SIO...
3270
  		return compat_dev_ifconf(net, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3271
3272
  	case SIOCETHTOOL:
  		return ethtool_ioctl(net, argp);
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3273
3274
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3275
3276
3277
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3278
3279
3280
  	case SIOCADDRT:
  	case SIOCDELRT:
  		return routing_ioctl(net, sock, cmd, argp);
0768e1707   Arnd Bergmann   net: socket: impl...
3281
3282
  	case SIOCGSTAMP_OLD:
  	case SIOCGSTAMPNS_OLD:
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
3283
3284
  		if (!sock->ops->gettstamp)
  			return -ENOIOCTLCMD;
0768e1707   Arnd Bergmann   net: socket: impl...
3285
  		return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
3286
  					    !COMPAT_USE_64BIT_TIME);
590d4693f   Ben Hutchings   net/compat: Merge...
3287
3288
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
3289
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
3290
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
3291
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
  
  	case FIOSETOWN:
  	case SIOCSPGRP:
  	case FIOGETOWN:
  	case SIOCGPGRP:
  	case SIOCBRADDBR:
  	case SIOCBRDELBR:
  	case SIOCGIFVLAN:
  	case SIOCSIFVLAN:
  	case SIOCADDDLCI:
  	case SIOCDELDLCI:
c62cce2ca   Andrey Vagin   net: add an ioctl...
3303
  	case SIOCGSKNS:
0768e1707   Arnd Bergmann   net: socket: impl...
3304
3305
  	case SIOCGSTAMP_NEW:
  	case SIOCGSTAMPNS_NEW:
6b96018b2   Arnd Bergmann   compat: move sock...
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
  		return sock_ioctl(file, cmd, arg);
  
  	case SIOCGIFFLAGS:
  	case SIOCSIFFLAGS:
  	case SIOCGIFMETRIC:
  	case SIOCSIFMETRIC:
  	case SIOCGIFMTU:
  	case SIOCSIFMTU:
  	case SIOCGIFMEM:
  	case SIOCSIFMEM:
  	case SIOCGIFHWADDR:
  	case SIOCSIFHWADDR:
  	case SIOCADDMULTI:
  	case SIOCDELMULTI:
  	case SIOCGIFINDEX:
6b96018b2   Arnd Bergmann   compat: move sock...
3321
3322
3323
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
3324
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
  	case SIOCGIFBRDADDR:
  	case SIOCSIFBRDADDR:
  	case SIOCGIFDSTADDR:
  	case SIOCSIFDSTADDR:
  	case SIOCGIFNETMASK:
  	case SIOCSIFNETMASK:
  	case SIOCSIFPFLAGS:
  	case SIOCGIFPFLAGS:
  	case SIOCGIFTXQLEN:
  	case SIOCSIFTXQLEN:
  	case SIOCBRADDIF:
  	case SIOCBRDELIF:
c6c9fee35   Johannes Berg   net: socket: fix ...
3337
  	case SIOCGIFNAME:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3338
3339
3340
3341
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
f92d4fc95   Al Viro   kill bond_ioctl()
3342
3343
3344
3345
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
37ac39bdd   Johannes Berg   Revert "kill dev_...
3346
  		return compat_ifreq_ioctl(net, sock, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3347
3348
3349
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
c7dc504e2   Arnd Bergmann   compat_ioctl: mov...
3350
  	case SIOCOUTQ:
9d7bf41fa   Arnd Bergmann   compat_ioctl: han...
3351
  	case SIOCOUTQNSD:
6b96018b2   Arnd Bergmann   compat: move sock...
3352
  	case SIOCATMARK:
63ff03ab7   Johannes Berg   Revert "socket: f...
3353
  		return sock_do_ioctl(net, sock, cmd, arg);
9177efd39   Arnd Bergmann   net, compat_ioctl...
3354
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
3355
3356
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3357

95c961747   Eric Dumazet   net: cleanup unsi...
3358
  static long compat_sock_ioctl(struct file *file, unsigned int cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
3359
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3360
3361
3362
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
3363
3364
3365
3366
3367
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3368
3369
3370
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
3371
3372
3373
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
3374
3375
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3376
3377
3378
  	return ret;
  }
  #endif
8a3c245c0   Pedro Tammela   net: add document...
3379
3380
3381
3382
3383
3384
3385
3386
  /**
   *	kernel_bind - bind an address to a socket (kernel space)
   *	@sock: socket
   *	@addr: address
   *	@addrlen: length of address
   *
   *	Returns 0 or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3387
3388
3389
3390
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3391
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3392

8a3c245c0   Pedro Tammela   net: add document...
3393
3394
3395
3396
3397
3398
3399
  /**
   *	kernel_listen - move socket to listening state (kernel space)
   *	@sock: socket
   *	@backlog: pending connections queue size
   *
   *	Returns 0 or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3400
3401
3402
3403
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3404
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3405

8a3c245c0   Pedro Tammela   net: add document...
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
  /**
   *	kernel_accept - accept a connection (kernel space)
   *	@sock: listening socket
   *	@newsock: new connected socket
   *	@flags: flags
   *
   *	@flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0.
   *	If it fails, @newsock is guaranteed to be %NULL.
   *	Returns 0 or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3416
3417
3418
3419
3420
3421
3422
3423
3424
  int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
  {
  	struct sock *sk = sock->sk;
  	int err;
  
  	err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
  			       newsock);
  	if (err < 0)
  		goto done;
cdfbabfb2   David Howells   net: Work around ...
3425
  	err = sock->ops->accept(sock, *newsock, flags, true);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3426
3427
  	if (err < 0) {
  		sock_release(*newsock);
fa8705b00   Tony Battersby   [NET]: sanitize k...
3428
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3429
3430
3431
3432
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
3433
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3434
3435
3436
3437
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3438
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3439

8a3c245c0   Pedro Tammela   net: add document...
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
  /**
   *	kernel_connect - connect a socket (kernel space)
   *	@sock: socket
   *	@addr: address
   *	@addrlen: address length
   *	@flags: flags (O_NONBLOCK, ...)
   *
   *	For datagram sockets, @addr is the addres to which datagrams are sent
   *	by default, and the only address from which datagrams are received.
   *	For stream sockets, attempts to connect to @addr.
   *	Returns 0 or an error code.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3452
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
3453
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3454
3455
3456
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3457
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3458

8a3c245c0   Pedro Tammela   net: add document...
3459
3460
3461
3462
3463
3464
3465
3466
  /**
   *	kernel_getsockname - get the address which the socket is bound (kernel space)
   *	@sock: socket
   *	@addr: address holder
   *
   * 	Fills the @addr pointer with the address which the socket is bound.
   *	Returns 0 or an error code.
   */
9b2c45d47   Denys Vlasenko   net: make getname...
3467
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3468
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3469
  	return sock->ops->getname(sock, addr, 0);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3470
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3471
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3472

8a3c245c0   Pedro Tammela   net: add document...
3473
3474
3475
3476
3477
3478
3479
3480
  /**
   *	kernel_peername - get the address which the socket is connected (kernel space)
   *	@sock: socket
   *	@addr: address holder
   *
   * 	Fills the @addr pointer with the address which the socket is connected.
   *	Returns 0 or an error code.
   */
9b2c45d47   Denys Vlasenko   net: make getname...
3481
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3482
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3483
  	return sock->ops->getname(sock, addr, 1);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3484
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3485
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3486

8a3c245c0   Pedro Tammela   net: add document...
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
  /**
   *	kernel_getsockopt - get a socket option (kernel space)
   *	@sock: socket
   *	@level: API level (SOL_SOCKET, ...)
   *	@optname: option tag
   *	@optval: option value
   *	@optlen: option length
   *
   *	Assigns the option length to @optlen.
   *	Returns 0 or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3498
3499
3500
3501
  int kernel_getsockopt(struct socket *sock, int level, int optname,
  			char *optval, int *optlen)
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3502
3503
  	char __user *uoptval;
  	int __user *uoptlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3504
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3505
3506
  	uoptval = (char __user __force *) optval;
  	uoptlen = (int __user __force *) optlen;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3507
3508
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3509
  		err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3510
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3511
3512
  		err = sock->ops->getsockopt(sock, level, optname, uoptval,
  					    uoptlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3513
3514
3515
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3516
  EXPORT_SYMBOL(kernel_getsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3517

8a3c245c0   Pedro Tammela   net: add document...
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
  /**
   *	kernel_setsockopt - set a socket option (kernel space)
   *	@sock: socket
   *	@level: API level (SOL_SOCKET, ...)
   *	@optname: option tag
   *	@optval: option value
   *	@optlen: option length
   *
   *	Returns 0 or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3528
  int kernel_setsockopt(struct socket *sock, int level, int optname,
b7058842c   David S. Miller   net: Make setsock...
3529
  			char *optval, unsigned int optlen)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3530
3531
  {
  	mm_segment_t oldfs = get_fs();
fb8621bb6   Namhyung Kim   net: remove addre...
3532
  	char __user *uoptval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3533
  	int err;
fb8621bb6   Namhyung Kim   net: remove addre...
3534
  	uoptval = (char __user __force *) optval;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3535
3536
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
fb8621bb6   Namhyung Kim   net: remove addre...
3537
  		err = sock_setsockopt(sock, level, optname, uoptval, optlen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3538
  	else
fb8621bb6   Namhyung Kim   net: remove addre...
3539
  		err = sock->ops->setsockopt(sock, level, optname, uoptval,
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3540
3541
3542
3543
  					    optlen);
  	set_fs(oldfs);
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3544
  EXPORT_SYMBOL(kernel_setsockopt);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3545

8a3c245c0   Pedro Tammela   net: add document...
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
  /**
   *	kernel_sendpage - send a &page through a socket (kernel space)
   *	@sock: socket
   *	@page: page
   *	@offset: page offset
   *	@size: total size in bytes
   *	@flags: flags (MSG_DONTWAIT, ...)
   *
   *	Returns the total amount sent in bytes or an error.
   */
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3556
3557
3558
3559
3560
3561
3562
3563
  int kernel_sendpage(struct socket *sock, struct page *page, int offset,
  		    size_t size, int flags)
  {
  	if (sock->ops->sendpage)
  		return sock->ops->sendpage(sock, page, offset, size, flags);
  
  	return sock_no_sendpage(sock, page, offset, size, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3564
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3565

8a3c245c0   Pedro Tammela   net: add document...
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
  /**
   *	kernel_sendpage_locked - send a &page through the locked sock (kernel space)
   *	@sk: sock
   *	@page: page
   *	@offset: page offset
   *	@size: total size in bytes
   *	@flags: flags (MSG_DONTWAIT, ...)
   *
   *	Returns the total amount sent in bytes or an error.
   *	Caller must hold @sk.
   */
306b13eb3   Tom Herbert   proto_ops: Add lo...
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
  int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,
  			   size_t size, int flags)
  {
  	struct socket *sock = sk->sk_socket;
  
  	if (sock->ops->sendpage_locked)
  		return sock->ops->sendpage_locked(sk, page, offset, size,
  						  flags);
  
  	return sock_no_sendpage_locked(sk, page, offset, size, flags);
  }
  EXPORT_SYMBOL(kernel_sendpage_locked);
8a3c245c0   Pedro Tammela   net: add document...
3589
3590
3591
3592
3593
3594
3595
  /**
   *	kernel_shutdown - shut down part of a full-duplex connection (kernel space)
   *	@sock: socket
   *	@how: connection part
   *
   *	Returns 0 or an error.
   */
91cf45f02   Trond Myklebust   [NET]: Add the he...
3596
3597
3598
3599
  int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)
  {
  	return sock->ops->shutdown(sock, how);
  }
91cf45f02   Trond Myklebust   [NET]: Add the he...
3600
  EXPORT_SYMBOL(kernel_sock_shutdown);
113c30759   R. Parameswaran   New kernel functi...
3601

8a3c245c0   Pedro Tammela   net: add document...
3602
3603
3604
3605
3606
3607
3608
3609
  /**
   *	kernel_sock_ip_overhead - returns the IP overhead imposed by a socket
   *	@sk: socket
   *
   *	This routine returns the IP overhead imposed by a socket i.e.
   *	the length of the underlying IP header, depending on whether
   *	this is an IPv4 or IPv6 socket and the length from IP options turned
   *	on at the socket. Assumes that the caller has a lock on the socket.
113c30759   R. Parameswaran   New kernel functi...
3610
   */
8a3c245c0   Pedro Tammela   net: add document...
3611

113c30759   R. Parameswaran   New kernel functi...
3612
3613
3614
3615
3616
  u32 kernel_sock_ip_overhead(struct sock *sk)
  {
  	struct inet_sock *inet;
  	struct ip_options_rcu *opt;
  	u32 overhead = 0;
113c30759   R. Parameswaran   New kernel functi...
3617
3618
3619
3620
3621
3622
3623
  #if IS_ENABLED(CONFIG_IPV6)
  	struct ipv6_pinfo *np;
  	struct ipv6_txoptions *optv6 = NULL;
  #endif /* IS_ENABLED(CONFIG_IPV6) */
  
  	if (!sk)
  		return overhead;
113c30759   R. Parameswaran   New kernel functi...
3624
3625
3626
3627
3628
  	switch (sk->sk_family) {
  	case AF_INET:
  		inet = inet_sk(sk);
  		overhead += sizeof(struct iphdr);
  		opt = rcu_dereference_protected(inet->inet_opt,
614d79c09   stephen hemminger   socket: fix set n...
3629
  						sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3630
3631
3632
3633
3634
3635
3636
3637
3638
  		if (opt)
  			overhead += opt->opt.optlen;
  		return overhead;
  #if IS_ENABLED(CONFIG_IPV6)
  	case AF_INET6:
  		np = inet6_sk(sk);
  		overhead += sizeof(struct ipv6hdr);
  		if (np)
  			optv6 = rcu_dereference_protected(np->opt,
614d79c09   stephen hemminger   socket: fix set n...
3639
  							  sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3640
3641
3642
3643
3644
3645
3646
3647
3648
  		if (optv6)
  			overhead += (optv6->opt_flen + optv6->opt_nflen);
  		return overhead;
  #endif /* IS_ENABLED(CONFIG_IPV6) */
  	default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */
  		return overhead;
  	}
  }
  EXPORT_SYMBOL(kernel_sock_ip_overhead);