Blame view

net/socket.c 91.7 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
  	if (f.file) {
  		sock = sock_from_file(f.file, err);
  		if (likely(sock)) {
ce787a5a0   Miaohe Lin   net: Set fput_nee...
478
  			*fput_needed = f.flags & FDPUT_FPUT;
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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
572
573
574
575
  	if (!sock->file) {
  		iput(SOCK_INODE(sock));
  		return;
  	}
89bddce58   Stephen Hemminger   [NET] socket: cod...
576
  	sock->file = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
  }
6d8c50dcb   Cong Wang   socket: close rac...
578

9a8ad9ac8   Andrew Lunn   net: socket: Move...
579
580
581
582
583
584
585
586
  /**
   *	sock_release - close a socket
   *	@sock: socket to close
   *
   *	The socket is released from the protocol stack if it has a release
   *	callback, and the inode is then released if the socket is bound to
   *	an inode not a file.
   */
6d8c50dcb   Cong Wang   socket: close rac...
587
588
589
590
  void sock_release(struct socket *sock)
  {
  	__sock_release(sock, NULL);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
591
  EXPORT_SYMBOL(sock_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592

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

8c3c447b3   Paolo Abeni   net: use indirect...
606
607
  INDIRECT_CALLABLE_DECLARE(int inet_sendmsg(struct socket *, struct msghdr *,
  					   size_t));
a648a592d   Paolo Abeni   net: adjust socke...
608
609
  INDIRECT_CALLABLE_DECLARE(int inet6_sendmsg(struct socket *, struct msghdr *,
  					    size_t));
d8725c86a   Al Viro   get rid of the si...
610
  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  {
a648a592d   Paolo Abeni   net: adjust socke...
612
613
614
  	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...
615
616
  	BUG_ON(ret == -EIOCBQUEUED);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
  }
85806af0c   Randy Dunlap   net: fix kernel-d...
618
619
620
621
622
623
624
625
  /**
   *	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...
626
  int sock_sendmsg(struct socket *sock, struct msghdr *msg)
228e548e6   Anton Blanchard   net: Add sendmmsg...
627
  {
d8725c86a   Al Viro   get rid of the si...
628
  	int err = security_socket_sendmsg(sock, msg,
01e97e651   Al Viro   new helper: msg_d...
629
  					  msg_data_left(msg));
228e548e6   Anton Blanchard   net: Add sendmmsg...
630

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

8a3c245c0   Pedro Tammela   net: add document...
635
636
637
638
639
640
641
642
643
644
645
  /**
   *	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
646
647
648
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
  		   struct kvec *vec, size_t num, size_t size)
  {
aa563d7bc   David Howells   iov_iter: Separat...
649
  	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
d8725c86a   Al Viro   get rid of the si...
650
  	return sock_sendmsg(sock, msg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
652
  EXPORT_SYMBOL(kernel_sendmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653

8a3c245c0   Pedro Tammela   net: add document...
654
655
656
657
658
659
660
661
662
663
664
665
  /**
   *	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...
666
667
668
669
670
671
  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...
672
  		return sock_no_sendmsg_locked(sk, msg, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
673

aa563d7bc   David Howells   iov_iter: Separat...
674
  	iov_iter_kvec(&msg->msg_iter, WRITE, vec, num, size);
306b13eb3   Tom Herbert   proto_ops: Add lo...
675
676
677
678
  
  	return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg));
  }
  EXPORT_SYMBOL(kernel_sendmsg_locked);
8605330aa   Soheil Hassas Yeganeh   tcp: fix SCM_TIME...
679
680
681
682
683
684
685
686
687
  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...
688
689
690
691
692
  /* 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...
693
   * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
b50a5c70f   Miroslav Lichvar   net: allow simult...
694
695
696
697
698
699
   * 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...
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
  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_...
720
721
722
723
724
725
  /*
   * 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...
726
  	int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
887feae36   Deepa Dinamani   socket: Add SO_TI...
727
  	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
9718475e6   Deepa Dinamani   socket: Add SO_TI...
728
  	struct scm_timestamping_internal tss;
b50a5c70f   Miroslav Lichvar   net: allow simult...
729
  	int empty = 1, false_tstamp = 0;
20d494735   Patrick Ohly   net: socket infra...
730
731
732
733
734
  	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...
735
  	if (need_software_tstamp && skb->tstamp == 0) {
20d494735   Patrick Ohly   net: socket infra...
736
  		__net_timestamp(skb);
b50a5c70f   Miroslav Lichvar   net: allow simult...
737
738
  		false_tstamp = 1;
  	}
20d494735   Patrick Ohly   net: socket infra...
739
740
741
  
  	if (need_software_tstamp) {
  		if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
887feae36   Deepa Dinamani   socket: Add SO_TI...
742
743
744
745
746
747
748
749
750
751
752
753
754
  			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...
755
  		} else {
887feae36   Deepa Dinamani   socket: Add SO_TI...
756
757
758
759
760
761
762
  			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...
763
  				struct __kernel_old_timespec ts;
887feae36   Deepa Dinamani   socket: Add SO_TI...
764
765
766
767
768
  
  				skb_get_timestampns(skb, &ts);
  				put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
  					 sizeof(ts), &ts);
  			}
20d494735   Patrick Ohly   net: socket infra...
769
770
  		}
  	}
f24b9be59   Willem de Bruijn   net-timestamp: ex...
771
  	memset(&tss, 0, sizeof(tss));
c199105d1   Willem de Bruijn   net-timestamp: on...
772
  	if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
9718475e6   Deepa Dinamani   socket: Add SO_TI...
773
  	    ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
20d494735   Patrick Ohly   net: socket infra...
774
  		empty = 0;
4d276eb6a   Willem de Bruijn   net: remove depre...
775
  	if (shhwtstamps &&
b9f40e21e   Willem de Bruijn   net-timestamp: mo...
776
  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
b50a5c70f   Miroslav Lichvar   net: allow simult...
777
  	    !skb_is_swtx_tstamp(skb, false_tstamp) &&
9718475e6   Deepa Dinamani   socket: Add SO_TI...
778
  	    ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
4d276eb6a   Willem de Bruijn   net: remove depre...
779
  		empty = 0;
aad9c8c47   Miroslav Lichvar   net: add new cont...
780
781
782
783
  		if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
  		    !skb_is_err_queue(skb))
  			put_ts_pktinfo(msg, skb);
  	}
1c885808e   Francis Yan   tcp: SOF_TIMESTAM...
784
  	if (!empty) {
9718475e6   Deepa Dinamani   socket: Add SO_TI...
785
786
787
788
  		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...
789

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

8c3c447b3   Paolo Abeni   net: use indirect...
827
  INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
a648a592d   Paolo Abeni   net: adjust socke...
828
829
830
  					   size_t, int));
  INDIRECT_CALLABLE_DECLARE(int inet6_recvmsg(struct socket *, struct msghdr *,
  					    size_t, int));
1b7841404   Ying Xue   net: Remove iocb ...
831
  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
2da62906b   Al Viro   [net] drop 'size'...
832
  				     int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  {
a648a592d   Paolo Abeni   net: adjust socke...
834
835
836
  	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
837
  }
85806af0c   Randy Dunlap   net: fix kernel-d...
838
839
840
841
842
843
844
845
846
  /**
   *	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'...
847
  int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
848
  {
2da62906b   Al Viro   [net] drop 'size'...
849
  	int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
850

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

c1249c0aa   Martin Lucina   net: Document the...
855
  /**
8a3c245c0   Pedro Tammela   net: add document...
856
857
858
859
860
861
862
   *	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...
863
   *
8a3c245c0   Pedro Tammela   net: add document...
864
865
866
   *	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...
867
   *
8a3c245c0   Pedro Tammela   net: add document...
868
   *	The returned value is the total number of bytes received, or an error.
c1249c0aa   Martin Lucina   net: Document the...
869
   */
8a3c245c0   Pedro Tammela   net: add document...
870

89bddce58   Stephen Hemminger   [NET] socket: cod...
871
872
  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
873
  {
1f466e1f1   Christoph Hellwig   net: cleanly hand...
874
  	msg->msg_control_is_user = false;
aa563d7bc   David Howells   iov_iter: Separat...
875
  	iov_iter_kvec(&msg->msg_iter, READ, vec, num, size);
1f466e1f1   Christoph Hellwig   net: cleanly hand...
876
  	return sock_recvmsg(sock, msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
878
  EXPORT_SYMBOL(kernel_recvmsg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879

ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
880
881
  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
882
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883
884
  	struct socket *sock;
  	int flags;
ce1d4d3e8   Christoph Hellwig   [NET]: restructur...
885
  	sock = file->private_data;
35f9c09fe   Eric Dumazet   tcp: tcp_sendpage...
886
887
888
  	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...
889

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

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

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

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

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

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

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

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

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
969
  void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
  {
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
971
  	mutex_lock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
972
  	dlci_ioctl_hook = hook;
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
973
  	mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
974
975
  }
  EXPORT_SYMBOL(dlci_ioctl_set);
6b96018b2   Arnd Bergmann   compat: move sock...
976
  static long sock_do_ioctl(struct net *net, struct socket *sock,
63ff03ab7   Johannes Berg   Revert "socket: f...
977
  			  unsigned int cmd, unsigned long arg)
6b96018b2   Arnd Bergmann   compat: move sock...
978
979
980
981
982
983
984
985
986
987
  {
  	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...
988
989
  	if (err != -ENOIOCTLCMD)
  		return err;
6b96018b2   Arnd Bergmann   compat: move sock...
990

36fd633ec   Al Viro   net: separate SIO...
991
992
993
994
995
996
997
998
999
  	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...
1000
1001
1002
  	} else {
  		struct ifreq ifr;
  		bool need_copyout;
63ff03ab7   Johannes Berg   Revert "socket: f...
1003
  		if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
1004
1005
1006
  			return -EFAULT;
  		err = dev_ioctl(net, cmd, &ifr, &need_copyout);
  		if (!err && need_copyout)
63ff03ab7   Johannes Berg   Revert "socket: f...
1007
  			if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
44c02a2c3   Al Viro   dev_ioctl(): move...
1008
  				return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
1009
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
1010
1011
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
1015
  /*
   *	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...
1016
1017
1018
1019
1020
1021
  /**
   *	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 ...
1022
  struct ns_common *get_net_ns(struct ns_common *ns)
c62cce2ca   Andrey Vagin   net: add an ioctl...
1023
1024
1025
  {
  	return &get_net(container_of(ns, struct net, ns))->ns;
  }
d8d211a2a   Kirill Tkhai   net: Make extern ...
1026
  EXPORT_SYMBOL_GPL(get_net_ns);
c62cce2ca   Andrey Vagin   net: add an ioctl...
1027

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

b69aee04f   Eric Dumazet   [NET]: Use file->...
1036
  	sock = file->private_data;
881d966b4   Eric W. Biederman   [NET]: Make the d...
1037
  	sk = sock->sk;
3b1e0a655   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
1038
  	net = sock_net(sk);
44c02a2c3   Al Viro   dev_ioctl(): move...
1039
1040
1041
1042
1043
1044
1045
1046
1047
  	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
1048
  	} else
3d23e349d   Johannes Berg   wext: refactor
1049
  #ifdef CONFIG_WEXT_CORE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
  	if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
b1b0c2450   Al Viro   lift handling of ...
1051
  		err = wext_handle_ioctl(net, cmd, argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1052
  	} else
3d23e349d   Johannes Berg   wext: refactor
1053
  #endif
89bddce58   Stephen Hemminger   [NET] socket: cod...
1054
  		switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
1056
1057
1058
1059
  		case FIOSETOWN:
  		case SIOCSPGRP:
  			err = -EFAULT;
  			if (get_user(pid, (int __user *)argp))
  				break;
393cc3f51   Jiri Slaby   fs/fcntl: f_setow...
1060
  			err = f_setown(sock->file, pid, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1061
1062
1063
  			break;
  		case FIOGETOWN:
  		case SIOCGPGRP:
609d7fa95   Eric W. Biederman   [PATCH] file: mod...
1064
  			err = put_user(f_getown(sock->file),
89bddce58   Stephen Hemminger   [NET] socket: cod...
1065
  				       (int __user *)argp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
1067
1068
1069
1070
1071
1072
1073
  			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: ...
1074
  			mutex_lock(&br_ioctl_mutex);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1075
  			if (br_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
1076
  				err = br_ioctl_hook(net, cmd, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1077
  			mutex_unlock(&br_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1078
1079
1080
1081
1082
1083
  			break;
  		case SIOCGIFVLAN:
  		case SIOCSIFVLAN:
  			err = -ENOPKG;
  			if (!vlan_ioctl_hook)
  				request_module("8021q");
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1084
  			mutex_lock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085
  			if (vlan_ioctl_hook)
881d966b4   Eric W. Biederman   [NET]: Make the d...
1086
  				err = vlan_ioctl_hook(net, argp);
4a3e2f711   Arjan van de Ven   [NET] sem2mutex: ...
1087
  			mutex_unlock(&vlan_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1088
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
1091
1092
1093
  		case SIOCADDDLCI:
  		case SIOCDELDLCI:
  			err = -ENOPKG;
  			if (!dlci_ioctl_hook)
  				request_module("dlci");
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1094
1095
  			mutex_lock(&dlci_ioctl_mutex);
  			if (dlci_ioctl_hook)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1096
  				err = dlci_ioctl_hook(cmd, argp);
7512cbf6e   Pavel Emelyanov   [DLCI]: Fix tiny ...
1097
  			mutex_unlock(&dlci_ioctl_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1098
  			break;
c62cce2ca   Andrey Vagin   net: add an ioctl...
1099
1100
1101
1102
1103
1104
1105
  		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...
1106
1107
  		case SIOCGSTAMP_OLD:
  		case SIOCGSTAMPNS_OLD:
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
1108
1109
1110
1111
1112
  			if (!sock->ops->gettstamp) {
  				err = -ENOIOCTLCMD;
  				break;
  			}
  			err = sock->ops->gettstamp(sock, argp,
0768e1707   Arnd Bergmann   net: socket: impl...
1113
1114
  						   cmd == SIOCGSTAMP_OLD,
  						   !IS_ENABLED(CONFIG_64BIT));
60747828e   Gustavo A. R. Silva   net: socket: Fix ...
1115
  			break;
0768e1707   Arnd Bergmann   net: socket: impl...
1116
1117
1118
1119
1120
1121
1122
1123
1124
  		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...
1125
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
  		default:
63ff03ab7   Johannes Berg   Revert "socket: f...
1127
  			err = sock_do_ioctl(net, sock, cmd, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
  			break;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1129
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
  	return err;
  }
8a3c245c0   Pedro Tammela   net: add document...
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
  /**
   *	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
1144
1145
1146
1147
  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...
1148

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

e88958e63   Christoph Hellwig   net: handle NULL ...
1178
1179
  	if (!sock->ops->poll)
  		return 0;
f641f13b9   Christoph Hellwig   net: remove sock_...
1180

a331de3bf   Christoph Hellwig   net: remove sock_...
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  	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
1191
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
1192
  static int sock_mmap(struct file *file, struct vm_area_struct *vma)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1193
  {
b69aee04f   Eric Dumazet   [NET]: Use file->...
1194
  	struct socket *sock = file->private_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1195
1196
1197
  
  	return sock->ops->mmap(file, sock, vma);
  }
20380731b   Arnaldo Carvalho de Melo   [NET]: Fix sparse...
1198
  static int sock_close(struct inode *inode, struct file *filp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1199
  {
6d8c50dcb   Cong Wang   socket: close rac...
1200
  	__sock_release(SOCKET_I(inode), inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
  	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...
1212
   *	   or under socket lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1213
1214
1215
1216
   */
  
  static int sock_fasync(int fd, struct file *filp, int on)
  {
989a29792   Eric Dumazet   fasync: RCU and f...
1217
1218
  	struct socket *sock = filp->private_data;
  	struct sock *sk = sock->sk;
333f7909a   Al Viro   coallocate socket...
1219
  	struct socket_wq *wq = &sock->wq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220

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

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

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

ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1237
  int sock_wake_async(struct socket_wq *wq, int how, int band)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
  {
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1239
  	if (!wq || !wq->fasync_list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
  		return -1;
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1241

89bddce58   Stephen Hemminger   [NET] socket: cod...
1242
  	switch (how) {
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1243
  	case SOCK_WAKE_WAITD:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1244
  		if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
1246
  			break;
  		goto call_kill;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1247
  	case SOCK_WAKE_SPACE:
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1248
  		if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  			break;
7c7ab580d   Miaohe Lin   net: Convert to u...
1250
  		fallthrough;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1251
  	case SOCK_WAKE_IO:
89bddce58   Stephen Hemminger   [NET] socket: cod...
1252
  call_kill:
438154823   Eric Dumazet   net: sock_def_rea...
1253
  		kill_fasync(&wq->fasync_list, SIGIO, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1254
  		break;
8d8ad9d7c   Pavel Emelyanov   [NET]: Name magic...
1255
  	case SOCK_WAKE_URG:
438154823   Eric Dumazet   net: sock_def_rea...
1256
  		kill_fasync(&wq->fasync_list, SIGURG, band);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
  	}
ceb5d58b2   Eric Dumazet   net: fix sock_wak...
1258

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259
1260
  	return 0;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1261
  EXPORT_SYMBOL(sock_wake_async);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1262

8a3c245c0   Pedro Tammela   net: add document...
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
  /**
   *	__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...
1277
  int __sock_create(struct net *net, int family, int type, int protocol,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1278
  			 struct socket **res, int kern)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
1280
1281
  {
  	int err;
  	struct socket *sock;
55737fda0   Stephen Hemminger   [NET]: socket fam...
1282
  	const struct net_proto_family *pf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1283
1284
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1285
  	 *      Check protocol is in range
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
  	 */
  	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 ...
1298
1299
1300
  		pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET)
  ",
  			     current->comm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
1302
1303
1304
1305
1306
  		family = PF_PACKET;
  	}
  
  	err = security_socket_create(family, type, protocol, kern);
  	if (err)
  		return err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1307

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

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

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

8a3c245c0   Pedro Tammela   net: add document...
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
  /**
   *	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
1393
1394
  int sock_create(int family, int type, int protocol, struct socket **res)
  {
1b8d7ae42   Eric W. Biederman   [NET]: Make socke...
1395
  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1396
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1397
  EXPORT_SYMBOL(sock_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398

8a3c245c0   Pedro Tammela   net: add document...
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
  /**
   *	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...
1410
  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1411
  {
eeb1bd5c4   Eric W. Biederman   net: Add a struct...
1412
  	return __sock_create(net, family, type, protocol, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1413
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1414
  EXPORT_SYMBOL(sock_create_kern);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1415

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

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

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

aaca0bdca   Ulrich Drepper   flag parameters: ...
1458
1459
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
  	/*
016a266bd   Al Viro   socketpair(): all...
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
  	 * 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
1483
1484
1485
1486
1487
  	 * 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...
1488
  	if (unlikely(err < 0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1489
1490
1491
  		goto out;
  
  	err = sock_create(family, type, protocol, &sock2);
016a266bd   Al Viro   socketpair(): all...
1492
1493
1494
  	if (unlikely(err < 0)) {
  		sock_release(sock1);
  		goto out;
bf3c23d17   David S. Miller   [NET]: Fix error ...
1495
  	}
d73aa2867   Yann Droneaud   net: handle error...
1496

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

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

016a266bd   Al Viro   socketpair(): all...
1527
  out:
d73aa2867   Yann Droneaud   net: handle error...
1528
  	put_unused_fd(fd2);
d73aa2867   Yann Droneaud   net: handle error...
1529
  	put_unused_fd(fd1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530
1531
  	return err;
  }
6debc8d83   Dominik Brodowski   net: socket: add ...
1532
1533
1534
1535
1536
  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
1537
1538
1539
1540
1541
1542
1543
  /*
   *	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 ...
1544
  int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1545
1546
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1547
  	struct sockaddr_storage address;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1548
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549

89bddce58   Stephen Hemminger   [NET] socket: cod...
1550
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
e71a4783a   Stephen Hemminger   [NET] core: white...
1551
  	if (sock) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1552
  		err = move_addr_to_kernel(umyaddr, addrlen, &address);
068b88cc1   Jakub Sitnicki   socket: Tighten n...
1553
  		if (!err) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
1554
  			err = security_socket_bind(sock,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1555
  						   (struct sockaddr *)&address,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1556
  						   addrlen);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1557
1558
  			if (!err)
  				err = sock->ops->bind(sock,
89bddce58   Stephen Hemminger   [NET] socket: cod...
1559
  						      (struct sockaddr *)
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1560
  						      &address, addrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
  		}
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1562
  		fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1563
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1564
1565
  	return err;
  }
a87d35d87   Dominik Brodowski   net: socket: add ...
1566
1567
1568
1569
  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
1570
1571
1572
1573
1574
  /*
   *	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 ...
1575
  int __sys_listen(int fd, int backlog)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
  {
  	struct socket *sock;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1578
  	int err, fput_needed;
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1579
  	int somaxconn;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1580
1581
1582
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock) {
8efa6e93c   Pavel Emelyanov   [NETNS]: Introduc...
1583
  		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
95c961747   Eric Dumazet   net: cleanup unsi...
1584
  		if ((unsigned int)backlog > somaxconn)
b8e1f9b5c   Pavel Emelyanov   [NET] sysctl: mak...
1585
  			backlog = somaxconn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1586
1587
  
  		err = security_socket_listen(sock, backlog);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1588
1589
  		if (!err)
  			err = sock->ops->listen(sock, backlog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1590

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

77d272005   Ulrich Drepper   flag parameters: ...
1609
  	if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK))
aaca0bdca   Ulrich Drepper   flag parameters: ...
1610
1611
1612
1613
  		return -EINVAL;
  
  	if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
  		flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
de2ea4b64   Jens Axboe   net: add __sys_ac...
1614
  	sock = sock_from_file(file, &err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615
1616
1617
1618
  	if (!sock)
  		goto out;
  
  	err = -ENFILE;
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
1619
1620
  	newsock = sock_alloc();
  	if (!newsock)
de2ea4b64   Jens Axboe   net: add __sys_ac...
1621
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1622
1623
1624
  
  	newsock->type = sock->type;
  	newsock->ops = sock->ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625
1626
1627
1628
1629
  	/*
  	 * 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);
09952e3e7   Jens Axboe   io_uring: make su...
1630
  	newfd = __get_unused_fd_flags(flags, nofile);
39d8c1b6f   David S. Miller   [NET]: Do not los...
1631
1632
  	if (unlikely(newfd < 0)) {
  		err = newfd;
9a1875e60   David S. Miller   [NET]: Fully fix ...
1633
  		sock_release(newsock);
de2ea4b64   Jens Axboe   net: add __sys_ac...
1634
  		goto out;
39d8c1b6f   David S. Miller   [NET]: Do not los...
1635
  	}
aab174f0d   Linus Torvalds   Merge branch 'for...
1636
  	newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name);
b5ffe6344   Viresh Kumar   net: Drop unlikel...
1637
  	if (IS_ERR(newfile)) {
284076305   Al Viro   take descriptor h...
1638
1639
  		err = PTR_ERR(newfile);
  		put_unused_fd(newfd);
de2ea4b64   Jens Axboe   net: add __sys_ac...
1640
  		goto out;
284076305   Al Viro   take descriptor h...
1641
  	}
39d8c1b6f   David S. Miller   [NET]: Do not los...
1642

a79af59ef   Frank Filz   [NET]: Fix module...
1643
1644
  	err = security_socket_accept(sock, newsock);
  	if (err)
39d8c1b6f   David S. Miller   [NET]: Do not los...
1645
  		goto out_fd;
a79af59ef   Frank Filz   [NET]: Fix module...
1646

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

bd3ded314   Jens Axboe   net: add __sys_co...
1732
  	sock = sock_from_file(file, &err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
1734
  	if (!sock)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1735

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

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

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
1813
1814
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1815
1816
  		err = security_socket_getpeername(sock);
  		if (err) {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1817
  			fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
1819
  			return err;
  		}
9b2c45d47   Denys Vlasenko   net: make getname...
1820
1821
1822
1823
  		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...
1824
  						usockaddr_len);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1825
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
1827
1828
  	}
  	return err;
  }
b21c8f838   Dominik Brodowski   net: socket: add ...
1829
1830
1831
1832
1833
  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
1834
1835
1836
1837
1838
  /*
   *	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 ...
1839
1840
  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
1841
1842
  {
  	struct socket *sock;
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1843
  	struct sockaddr_storage address;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1844
1845
1846
  	int err;
  	struct msghdr msg;
  	struct iovec iov;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1847
  	int fput_needed;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1848

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

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

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

89bddce58   Stephen Hemminger   [NET] socket: cod...
1913
1914
  	msg.msg_control = NULL;
  	msg.msg_controllen = 0;
f3d334260   Hannes Frederic Sowa   net: rework recvm...
1915
1916
1917
1918
  	/* 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...
1919
  	msg.msg_iocb = NULL;
9f138fa60   Alexander Potapenko   net: initialize m...
1920
  	msg.msg_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1921
1922
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
2da62906b   Al Viro   [net] drop 'size'...
1923
  	err = sock_recvmsg(sock, &msg, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1924

89bddce58   Stephen Hemminger   [NET] socket: cod...
1925
  	if (err >= 0 && addr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
1926
  		err2 = move_addr_to_user(&address,
230b18392   YOSHIFUJI Hideaki   net: Use standard...
1927
  					 msg.msg_namelen, addr, addr_len);
89bddce58   Stephen Hemminger   [NET] socket: cod...
1928
1929
  		if (err2 < 0)
  			err = err2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1930
  	}
de0fa95c1   Pavel Emelyanov   [NET]: Use sockfd...
1931
1932
  
  	fput_light(sock->file, fput_needed);
4387ff75f   David S. Miller   [NET]: Fix net/so...
1933
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1934
1935
  	return err;
  }
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1936
1937
1938
1939
1940
1941
  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
1942
  /*
89bddce58   Stephen Hemminger   [NET] socket: cod...
1943
   *	Receive a datagram from a socket.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1944
   */
b7c0ddf5f   Jan Glauber   net: use SYSCALL_...
1945
1946
  SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
  		unsigned int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
  {
7a09e1eb9   Dominik Brodowski   net: socket: add ...
1948
  	return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1949
  }
83f0c10bc   Florian Westphal   net: use mptcp se...
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
  static bool sock_use_custom_sol_socket(const struct socket *sock)
  {
  	const struct sock *sk = sock->sk;
  
  	/* Use sock->ops->setsockopt() for MPTCP */
  	return IS_ENABLED(CONFIG_MPTCP) &&
  	       sk->sk_protocol == IPPROTO_MPTCP &&
  	       sk->sk_type == SOCK_STREAM &&
  	       (sk->sk_family == AF_INET || sk->sk_family == AF_INET6);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1960
1961
1962
1963
  /*
   *	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.
   */
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
1964
  int __sys_setsockopt(int fd, int level, int optname, char __user *user_optval,
55db9c0e8   Christoph Hellwig   net: remove compa...
1965
  		int optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
  {
519a8a6cf   Christoph Hellwig   net: Revert "net:...
1967
  	sockptr_t optval = USER_SOCKPTR(user_optval);
0d01da6af   Stanislav Fomichev   bpf: implement ge...
1968
  	char *kernel_optval = NULL;
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
1969
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1970
1971
1972
1973
  	struct socket *sock;
  
  	if (optlen < 0)
  		return -EINVAL;
89bddce58   Stephen Hemminger   [NET] socket: cod...
1974
1975
  
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
4a3672993   Christoph Hellwig   net: streamline _...
1976
1977
  	if (!sock)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1978

4a3672993   Christoph Hellwig   net: streamline _...
1979
1980
1981
  	err = security_socket_setsockopt(sock, level, optname);
  	if (err)
  		goto out_put;
0d01da6af   Stanislav Fomichev   bpf: implement ge...
1982

55db9c0e8   Christoph Hellwig   net: remove compa...
1983
1984
  	if (!in_compat_syscall())
  		err = BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock->sk, &level, &optname,
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
1985
  						     user_optval, &optlen,
55db9c0e8   Christoph Hellwig   net: remove compa...
1986
  						     &kernel_optval);
4a3672993   Christoph Hellwig   net: streamline _...
1987
1988
1989
1990
1991
1992
  	if (err < 0)
  		goto out_put;
  	if (err > 0) {
  		err = 0;
  		goto out_put;
  	}
0d01da6af   Stanislav Fomichev   bpf: implement ge...
1993

a7b75c5a8   Christoph Hellwig   net: pass a sockp...
1994
1995
  	if (kernel_optval)
  		optval = KERNEL_SOCKPTR(kernel_optval);
4a3672993   Christoph Hellwig   net: streamline _...
1996
  	if (level == SOL_SOCKET && !sock_use_custom_sol_socket(sock))
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
1997
  		err = sock_setsockopt(sock, level, optname, optval, optlen);
a44d9e721   Christoph Hellwig   net: make ->{get,...
1998
1999
  	else if (unlikely(!sock->ops->setsockopt))
  		err = -EOPNOTSUPP;
4a3672993   Christoph Hellwig   net: streamline _...
2000
2001
  	else
  		err = sock->ops->setsockopt(sock, level, optname, optval,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2002
  					    optlen);
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
2003
  	kfree(kernel_optval);
4a3672993   Christoph Hellwig   net: streamline _...
2004
2005
  out_put:
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2006
2007
  	return err;
  }
cc36dca0d   Dominik Brodowski   net: socket: add ...
2008
2009
2010
2011
2012
  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
2013
2014
2015
2016
  /*
   *	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.
   */
55db9c0e8   Christoph Hellwig   net: remove compa...
2017
2018
  int __sys_getsockopt(int fd, int level, int optname, char __user *optval,
  		int __user *optlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2019
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2020
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2021
  	struct socket *sock;
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2022
  	int max_optlen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023

89bddce58   Stephen Hemminger   [NET] socket: cod...
2024
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
d8a9b38f8   Christoph Hellwig   net: streamline _...
2025
2026
2027
2028
2029
2030
  	if (!sock)
  		return err;
  
  	err = security_socket_getsockopt(sock, level, optname);
  	if (err)
  		goto out_put;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2031

55db9c0e8   Christoph Hellwig   net: remove compa...
2032
2033
  	if (!in_compat_syscall())
  		max_optlen = BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN(optlen);
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2034

d8a9b38f8   Christoph Hellwig   net: streamline _...
2035
2036
  	if (level == SOL_SOCKET)
  		err = sock_getsockopt(sock, level, optname, optval, optlen);
a44d9e721   Christoph Hellwig   net: make ->{get,...
2037
2038
  	else if (unlikely(!sock->ops->getsockopt))
  		err = -EOPNOTSUPP;
d8a9b38f8   Christoph Hellwig   net: streamline _...
2039
2040
  	else
  		err = sock->ops->getsockopt(sock, level, optname, optval,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2041
  					    optlen);
0d01da6af   Stanislav Fomichev   bpf: implement ge...
2042

55db9c0e8   Christoph Hellwig   net: remove compa...
2043
2044
2045
2046
  	if (!in_compat_syscall())
  		err = BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock->sk, level, optname,
  						     optval, optlen, max_optlen,
  						     err);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2047
  out_put:
d8a9b38f8   Christoph Hellwig   net: streamline _...
2048
  	fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2049
2050
  	return err;
  }
13a2d70e2   Dominik Brodowski   net: socket: add ...
2051
2052
2053
2054
2055
  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
2056
2057
2058
  /*
   *	Shutdown a socket.
   */
005a1aeac   Dominik Brodowski   net: socket: add ...
2059
  int __sys_shutdown(int fd, int how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2060
  {
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2061
  	int err, fput_needed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2062
  	struct socket *sock;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2063
2064
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
  	if (sock != NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2065
  		err = security_socket_shutdown(sock, how);
6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2066
2067
2068
  		if (!err)
  			err = sock->ops->shutdown(sock, how);
  		fput_light(sock->file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
2070
2071
  	}
  	return err;
  }
005a1aeac   Dominik Brodowski   net: socket: add ...
2072
2073
2074
2075
  SYSCALL_DEFINE2(shutdown, int, fd, int, how)
  {
  	return __sys_shutdown(fd, how);
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2076
  /* A couple of helpful macros for getting the address of the 32/64 bit
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2077
2078
2079
2080
2081
   * 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...
2082
2083
2084
2085
  struct used_address {
  	struct sockaddr_storage name;
  	unsigned int name_len;
  };
0a384abfa   Jens Axboe   net: abstract out...
2086
2087
2088
2089
  int __copy_msghdr_from_user(struct msghdr *kmsg,
  			    struct user_msghdr __user *umsg,
  			    struct sockaddr __user **save_addr,
  			    struct iovec __user **uiov, size_t *nsegs)
1661bf364   Dan Carpenter   net: heap overflo...
2090
  {
ffb07550c   Al Viro   copy_msghdr_from_...
2091
  	struct user_msghdr msg;
08adb7dab   Al Viro   fold verify_iovec...
2092
  	ssize_t err;
ffb07550c   Al Viro   copy_msghdr_from_...
2093
  	if (copy_from_user(&msg, umsg, sizeof(*umsg)))
1661bf364   Dan Carpenter   net: heap overflo...
2094
  		return -EFAULT;
dbb490b96   Matthew Leach   net: socket: erro...
2095

1f466e1f1   Christoph Hellwig   net: cleanly hand...
2096
2097
  	kmsg->msg_control_is_user = true;
  	kmsg->msg_control_user = msg.msg_control;
ffb07550c   Al Viro   copy_msghdr_from_...
2098
2099
2100
2101
2102
  	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...
2103
  		kmsg->msg_namelen = 0;
dbb490b96   Matthew Leach   net: socket: erro...
2104
2105
  	if (kmsg->msg_namelen < 0)
  		return -EINVAL;
1661bf364   Dan Carpenter   net: heap overflo...
2106
  	if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
db31c55a6   Dan Carpenter   net: clamp ->msg_...
2107
  		kmsg->msg_namelen = sizeof(struct sockaddr_storage);
08adb7dab   Al Viro   fold verify_iovec...
2108
2109
  
  	if (save_addr)
ffb07550c   Al Viro   copy_msghdr_from_...
2110
  		*save_addr = msg.msg_name;
08adb7dab   Al Viro   fold verify_iovec...
2111

ffb07550c   Al Viro   copy_msghdr_from_...
2112
  	if (msg.msg_name && kmsg->msg_namelen) {
08adb7dab   Al Viro   fold verify_iovec...
2113
  		if (!save_addr) {
864d96642   Paolo Abeni   net/socket: fix t...
2114
2115
  			err = move_addr_to_kernel(msg.msg_name,
  						  kmsg->msg_namelen,
08adb7dab   Al Viro   fold verify_iovec...
2116
2117
2118
2119
2120
2121
2122
2123
  						  kmsg->msg_name);
  			if (err < 0)
  				return err;
  		}
  	} else {
  		kmsg->msg_name = NULL;
  		kmsg->msg_namelen = 0;
  	}
ffb07550c   Al Viro   copy_msghdr_from_...
2124
  	if (msg.msg_iovlen > UIO_MAXIOV)
08adb7dab   Al Viro   fold verify_iovec...
2125
  		return -EMSGSIZE;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
2126
  	kmsg->msg_iocb = NULL;
0a384abfa   Jens Axboe   net: abstract out...
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
  	*uiov = msg.msg_iov;
  	*nsegs = msg.msg_iovlen;
  	return 0;
  }
  
  static int copy_msghdr_from_user(struct msghdr *kmsg,
  				 struct user_msghdr __user *umsg,
  				 struct sockaddr __user **save_addr,
  				 struct iovec **iov)
  {
  	struct user_msghdr msg;
  	ssize_t err;
  
  	err = __copy_msghdr_from_user(kmsg, umsg, save_addr, &msg.msg_iov,
  					&msg.msg_iovlen);
  	if (err)
  		return err;
0345f9313   tadeusz.struk@intel.com   net: socket: add ...
2144

87e5e6dab   Jens Axboe   uio: make import_...
2145
  	err = import_iovec(save_addr ? READ : WRITE,
ffb07550c   Al Viro   copy_msghdr_from_...
2146
  			    msg.msg_iov, msg.msg_iovlen,
da1842849   Al Viro   net: switch impor...
2147
  			    UIO_FASTIOV, iov, &kmsg->msg_iter);
87e5e6dab   Jens Axboe   uio: make import_...
2148
  	return err < 0 ? err : 0;
1661bf364   Dan Carpenter   net: heap overflo...
2149
  }
4257c8ca1   Jens Axboe   net: separate out...
2150
2151
2152
  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
2153
  {
b9d717a7b   Alex Williamson   [NET]: Make sure ...
2154
  	unsigned char ctl[sizeof(struct cmsghdr) + 20]
846cc1231   Amit Kushwaha   net: socket: pref...
2155
  				__aligned(sizeof(__kernel_size_t));
89bddce58   Stephen Hemminger   [NET] socket: cod...
2156
  	/* 20 is size of ipv6_pktinfo */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2157
  	unsigned char *ctl_buf = ctl;
d8725c86a   Al Viro   get rid of the si...
2158
  	int ctl_len;
08adb7dab   Al Viro   fold verify_iovec...
2159
  	ssize_t err;
89bddce58   Stephen Hemminger   [NET] socket: cod...
2160

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2161
  	err = -ENOBUFS;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2162
  	if (msg_sys->msg_controllen > INT_MAX)
4257c8ca1   Jens Axboe   net: separate out...
2163
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2164
  	flags |= (msg_sys->msg_flags & allowed_msghdr_flags);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2165
  	ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2166
  	if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
89bddce58   Stephen Hemminger   [NET] socket: cod...
2167
  		err =
228e548e6   Anton Blanchard   net: Add sendmmsg...
2168
  		    cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2169
  						     sizeof(ctl));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2170
  		if (err)
4257c8ca1   Jens Axboe   net: separate out...
2171
  			goto out;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2172
2173
  		ctl_buf = msg_sys->msg_control;
  		ctl_len = msg_sys->msg_controllen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2174
  	} else if (ctl_len) {
ac4340fc3   David S. Miller   net: Assert at bu...
2175
2176
  		BUILD_BUG_ON(sizeof(struct cmsghdr) !=
  			     CMSG_ALIGN(sizeof(struct cmsghdr)));
89bddce58   Stephen Hemminger   [NET] socket: cod...
2177
  		if (ctl_len > sizeof(ctl)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2178
  			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2179
  			if (ctl_buf == NULL)
4257c8ca1   Jens Axboe   net: separate out...
2180
  				goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2181
2182
  		}
  		err = -EFAULT;
1f466e1f1   Christoph Hellwig   net: cleanly hand...
2183
  		if (copy_from_user(ctl_buf, msg_sys->msg_control_user, ctl_len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2184
  			goto out_freectl;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2185
  		msg_sys->msg_control = ctl_buf;
1f466e1f1   Christoph Hellwig   net: cleanly hand...
2186
  		msg_sys->msg_control_is_user = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2187
  	}
228e548e6   Anton Blanchard   net: Add sendmmsg...
2188
  	msg_sys->msg_flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2189
2190
  
  	if (sock->file->f_flags & O_NONBLOCK)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2191
  		msg_sys->msg_flags |= MSG_DONTWAIT;
c71d8ebe7   Tetsuo Handa   net: Fix security...
2192
2193
2194
2195
2196
2197
  	/*
  	 * 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:...
2198
2199
2200
  	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...
2201
  		    used_address->name_len)) {
d8725c86a   Al Viro   get rid of the si...
2202
  		err = sock_sendmsg_nosec(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2203
2204
  		goto out_freectl;
  	}
d8725c86a   Al Viro   get rid of the si...
2205
  	err = sock_sendmsg(sock, msg_sys);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2206
2207
2208
2209
2210
2211
  	/*
  	 * 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:...
2212
2213
2214
  		if (msg_sys->msg_name)
  			memcpy(&used_address->name, msg_sys->msg_name,
  			       used_address->name_len);
c71d8ebe7   Tetsuo Handa   net: Fix security...
2215
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2216
2217
  
  out_freectl:
89bddce58   Stephen Hemminger   [NET] socket: cod...
2218
  	if (ctl_buf != ctl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2219
  		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
4257c8ca1   Jens Axboe   net: separate out...
2220
2221
2222
  out:
  	return err;
  }
03b1230ca   Jens Axboe   io_uring: ensure ...
2223
2224
2225
  int sendmsg_copy_msghdr(struct msghdr *msg,
  			struct user_msghdr __user *umsg, unsigned flags,
  			struct iovec **iov)
4257c8ca1   Jens Axboe   net: separate out...
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
  {
  	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...
2260
  	kfree(iov);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2261
2262
2263
2264
2265
2266
  	return err;
  }
  
  /*
   *	BSD sendmsg interface
   */
03b1230ca   Jens Axboe   io_uring: ensure ...
2267
  long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
0fa03c624   Jens Axboe   io_uring: add sup...
2268
2269
  			unsigned int flags)
  {
d69e07793   Jens Axboe   net: disallow anc...
2270
  	/* disallow ancillary data requests from this path */
03b1230ca   Jens Axboe   io_uring: ensure ...
2271
2272
  	if (msg->msg_control || msg->msg_controllen)
  		return -EINVAL;
d69e07793   Jens Axboe   net: disallow anc...
2273

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

e1834a329   Dominik Brodowski   net: socket: move...
2277
2278
  long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags,
  		   bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2279
2280
2281
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2282
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2283
2284
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2285
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2286
2287
  	if (!sock)
  		goto out;
28a94d8fb   Tom Herbert   net: Allow MSG_EO...
2288
  	err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0);
228e548e6   Anton Blanchard   net: Add sendmmsg...
2289

6cb153cab   Benjamin LaHaise   [NET]: use fget_l...
2290
  	fput_light(sock->file, fput_needed);
89bddce58   Stephen Hemminger   [NET] socket: cod...
2291
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2292
2293
  	return err;
  }
666547ff5   Al Viro   separate kernel- ...
2294
  SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2295
  {
e1834a329   Dominik Brodowski   net: socket: move...
2296
  	return __sys_sendmsg(fd, msg, flags, true);
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2297
  }
228e548e6   Anton Blanchard   net: Add sendmmsg...
2298
2299
2300
2301
2302
  /*
   *	Linux sendmmsg interface
   */
  
  int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
e1834a329   Dominik Brodowski   net: socket: move...
2303
  		   unsigned int flags, bool forbid_cmsg_compat)
228e548e6   Anton Blanchard   net: Add sendmmsg...
2304
2305
2306
2307
2308
2309
  {
  	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...
2310
  	struct used_address used_address;
f092276d8   Tom Herbert   net: Add MSG_BATC...
2311
  	unsigned int oflags = flags;
228e548e6   Anton Blanchard   net: Add sendmmsg...
2312

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

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

4257c8ca1   Jens Axboe   net: separate out...
2378
2379
2380
2381
2382
  		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
2383
  	if (err < 0)
da1842849   Al Viro   net: switch impor...
2384
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2385

4257c8ca1   Jens Axboe   net: separate out...
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
  	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...
2403
2404
  	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...
2405

f3d334260   Hannes Frederic Sowa   net: rework recvm...
2406
2407
  	/* We assume all kernel code knows the size of sockaddr_storage */
  	msg_sys->msg_namelen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2408
2409
  	if (sock->file->f_flags & O_NONBLOCK)
  		flags |= MSG_DONTWAIT;
1af66221a   Eric Dumazet   net: avoid an ind...
2410
2411
2412
2413
2414
  
  	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
2415
  	if (err < 0)
4257c8ca1   Jens Axboe   net: separate out...
2416
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417
2418
2419
  	len = err;
  
  	if (uaddr != NULL) {
43db362d3   Maciej Å»enczykowski   net: get rid of s...
2420
  		err = move_addr_to_user(&addr,
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2421
  					msg_sys->msg_namelen, uaddr,
89bddce58   Stephen Hemminger   [NET] socket: cod...
2422
  					uaddr_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2423
  		if (err < 0)
4257c8ca1   Jens Axboe   net: separate out...
2424
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2425
  	}
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2426
  	err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
37f7f421c   David S. Miller   [NET]: Do not lea...
2427
  			 COMPAT_FLAGS(msg));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2428
  	if (err)
4257c8ca1   Jens Axboe   net: separate out...
2429
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2430
  	if (MSG_CMSG_COMPAT & flags)
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2431
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2432
2433
  				 &msg_compat->msg_controllen);
  	else
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2434
  		err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2435
2436
  				 &msg->msg_controllen);
  	if (err)
4257c8ca1   Jens Axboe   net: separate out...
2437
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2438
  	err = len;
4257c8ca1   Jens Axboe   net: separate out...
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
  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
2454

4257c8ca1   Jens Axboe   net: separate out...
2455
  	err = ____sys_recvmsg(sock, msg_sys, msg, uaddr, flags, nosec);
da1842849   Al Viro   net: switch impor...
2456
  	kfree(iov);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2457
2458
2459
2460
2461
2462
  	return err;
  }
  
  /*
   *	BSD recvmsg interface
   */
03b1230ca   Jens Axboe   io_uring: ensure ...
2463
2464
2465
  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...
2466
  {
d69e07793   Jens Axboe   net: disallow anc...
2467
  	/* disallow ancillary data requests from this path */
03b1230ca   Jens Axboe   io_uring: ensure ...
2468
2469
  	if (msg->msg_control || msg->msg_controllen)
  		return -EINVAL;
aa1fa28fc   Jens Axboe   io_uring: add sup...
2470

03b1230ca   Jens Axboe   io_uring: ensure ...
2471
  	return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0);
aa1fa28fc   Jens Axboe   io_uring: add sup...
2472
  }
e1834a329   Dominik Brodowski   net: socket: move...
2473
2474
  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...
2475
2476
2477
  {
  	int fput_needed, err;
  	struct msghdr msg_sys;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2478
  	struct socket *sock;
e1834a329   Dominik Brodowski   net: socket: move...
2479
2480
  	if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT))
  		return -EINVAL;
1be374a05   Andy Lutomirski   net: Block MSG_CM...
2481
  	sock = sockfd_lookup_light(fd, &err, &fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2482
2483
  	if (!sock)
  		goto out;
a7526eb5d   Andy Lutomirski   net: Unbreak comp...
2484
  	err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2485

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

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2585
2586
2587
2588
2589
  	/*
  	 * 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...
2590
  		/*
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2591
2592
2593
2594
  		 * ... 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...
2595
  		 */
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2596
  		sock->sk->sk_err = -err;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2597
  	}
34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2598
2599
  out_put:
  	fput_light(sock->file, fput_needed);
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2600

34b88a68f   Arnaldo Carvalho de Melo   net: Fix use afte...
2601
  	return datagrams;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2602
  }
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2603
2604
2605
2606
  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...
2607
2608
  {
  	int datagrams;
c2e6c8567   Arnd Bergmann   y2038: socket: Ch...
2609
  	struct timespec64 timeout_sys;
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2610

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

e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2614
  	if (timeout32 && get_old_timespec32(&timeout_sys, timeout32))
a2e272554   Arnaldo Carvalho de Melo   net: Introduce re...
2615
  		return -EFAULT;
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2616
2617
2618
2619
  	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...
2620

e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2621
2622
2623
2624
2625
2626
2627
  	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...
2628
2629
2630
2631
  		datagrams = -EFAULT;
  
  	return datagrams;
  }
1255e2690   Dominik Brodowski   net: socket: add ...
2632
2633
  SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
  		unsigned int, vlen, unsigned int, flags,
c2e6c8567   Arnd Bergmann   y2038: socket: Ch...
2634
  		struct __kernel_timespec __user *, timeout)
1255e2690   Dominik Brodowski   net: socket: add ...
2635
  {
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
  	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 ...
2651
  }
e11d4284e   Arnd Bergmann   y2038: socket: Ad...
2652
  #endif
1255e2690   Dominik Brodowski   net: socket: add ...
2653

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

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

47379052b   Arjan van de Ven   net: Add explicit...
2683
2684
2685
  	len = nargs[call];
  	if (len > sizeof(a))
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2686
  	/* copy_from_user should be SMP safe. */
47379052b   Arjan van de Ven   net: Add explicit...
2687
  	if (copy_from_user(a, args, len))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2688
  		return -EFAULT;
3ec3b2fba   David Woodhouse   AUDIT: Capture sy...
2689

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

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

55737fda0   Stephen Hemminger   [NET]: socket fam...
2791
2792
2793
2794
  /**
   *	sock_register - add a socket protocol handler
   *	@ops: description of protocol
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2795
2796
   *	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...
2797
   *	socket interface. The value ops->family corresponds to the
55737fda0   Stephen Hemminger   [NET]: socket fam...
2798
   *	socket system call protocol family.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2799
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2800
  int sock_register(const struct net_proto_family *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2801
2802
2803
2804
  {
  	int err;
  
  	if (ops->family >= NPROTO) {
3410f22ea   Yang Yingliang   socket: replace s...
2805
2806
  		pr_crit("protocol %d >= NPROTO(%d)
  ", ops->family, NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2807
2808
  		return -ENOBUFS;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2809
2810
  
  	spin_lock(&net_family_lock);
190683a9d   Eric Dumazet   net: net_families...
2811
2812
  	if (rcu_dereference_protected(net_families[ops->family],
  				      lockdep_is_held(&net_family_lock)))
55737fda0   Stephen Hemminger   [NET]: socket fam...
2813
2814
  		err = -EEXIST;
  	else {
cf778b00e   Eric Dumazet   net: reintroduce ...
2815
  		rcu_assign_pointer(net_families[ops->family], ops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2816
2817
  		err = 0;
  	}
55737fda0   Stephen Hemminger   [NET]: socket fam...
2818
  	spin_unlock(&net_family_lock);
3410f22ea   Yang Yingliang   socket: replace s...
2819
2820
  	pr_info("NET: Registered protocol family %d
  ", ops->family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2821
2822
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2823
  EXPORT_SYMBOL(sock_register);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2824

55737fda0   Stephen Hemminger   [NET]: socket fam...
2825
2826
2827
2828
  /**
   *	sock_unregister - remove a protocol handler
   *	@family: protocol family to remove
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2829
2830
   *	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...
2831
2832
2833
2834
2835
2836
   *	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
2837
   */
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2838
  void sock_unregister(int family)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2839
  {
f0fd27d42   Stephen Hemminger   [NET]: sock_regis...
2840
  	BUG_ON(family < 0 || family >= NPROTO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2841

55737fda0   Stephen Hemminger   [NET]: socket fam...
2842
  	spin_lock(&net_family_lock);
a9b3cd7f3   Stephen Hemminger   rcu: convert uses...
2843
  	RCU_INIT_POINTER(net_families[family], NULL);
55737fda0   Stephen Hemminger   [NET]: socket fam...
2844
2845
2846
  	spin_unlock(&net_family_lock);
  
  	synchronize_rcu();
3410f22ea   Yang Yingliang   socket: replace s...
2847
2848
  	pr_info("NET: Unregistered protocol family %d
  ", family);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2849
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
2850
  EXPORT_SYMBOL(sock_unregister);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2851

bf2ae2e4b   Xin Long   sock_diag: reques...
2852
2853
  bool sock_is_registered(int family)
  {
66b51b0a0   Jeremy Cline   net: sock_diag: F...
2854
  	return family < NPROTO && rcu_access_pointer(net_families[family]);
bf2ae2e4b   Xin Long   sock_diag: reques...
2855
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2856
  static int __init sock_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2857
  {
b3e19d924   Nick Piggin   fs: scale mntget/...
2858
  	int err;
2ca794e5e   Eric W. Biederman   net sysctl: Initi...
2859
2860
2861
2862
2863
2864
  	/*
  	 *      Initialize the network sysctl infrastructure.
  	 */
  	err = net_sysctl_init();
  	if (err)
  		goto out;
b3e19d924   Nick Piggin   fs: scale mntget/...
2865

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2866
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2867
  	 *      Initialize skbuff SLAB cache
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2868
2869
  	 */
  	skb_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2870
2871
  
  	/*
89bddce58   Stephen Hemminger   [NET] socket: cod...
2872
  	 *      Initialize the protocols module.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2873
2874
2875
  	 */
  
  	init_inodecache();
b3e19d924   Nick Piggin   fs: scale mntget/...
2876
2877
2878
  
  	err = register_filesystem(&sock_fs_type);
  	if (err)
47260ba93   Miaohe Lin   net: Remove meani...
2879
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2880
  	sock_mnt = kern_mount(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2881
2882
2883
2884
  	if (IS_ERR(sock_mnt)) {
  		err = PTR_ERR(sock_mnt);
  		goto out_mount;
  	}
77d76ea31   Andi Kleen   [NET]: Small clea...
2885
2886
  
  	/* The real protocol initialization is performed in later initcalls.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2887
2888
2889
  	 */
  
  #ifdef CONFIG_NETFILTER
6d11cfdba   Pablo Neira Ayuso   netfilter: don't ...
2890
2891
2892
  	err = netfilter_init();
  	if (err)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2893
  #endif
cbeb321a6   David S. Miller   [NET]: Fix sock_i...
2894

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

b3e19d924   Nick Piggin   fs: scale mntget/...
2897
2898
2899
2900
2901
  out:
  	return err;
  
  out_mount:
  	unregister_filesystem(&sock_fs_type);
b3e19d924   Nick Piggin   fs: scale mntget/...
2902
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2903
  }
77d76ea31   Andi Kleen   [NET]: Small clea...
2904
  core_initcall(sock_init);	/* early initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2905
2906
2907
  #ifdef CONFIG_PROC_FS
  void socket_seq_show(struct seq_file *seq)
  {
648845ab7   Tonghao Zhang   sock: Move the so...
2908
2909
2910
  	seq_printf(seq, "sockets: used %d
  ",
  		   sock_inuse_get(seq->private));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2911
  }
89bddce58   Stephen Hemminger   [NET] socket: cod...
2912
  #endif				/* CONFIG_PROC_FS */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2913

89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
2914
  #ifdef CONFIG_COMPAT
36fd633ec   Al Viro   net: separate SIO...
2915
  static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
7a229387d   Arnd Bergmann   net: copy socket ...
2916
  {
6b96018b2   Arnd Bergmann   compat: move sock...
2917
  	struct compat_ifconf ifc32;
7a229387d   Arnd Bergmann   net: copy socket ...
2918
  	struct ifconf ifc;
7a229387d   Arnd Bergmann   net: copy socket ...
2919
  	int err;
6b96018b2   Arnd Bergmann   compat: move sock...
2920
  	if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2921
  		return -EFAULT;
36fd633ec   Al Viro   net: separate SIO...
2922
2923
  	ifc.ifc_len = ifc32.ifc_len;
  	ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
7a229387d   Arnd Bergmann   net: copy socket ...
2924

36fd633ec   Al Viro   net: separate SIO...
2925
2926
2927
  	rtnl_lock();
  	err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
  	rtnl_unlock();
7a229387d   Arnd Bergmann   net: copy socket ...
2928
2929
  	if (err)
  		return err;
36fd633ec   Al Viro   net: separate SIO...
2930
  	ifc32.ifc_len = ifc.ifc_len;
6b96018b2   Arnd Bergmann   compat: move sock...
2931
  	if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
7a229387d   Arnd Bergmann   net: copy socket ...
2932
2933
2934
2935
  		return -EFAULT;
  
  	return 0;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
2936
  static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
7a229387d   Arnd Bergmann   net: copy socket ...
2937
  {
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2938
2939
  	struct compat_ethtool_rxnfc __user *compat_rxnfc;
  	bool convert_in = false, convert_out = false;
44c02a2c3   Al Viro   dev_ioctl(): move...
2940
2941
2942
  	size_t buf_size = 0;
  	struct ethtool_rxnfc __user *rxnfc = NULL;
  	struct ifreq ifr;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2943
2944
  	u32 rule_cnt = 0, actual_rule_cnt;
  	u32 ethcmd;
7a229387d   Arnd Bergmann   net: copy socket ...
2945
  	u32 data;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2946
  	int ret;
7a229387d   Arnd Bergmann   net: copy socket ...
2947

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

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2951
2952
2953
  	compat_rxnfc = compat_ptr(data);
  
  	if (get_user(ethcmd, &compat_rxnfc->cmd))
7a229387d   Arnd Bergmann   net: copy socket ...
2954
  		return -EFAULT;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
  	/* 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);
7c7ab580d   Miaohe Lin   net: Convert to u...
2968
  		fallthrough;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2969
2970
2971
  	case ETHTOOL_GRXRINGS:
  	case ETHTOOL_GRXCLSRLCNT:
  	case ETHTOOL_GRXCLSRULE:
55664f324   Ben Hutchings   ethtool: Allow dr...
2972
  	case ETHTOOL_SRXCLSRLINS:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2973
  		convert_out = true;
7c7ab580d   Miaohe Lin   net: Convert to u...
2974
  		fallthrough;
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2975
  	case ETHTOOL_SRXCLSRLDEL:
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2976
2977
  		buf_size += sizeof(struct ethtool_rxnfc);
  		convert_in = true;
44c02a2c3   Al Viro   dev_ioctl(): move...
2978
  		rxnfc = compat_alloc_user_space(buf_size);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2979
2980
  		break;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
2981
  	if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
2982
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
2983
  	ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
7a229387d   Arnd Bergmann   net: copy socket ...
2984

3a7da39d1   Ben Hutchings   ethtool: Compat h...
2985
  	if (convert_in) {
127fe533a   Alexander Duyck   v3 ethtool: add n...
2986
  		/* We expect there to be holes between fs.m_ext and
3a7da39d1   Ben Hutchings   ethtool: Compat h...
2987
2988
  		 * fs.ring_cookie and at the end of fs, but nowhere else.
  		 */
127fe533a   Alexander Duyck   v3 ethtool: add n...
2989
2990
2991
2992
  		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...
2993
2994
2995
2996
2997
2998
2999
  		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...
3000
3001
  				 (void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3002
3003
  		    copy_in_user(&rxnfc->fs.ring_cookie,
  				 &compat_rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
3004
  				 (void __user *)(&rxnfc->fs.location + 1) -
b6168562c   Wenwen Wang   net: socket: fix ...
3005
3006
3007
3008
3009
3010
3011
3012
  				 (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...
3013
3014
  			return -EFAULT;
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
3015
  	ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3016
3017
3018
3019
3020
  	if (ret)
  		return ret;
  
  	if (convert_out) {
  		if (copy_in_user(compat_rxnfc, rxnfc,
954b12445   Stephen Hemminger   ethtool: fix spar...
3021
3022
  				 (const void __user *)(&rxnfc->fs.m_ext + 1) -
  				 (const void __user *)rxnfc) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3023
3024
  		    copy_in_user(&compat_rxnfc->fs.ring_cookie,
  				 &rxnfc->fs.ring_cookie,
954b12445   Stephen Hemminger   ethtool: fix spar...
3025
3026
  				 (const void __user *)(&rxnfc->fs.location + 1) -
  				 (const void __user *)&rxnfc->fs.ring_cookie) ||
3a7da39d1   Ben Hutchings   ethtool: Compat h...
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
  		    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 ...
3052
  }
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3053
3054
  static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
  {
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3055
  	compat_uptr_t uptr32;
44c02a2c3   Al Viro   dev_ioctl(): move...
3056
3057
3058
  	struct ifreq ifr;
  	void __user *saved;
  	int err;
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3059

44c02a2c3   Al Viro   dev_ioctl(): move...
3060
  	if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3061
3062
3063
3064
  		return -EFAULT;
  
  	if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3065
3066
  	saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc;
  	ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32);
7a229387d   Arnd Bergmann   net: copy socket ...
3067

44c02a2c3   Al Viro   dev_ioctl(): move...
3068
3069
3070
3071
3072
  	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...
3073
  	}
44c02a2c3   Al Viro   dev_ioctl(): move...
3074
  	return err;
7a229387d   Arnd Bergmann   net: copy socket ...
3075
  }
590d4693f   Ben Hutchings   net/compat: Merge...
3076
3077
  /* 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...
3078
  				 struct compat_ifreq __user *u_ifreq32)
7a229387d   Arnd Bergmann   net: copy socket ...
3079
  {
44c02a2c3   Al Viro   dev_ioctl(): move...
3080
  	struct ifreq ifreq;
7a229387d   Arnd Bergmann   net: copy socket ...
3081
  	u32 data32;
44c02a2c3   Al Viro   dev_ioctl(): move...
3082
  	if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ))
7a229387d   Arnd Bergmann   net: copy socket ...
3083
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3084
  	if (get_user(data32, &u_ifreq32->ifr_data))
7a229387d   Arnd Bergmann   net: copy socket ...
3085
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3086
  	ifreq.ifr_data = compat_ptr(data32);
7a229387d   Arnd Bergmann   net: copy socket ...
3087

44c02a2c3   Al Viro   dev_ioctl(): move...
3088
  	return dev_ioctl(net, cmd, &ifreq, NULL);
7a229387d   Arnd Bergmann   net: copy socket ...
3089
  }
37ac39bdd   Johannes Berg   Revert "kill dev_...
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
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
  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 ...
3129
  		case SIOCGIFNAME:
37ac39bdd   Johannes Berg   Revert "kill dev_...
3130
3131
3132
3133
3134
3135
3136
  			if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
  				err = -EFAULT;
  			break;
  		}
  	}
  	return err;
  }
a2116ed22   Arnd Bergmann   net/compat: fix d...
3137
3138
3139
3140
3141
  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...
3142
3143
3144
3145
  	int err;
  
  	uifmap32 = &uifr32->ifr_ifru.ifru_map;
  	err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3146
3147
3148
3149
3150
3151
  	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...
3152
3153
  	if (err)
  		return -EFAULT;
44c02a2c3   Al Viro   dev_ioctl(): move...
3154
  	err = dev_ioctl(net, cmd, &ifr, NULL);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3155
3156
3157
  
  	if (cmd == SIOCGIFMAP && !err) {
  		err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
3158
3159
3160
3161
3162
3163
  		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...
3164
3165
3166
3167
3168
  		if (err)
  			err = -EFAULT;
  	}
  	return err;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3169
3170
  /* 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...
3171
   * use compatible ioctls
7a229387d   Arnd Bergmann   net: copy socket ...
3172
   */
6b96018b2   Arnd Bergmann   compat: move sock...
3173
  static int old_bridge_ioctl(compat_ulong_t __user *argp)
7a229387d   Arnd Bergmann   net: copy socket ...
3174
  {
6b96018b2   Arnd Bergmann   compat: move sock...
3175
  	compat_ulong_t tmp;
7a229387d   Arnd Bergmann   net: copy socket ...
3176

6b96018b2   Arnd Bergmann   compat: move sock...
3177
  	if (get_user(tmp, argp))
7a229387d   Arnd Bergmann   net: copy socket ...
3178
3179
3180
3181
3182
  		return -EFAULT;
  	if (tmp == BRCTL_GET_VERSION)
  		return BRCTL_VERSION + 1;
  	return -EINVAL;
  }
6b96018b2   Arnd Bergmann   compat: move sock...
3183
3184
3185
3186
3187
3188
  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 ...
3189

6b96018b2   Arnd Bergmann   compat: move sock...
3190
  	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
590d4693f   Ben Hutchings   net/compat: Merge...
3191
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3192
3193
3194
3195
3196
  
  	switch (cmd) {
  	case SIOCSIFBR:
  	case SIOCGIFBR:
  		return old_bridge_ioctl(argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3197
  	case SIOCGIFCONF:
36fd633ec   Al Viro   net: separate SIO...
3198
  		return compat_dev_ifconf(net, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3199
3200
  	case SIOCETHTOOL:
  		return ethtool_ioctl(net, argp);
7a50a240c   Arnd Bergmann   net/compat_ioctl:...
3201
3202
  	case SIOCWANDEV:
  		return compat_siocwandev(net, argp);
a2116ed22   Arnd Bergmann   net/compat: fix d...
3203
3204
3205
  	case SIOCGIFMAP:
  	case SIOCSIFMAP:
  		return compat_sioc_ifmap(net, cmd, argp);
0768e1707   Arnd Bergmann   net: socket: impl...
3206
3207
  	case SIOCGSTAMP_OLD:
  	case SIOCGSTAMPNS_OLD:
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
3208
3209
  		if (!sock->ops->gettstamp)
  			return -ENOIOCTLCMD;
0768e1707   Arnd Bergmann   net: socket: impl...
3210
  		return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
3211
  					    !COMPAT_USE_64BIT_TIME);
590d4693f   Ben Hutchings   net/compat: Merge...
3212
3213
  	case SIOCBONDSLAVEINFOQUERY:
  	case SIOCBONDINFOQUERY:
a2116ed22   Arnd Bergmann   net/compat: fix d...
3214
  	case SIOCSHWTSTAMP:
fd468c74b   Ben Hutchings   net_tstamp: Add S...
3215
  	case SIOCGHWTSTAMP:
590d4693f   Ben Hutchings   net/compat: Merge...
3216
  		return compat_ifr_data_ioctl(net, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
  
  	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...
3228
  	case SIOCGSKNS:
0768e1707   Arnd Bergmann   net: socket: impl...
3229
3230
  	case SIOCGSTAMP_NEW:
  	case SIOCGSTAMPNS_NEW:
6b96018b2   Arnd Bergmann   compat: move sock...
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
  		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...
3246
3247
3248
  	case SIOCGIFADDR:
  	case SIOCSIFADDR:
  	case SIOCSIFHWBROADCAST:
6b96018b2   Arnd Bergmann   compat: move sock...
3249
  	case SIOCDIFADDR:
6b96018b2   Arnd Bergmann   compat: move sock...
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
  	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 ...
3262
  	case SIOCGIFNAME:
9177efd39   Arnd Bergmann   net, compat_ioctl...
3263
3264
3265
3266
  	case SIOCSIFNAME:
  	case SIOCGMIIPHY:
  	case SIOCGMIIREG:
  	case SIOCSMIIREG:
f92d4fc95   Al Viro   kill bond_ioctl()
3267
3268
3269
3270
  	case SIOCBONDENSLAVE:
  	case SIOCBONDRELEASE:
  	case SIOCBONDSETHWADDR:
  	case SIOCBONDCHANGEACTIVE:
37ac39bdd   Johannes Berg   Revert "kill dev_...
3271
  		return compat_ifreq_ioctl(net, sock, cmd, argp);
6b96018b2   Arnd Bergmann   compat: move sock...
3272
3273
3274
  	case SIOCSARP:
  	case SIOCGARP:
  	case SIOCDARP:
c7dc504e2   Arnd Bergmann   compat_ioctl: mov...
3275
  	case SIOCOUTQ:
9d7bf41fa   Arnd Bergmann   compat_ioctl: han...
3276
  	case SIOCOUTQNSD:
6b96018b2   Arnd Bergmann   compat: move sock...
3277
  	case SIOCATMARK:
63ff03ab7   Johannes Berg   Revert "socket: f...
3278
  		return sock_do_ioctl(net, sock, cmd, arg);
9177efd39   Arnd Bergmann   net, compat_ioctl...
3279
  	}
6b96018b2   Arnd Bergmann   compat: move sock...
3280
3281
  	return -ENOIOCTLCMD;
  }
7a229387d   Arnd Bergmann   net: copy socket ...
3282

95c961747   Eric Dumazet   net: cleanup unsi...
3283
  static long compat_sock_ioctl(struct file *file, unsigned int cmd,
89bddce58   Stephen Hemminger   [NET] socket: cod...
3284
  			      unsigned long arg)
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3285
3286
3287
  {
  	struct socket *sock = file->private_data;
  	int ret = -ENOIOCTLCMD;
87de87d5e   David S. Miller   wext: Dispatch an...
3288
3289
3290
3291
3292
  	struct sock *sk;
  	struct net *net;
  
  	sk = sock->sk;
  	net = sock_net(sk);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3293
3294
3295
  
  	if (sock->ops->compat_ioctl)
  		ret = sock->ops->compat_ioctl(sock, cmd, arg);
87de87d5e   David S. Miller   wext: Dispatch an...
3296
3297
3298
  	if (ret == -ENOIOCTLCMD &&
  	    (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
  		ret = compat_wext_handle_ioctl(net, cmd, arg);
6b96018b2   Arnd Bergmann   compat: move sock...
3299
3300
  	if (ret == -ENOIOCTLCMD)
  		ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
89bbfc95d   Shaun Pereira   [NET]: allow 32 b...
3301
3302
3303
  	return ret;
  }
  #endif
8a3c245c0   Pedro Tammela   net: add document...
3304
3305
3306
3307
3308
3309
3310
3311
  /**
   *	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 ...
3312
3313
3314
3315
  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
  {
  	return sock->ops->bind(sock, addr, addrlen);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3316
  EXPORT_SYMBOL(kernel_bind);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3317

8a3c245c0   Pedro Tammela   net: add document...
3318
3319
3320
3321
3322
3323
3324
  /**
   *	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 ...
3325
3326
3327
3328
  int kernel_listen(struct socket *sock, int backlog)
  {
  	return sock->ops->listen(sock, backlog);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3329
  EXPORT_SYMBOL(kernel_listen);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3330

8a3c245c0   Pedro Tammela   net: add document...
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
  /**
   *	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 ...
3341
3342
3343
3344
3345
3346
3347
3348
3349
  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 ...
3350
  	err = sock->ops->accept(sock, *newsock, flags, true);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3351
3352
  	if (err < 0) {
  		sock_release(*newsock);
fa8705b00   Tony Battersby   [NET]: sanitize k...
3353
  		*newsock = NULL;
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3354
3355
3356
3357
  		goto done;
  	}
  
  	(*newsock)->ops = sock->ops;
1b08534e5   Wei Yongjun   net: Fix module r...
3358
  	__module_get((*newsock)->ops->owner);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3359
3360
3361
3362
  
  done:
  	return err;
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3363
  EXPORT_SYMBOL(kernel_accept);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3364

8a3c245c0   Pedro Tammela   net: add document...
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
  /**
   *	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 ...
3377
  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
4768fbcbc   YOSHIFUJI Hideaki   [NET]: Fix whites...
3378
  		   int flags)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3379
3380
3381
  {
  	return sock->ops->connect(sock, addr, addrlen, flags);
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3382
  EXPORT_SYMBOL(kernel_connect);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3383

8a3c245c0   Pedro Tammela   net: add document...
3384
3385
3386
3387
3388
3389
3390
3391
  /**
   *	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...
3392
  int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3393
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3394
  	return sock->ops->getname(sock, addr, 0);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3395
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3396
  EXPORT_SYMBOL(kernel_getsockname);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3397

8a3c245c0   Pedro Tammela   net: add document...
3398
3399
3400
3401
3402
3403
3404
3405
  /**
   *	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...
3406
  int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3407
  {
9b2c45d47   Denys Vlasenko   net: make getname...
3408
  	return sock->ops->getname(sock, addr, 1);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3409
  }
c6d409cfd   Eric Dumazet   From abbffa2aa9bd...
3410
  EXPORT_SYMBOL(kernel_getpeername);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3411

8a3c245c0   Pedro Tammela   net: add document...
3412
  /**
8a3c245c0   Pedro Tammela   net: add document...
3413
3414
3415
3416
3417
3418
3419
3420
3421
   *	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 ...
3422
3423
3424
3425
3426
3427
3428
3429
  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...
3430
  EXPORT_SYMBOL(kernel_sendpage);
ac5a488ef   Sridhar Samudrala   [NET]: Round out ...
3431

8a3c245c0   Pedro Tammela   net: add document...
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
  /**
   *	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...
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
  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...
3455
3456
3457
3458
3459
3460
3461
  /**
   *	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...
3462
3463
3464
3465
  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...
3466
  EXPORT_SYMBOL(kernel_sock_shutdown);
113c30759   R. Parameswaran   New kernel functi...
3467

8a3c245c0   Pedro Tammela   net: add document...
3468
3469
3470
3471
3472
3473
3474
3475
  /**
   *	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...
3476
   */
8a3c245c0   Pedro Tammela   net: add document...
3477

113c30759   R. Parameswaran   New kernel functi...
3478
3479
3480
3481
3482
  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...
3483
3484
3485
3486
3487
3488
3489
  #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...
3490
3491
3492
3493
3494
  	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...
3495
  						sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3496
3497
3498
3499
3500
3501
3502
3503
3504
  		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...
3505
  							  sock_owned_by_user(sk));
113c30759   R. Parameswaran   New kernel functi...
3506
3507
3508
3509
3510
3511
3512
3513
3514
  		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);