sock.c 76.1 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		Generic socket support routines. Memory allocators, socket lock/release
 *		handler for protocols to use and generic option handler.
 *
 *
10
 * Authors:	Ross Biro
Linus Torvalds's avatar
Linus Torvalds committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Florian La Roche, <flla@stud.uni-sb.de>
 *		Alan Cox, <A.Cox@swansea.ac.uk>
 *
 * Fixes:
 *		Alan Cox	: 	Numerous verify_area() problems
 *		Alan Cox	:	Connecting on a connecting socket
 *					now returns an error for tcp.
 *		Alan Cox	:	sock->protocol is set correctly.
 *					and is not sometimes left as 0.
 *		Alan Cox	:	connect handles icmp errors on a
 *					connect properly. Unfortunately there
 *					is a restart syscall nasty there. I
 *					can't match BSD without hacking the C
 *					library. Ideas urgently sought!
 *		Alan Cox	:	Disallow bind() to addresses that are
 *					not ours - especially broadcast ones!!
 *		Alan Cox	:	Socket 1024 _IS_ ok for users. (fencepost)
 *		Alan Cox	:	sock_wfree/sock_rfree don't destroy sockets,
 *					instead they leave that for the DESTROY timer.
 *		Alan Cox	:	Clean up error flag in accept
 *		Alan Cox	:	TCP ack handling is buggy, the DESTROY timer
 *					was buggy. Put a remove_sock() in the handler
 *					for memory when we hit 0. Also altered the timer
35
 *					code. The ACK stuff can wait and needs major
Linus Torvalds's avatar
Linus Torvalds committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 *					TCP layer surgery.
 *		Alan Cox	:	Fixed TCP ack bug, removed remove sock
 *					and fixed timer/inet_bh race.
 *		Alan Cox	:	Added zapped flag for TCP
 *		Alan Cox	:	Move kfree_skb into skbuff.c and tidied up surplus code
 *		Alan Cox	:	for new sk_buff allocations wmalloc/rmalloc now call alloc_skb
 *		Alan Cox	:	kfree_s calls now are kfree_skbmem so we can track skb resources
 *		Alan Cox	:	Supports socket option broadcast now as does udp. Packet and raw need fixing.
 *		Alan Cox	:	Added RCVBUF,SNDBUF size setting. It suddenly occurred to me how easy it was so...
 *		Rick Sladkey	:	Relaxed UDP rules for matching packets.
 *		C.E.Hawkins	:	IFF_PROMISC/SIOCGHWADDR support
 *	Pauline Middelink	:	identd support
 *		Alan Cox	:	Fixed connect() taking signals I think.
 *		Alan Cox	:	SO_LINGER supported
 *		Alan Cox	:	Error reporting fixes
 *		Anonymous	:	inet_create tidied up (sk->reuse setting)
 *		Alan Cox	:	inet sockets don't set sk->type!
 *		Alan Cox	:	Split socket option code
 *		Alan Cox	:	Callbacks
 *		Alan Cox	:	Nagle flag for Charles & Johannes stuff
 *		Alex		:	Removed restriction on inet fioctl
 *		Alan Cox	:	Splitting INET from NET core
 *		Alan Cox	:	Fixed bogus SO_TYPE handling in getsockopt()
 *		Adam Caldwell	:	Missing return in SO_DONTROUTE/SO_DEBUG code
 *		Alan Cox	:	Split IP from generic code
 *		Alan Cox	:	New kfree_skbmem()
 *		Alan Cox	:	Make SO_DEBUG superuser only.
 *		Alan Cox	:	Allow anyone to clear SO_DEBUG
 *					(compatibility fix)
 *		Alan Cox	:	Added optimistic memory grabbing for AF_UNIX throughput.
 *		Alan Cox	:	Allocator for a socket is settable.
 *		Alan Cox	:	SO_ERROR includes soft errors.
 *		Alan Cox	:	Allow NULL arguments on some SO_ opts
 *		Alan Cox	: 	Generic socket allocation to make hooks
 *					easier (suggested by Craig Metz).
 *		Michael Pall	:	SO_ERROR returns positive errno again
 *              Steve Whitehouse:       Added default destructor to free
 *                                      protocol private data.
 *              Steve Whitehouse:       Added various other default routines
 *                                      common to several socket families.
 *              Chris Evans     :       Call suser() check last on F_SETOWN
 *		Jay Schulist	:	Added SO_ATTACH_FILTER and SO_DETACH_FILTER.
 *		Andi Kleen	:	Add sock_kmalloc()/sock_kfree_s()
 *		Andi Kleen	:	Fix write_space callback
 *		Chris Evans	:	Security fixes - signedness again
 *		Arnaldo C. Melo :       cleanups, use skb_queue_purge
 *
 * To Fix:
 *
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 */

Joe Perches's avatar
Joe Perches committed
92
93
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

94
#include <linux/capability.h>
Linus Torvalds's avatar
Linus Torvalds committed
95
#include <linux/errno.h>
96
#include <linux/errqueue.h>
Linus Torvalds's avatar
Linus Torvalds committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/tcp.h>
#include <linux/init.h>
115
#include <linux/highmem.h>
116
#include <linux/user_namespace.h>
117
#include <linux/static_key.h>
118
#include <linux/memcontrol.h>
119
#include <linux/prefetch.h>
Linus Torvalds's avatar
Linus Torvalds committed
120
121
122
123
124
125

#include <asm/uaccess.h>

#include <linux/netdevice.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
126
#include <net/net_namespace.h>
127
#include <net/request_sock.h>
Linus Torvalds's avatar
Linus Torvalds committed
128
#include <net/sock.h>
129
#include <linux/net_tstamp.h>
Linus Torvalds's avatar
Linus Torvalds committed
130
131
#include <net/xfrm.h>
#include <linux/ipsec.h>
132
#include <net/cls_cgroup.h>
133
#include <net/netprio_cgroup.h>
134
#include <linux/sock_diag.h>
Linus Torvalds's avatar
Linus Torvalds committed
135
136

#include <linux/filter.h>
137
#include <net/sock_reuseport.h>
Linus Torvalds's avatar
Linus Torvalds committed
138

139
140
#include <trace/events/sock.h>

Linus Torvalds's avatar
Linus Torvalds committed
141
142
143
144
#ifdef CONFIG_INET
#include <net/tcp.h>
#endif

145
#include <net/busy_poll.h>
146

147
static DEFINE_MUTEX(proto_list_mutex);
Glauber Costa's avatar
Glauber Costa committed
148
149
static LIST_HEAD(proto_list);

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
 * sk_ns_capable - General socket capability test
 * @sk: Socket to use a capability on or through
 * @user_ns: The user namespace of the capability to use
 * @cap: The capability to use
 *
 * Test to see if the opener of the socket had when the socket was
 * created and the current process has the capability @cap in the user
 * namespace @user_ns.
 */
bool sk_ns_capable(const struct sock *sk,
		   struct user_namespace *user_ns, int cap)
{
	return file_ns_capable(sk->sk_socket->file, user_ns, cap) &&
		ns_capable(user_ns, cap);
}
EXPORT_SYMBOL(sk_ns_capable);

/**
 * sk_capable - Socket global capability test
 * @sk: Socket to use a capability on or through
171
 * @cap: The global capability to use
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Test to see if the opener of the socket had when the socket was
 * created and the current process has the capability @cap in all user
 * namespaces.
 */
bool sk_capable(const struct sock *sk, int cap)
{
	return sk_ns_capable(sk, &init_user_ns, cap);
}
EXPORT_SYMBOL(sk_capable);

/**
 * sk_net_capable - Network namespace socket capability test
 * @sk: Socket to use a capability on or through
 * @cap: The capability to use
 *
188
 * Test to see if the opener of the socket had when the socket was created
189
190
191
192
193
194
195
196
197
 * and the current process has the capability @cap over the network namespace
 * the socket is a member of.
 */
bool sk_net_capable(const struct sock *sk, int cap)
{
	return sk_ns_capable(sk, sock_net(sk)->user_ns, cap);
}
EXPORT_SYMBOL(sk_net_capable);

198
199
200
201
/*
 * Each address family might have different locking rules, so we have
 * one slock key per address family:
 */
202
203
204
205
206
207
208
209
static struct lock_class_key af_family_keys[AF_MAX];
static struct lock_class_key af_family_slock_keys[AF_MAX];

/*
 * Make lock validator output more readable. (we pre-construct these
 * strings build-time, so that runtime initialization of socket
 * locks is fast):
 */
210
static const char *const af_family_key_strings[AF_MAX+1] = {
211
212
213
214
215
216
217
  "sk_lock-AF_UNSPEC", "sk_lock-AF_UNIX"     , "sk_lock-AF_INET"     ,
  "sk_lock-AF_AX25"  , "sk_lock-AF_IPX"      , "sk_lock-AF_APPLETALK",
  "sk_lock-AF_NETROM", "sk_lock-AF_BRIDGE"   , "sk_lock-AF_ATMPVC"   ,
  "sk_lock-AF_X25"   , "sk_lock-AF_INET6"    , "sk_lock-AF_ROSE"     ,
  "sk_lock-AF_DECnet", "sk_lock-AF_NETBEUI"  , "sk_lock-AF_SECURITY" ,
  "sk_lock-AF_KEY"   , "sk_lock-AF_NETLINK"  , "sk_lock-AF_PACKET"   ,
  "sk_lock-AF_ASH"   , "sk_lock-AF_ECONET"   , "sk_lock-AF_ATMSVC"   ,
Andy Grover's avatar
Andy Grover committed
218
  "sk_lock-AF_RDS"   , "sk_lock-AF_SNA"      , "sk_lock-AF_IRDA"     ,
219
  "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE"  , "sk_lock-AF_LLC"      ,
220
  "sk_lock-27"       , "sk_lock-28"          , "sk_lock-AF_CAN"      ,
221
  "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
222
  "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
223
  "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG"      ,
224
225
  "sk_lock-AF_NFC"   , "sk_lock-AF_VSOCK"    , "sk_lock-AF_KCM"      ,
  "sk_lock-AF_MAX"
226
};
227
static const char *const af_family_slock_key_strings[AF_MAX+1] = {
228
229
230
231
232
233
234
  "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
  "slock-AF_AX25"  , "slock-AF_IPX"      , "slock-AF_APPLETALK",
  "slock-AF_NETROM", "slock-AF_BRIDGE"   , "slock-AF_ATMPVC"   ,
  "slock-AF_X25"   , "slock-AF_INET6"    , "slock-AF_ROSE"     ,
  "slock-AF_DECnet", "slock-AF_NETBEUI"  , "slock-AF_SECURITY" ,
  "slock-AF_KEY"   , "slock-AF_NETLINK"  , "slock-AF_PACKET"   ,
  "slock-AF_ASH"   , "slock-AF_ECONET"   , "slock-AF_ATMSVC"   ,
Andy Grover's avatar
Andy Grover committed
235
  "slock-AF_RDS"   , "slock-AF_SNA"      , "slock-AF_IRDA"     ,
236
  "slock-AF_PPPOX" , "slock-AF_WANPIPE"  , "slock-AF_LLC"      ,
237
  "slock-27"       , "slock-28"          , "slock-AF_CAN"      ,
238
  "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
239
  "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
240
  "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG"      ,
241
242
  "slock-AF_NFC"   , "slock-AF_VSOCK"    ,"slock-AF_KCM"       ,
  "slock-AF_MAX"
243
};
244
static const char *const af_family_clock_key_strings[AF_MAX+1] = {
245
246
247
248
249
250
251
  "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
  "clock-AF_AX25"  , "clock-AF_IPX"      , "clock-AF_APPLETALK",
  "clock-AF_NETROM", "clock-AF_BRIDGE"   , "clock-AF_ATMPVC"   ,
  "clock-AF_X25"   , "clock-AF_INET6"    , "clock-AF_ROSE"     ,
  "clock-AF_DECnet", "clock-AF_NETBEUI"  , "clock-AF_SECURITY" ,
  "clock-AF_KEY"   , "clock-AF_NETLINK"  , "clock-AF_PACKET"   ,
  "clock-AF_ASH"   , "clock-AF_ECONET"   , "clock-AF_ATMSVC"   ,
Andy Grover's avatar
Andy Grover committed
252
  "clock-AF_RDS"   , "clock-AF_SNA"      , "clock-AF_IRDA"     ,
253
  "clock-AF_PPPOX" , "clock-AF_WANPIPE"  , "clock-AF_LLC"      ,
254
  "clock-27"       , "clock-28"          , "clock-AF_CAN"      ,
255
  "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
256
  "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
257
  "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG"      ,
258
259
  "clock-AF_NFC"   , "clock-AF_VSOCK"    , "clock-AF_KCM"      ,
  "clock-AF_MAX"
260
};
261
262
263
264
265
266
267

/*
 * sk_callback_lock locking rules are per-address-family,
 * so split the lock classes by using a per-AF key:
 */
static struct lock_class_key af_callback_keys[AF_MAX];

Linus Torvalds's avatar
Linus Torvalds committed
268
269
270
271
272
273
/* Take into consideration the size of the struct sk_buff overhead in the
 * determination of these values, since that is non-constant across
 * platforms.  This makes socket queueing behavior and performance
 * not depend upon such differences.
 */
#define _SK_MEM_PACKETS		256
Eric Dumazet's avatar
Eric Dumazet committed
274
#define _SK_MEM_OVERHEAD	SKB_TRUESIZE(256)
Linus Torvalds's avatar
Linus Torvalds committed
275
276
277
278
#define SK_WMEM_MAX		(_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)
#define SK_RMEM_MAX		(_SK_MEM_OVERHEAD * _SK_MEM_PACKETS)

/* Run time adjustable parameters. */
279
__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
280
EXPORT_SYMBOL(sysctl_wmem_max);
281
__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
282
EXPORT_SYMBOL(sysctl_rmem_max);
283
284
__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
Linus Torvalds's avatar
Linus Torvalds committed
285

Lucas De Marchi's avatar
Lucas De Marchi committed
286
/* Maximal space eaten by iovec or ancillary data plus some space */
287
int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512);
Eric Dumazet's avatar
Eric Dumazet committed
288
EXPORT_SYMBOL(sysctl_optmem_max);
Linus Torvalds's avatar
Linus Torvalds committed
289

290
291
int sysctl_tstamp_allow_data __read_mostly = 1;

292
293
294
struct static_key memalloc_socks = STATIC_KEY_INIT_FALSE;
EXPORT_SYMBOL_GPL(memalloc_socks);

295
296
297
298
299
300
301
302
303
304
305
306
/**
 * sk_set_memalloc - sets %SOCK_MEMALLOC
 * @sk: socket to set it on
 *
 * Set %SOCK_MEMALLOC on a socket for access to emergency reserves.
 * It's the responsibility of the admin to adjust min_free_kbytes
 * to meet the requirements
 */
void sk_set_memalloc(struct sock *sk)
{
	sock_set_flag(sk, SOCK_MEMALLOC);
	sk->sk_allocation |= __GFP_MEMALLOC;
307
	static_key_slow_inc(&memalloc_socks);
308
309
310
311
312
313
314
}
EXPORT_SYMBOL_GPL(sk_set_memalloc);

void sk_clear_memalloc(struct sock *sk)
{
	sock_reset_flag(sk, SOCK_MEMALLOC);
	sk->sk_allocation &= ~__GFP_MEMALLOC;
315
	static_key_slow_dec(&memalloc_socks);
316
317
318

	/*
	 * SOCK_MEMALLOC is allowed to ignore rmem limits to ensure forward
319
320
321
322
	 * progress of swapping. SOCK_MEMALLOC may be cleared while
	 * it has rmem allocations due to the last swapfile being deactivated
	 * but there is a risk that the socket is unusable due to exceeding
	 * the rmem limits. Reclaim the reserves and obey rmem limits again.
323
	 */
324
	sk_mem_reclaim(sk);
325
326
327
}
EXPORT_SYMBOL_GPL(sk_clear_memalloc);

328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
	int ret;
	unsigned long pflags = current->flags;

	/* these should have been dropped before queueing */
	BUG_ON(!sock_flag(sk, SOCK_MEMALLOC));

	current->flags |= PF_MEMALLOC;
	ret = sk->sk_backlog_rcv(sk, skb);
	tsk_restore_flags(current, pflags, PF_MEMALLOC);

	return ret;
}
EXPORT_SYMBOL(__sk_backlog_rcv);

Linus Torvalds's avatar
Linus Torvalds committed
344
345
346
347
348
349
350
351
static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
{
	struct timeval tv;

	if (optlen < sizeof(tv))
		return -EINVAL;
	if (copy_from_user(&tv, optval, sizeof(tv)))
		return -EFAULT;
352
353
	if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
		return -EDOM;
Linus Torvalds's avatar
Linus Torvalds committed
354

355
	if (tv.tv_sec < 0) {
356
357
		static int warned __read_mostly;

358
		*timeo_p = 0;
359
		if (warned < 10 && net_ratelimit()) {
360
			warned++;
Joe Perches's avatar
Joe Perches committed
361
362
			pr_info("%s: `%s' (pid %d) tries to set negative timeout\n",
				__func__, current->comm, task_pid_nr(current));
363
		}
364
365
		return 0;
	}
Linus Torvalds's avatar
Linus Torvalds committed
366
367
368
369
370
371
372
373
374
375
376
377
	*timeo_p = MAX_SCHEDULE_TIMEOUT;
	if (tv.tv_sec == 0 && tv.tv_usec == 0)
		return 0;
	if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT/HZ - 1))
		*timeo_p = tv.tv_sec*HZ + (tv.tv_usec+(1000000/HZ-1))/(1000000/HZ);
	return 0;
}

static void sock_warn_obsolete_bsdism(const char *name)
{
	static int warned;
	static char warncomm[TASK_COMM_LEN];
378
379
	if (strcmp(warncomm, current->comm) && warned < 5) {
		strcpy(warncomm,  current->comm);
Joe Perches's avatar
Joe Perches committed
380
381
		pr_warn("process `%s' is using obsolete %s SO_BSDCOMPAT\n",
			warncomm, name);
Linus Torvalds's avatar
Linus Torvalds committed
382
383
384
385
		warned++;
	}
}

386
387
388
389
390
391
392
393
394
395
396
static bool sock_needs_netstamp(const struct sock *sk)
{
	switch (sk->sk_family) {
	case AF_UNSPEC:
	case AF_UNIX:
		return false;
	default:
		return true;
	}
}

397
static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
398
{
399
400
	if (sk->sk_flags & flags) {
		sk->sk_flags &= ~flags;
401
402
		if (sock_needs_netstamp(sk) &&
		    !(sk->sk_flags & SK_FLAGS_TIMESTAMP))
403
			net_disable_timestamp();
Linus Torvalds's avatar
Linus Torvalds committed
404
405
406
407
	}
}


408
int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
409
{
410
411
	unsigned long flags;
	struct sk_buff_head *list = &sk->sk_receive_queue;
412

Eric Dumazet's avatar
Eric Dumazet committed
413
	if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) {
Eric Dumazet's avatar
Eric Dumazet committed
414
		atomic_inc(&sk->sk_drops);
415
		trace_sock_rcvqueue_full(sk, skb);
Eric Dumazet's avatar
Eric Dumazet committed
416
		return -ENOMEM;
417
418
	}

419
	if (!sk_rmem_schedule(sk, skb, skb->truesize)) {
Eric Dumazet's avatar
Eric Dumazet committed
420
421
		atomic_inc(&sk->sk_drops);
		return -ENOBUFS;
422
423
	}

424
425
	skb->dev = NULL;
	skb_set_owner_r(skb, sk);
426

Eric Dumazet's avatar
Eric Dumazet committed
427
428
429
430
431
	/* we escape from rcu protected region, make sure we dont leak
	 * a norefcounted dst
	 */
	skb_dst_force(skb);

432
	spin_lock_irqsave(&list->lock, flags);
433
	sock_skb_set_dropcount(sk, skb);
434
435
	__skb_queue_tail(list, skb);
	spin_unlock_irqrestore(&list->lock, flags);
436
437

	if (!sock_flag(sk, SOCK_DEAD))
438
		sk->sk_data_ready(sk);
Eric Dumazet's avatar
Eric Dumazet committed
439
	return 0;
440
}
441
442
443
444
445
446
447
448
449
450
451
452
EXPORT_SYMBOL(__sock_queue_rcv_skb);

int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
	int err;

	err = sk_filter(sk, skb);
	if (err)
		return err;

	return __sock_queue_rcv_skb(sk, skb);
}
453
454
EXPORT_SYMBOL(sock_queue_rcv_skb);

455
456
int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
		     const int nested, unsigned int trim_cap)
457
458
459
{
	int rc = NET_RX_SUCCESS;

460
	if (sk_filter_trim_cap(sk, skb, trim_cap))
461
462
463
464
		goto discard_and_relse;

	skb->dev = NULL;

465
	if (sk_rcvqueues_full(sk, sk->sk_rcvbuf)) {
466
467
468
		atomic_inc(&sk->sk_drops);
		goto discard_and_relse;
	}
469
470
471
472
	if (nested)
		bh_lock_sock_nested(sk);
	else
		bh_lock_sock(sk);
473
474
475
476
477
478
	if (!sock_owned_by_user(sk)) {
		/*
		 * trylock + unlock semantics:
		 */
		mutex_acquire(&sk->sk_lock.dep_map, 0, 1, _RET_IP_);

479
		rc = sk_backlog_rcv(sk, skb);
480
481

		mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
482
	} else if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) {
Zhu Yi's avatar
Zhu Yi committed
483
484
485
486
487
		bh_unlock_sock(sk);
		atomic_inc(&sk->sk_drops);
		goto discard_and_relse;
	}

488
489
490
491
492
493
494
495
	bh_unlock_sock(sk);
out:
	sock_put(sk);
	return rc;
discard_and_relse:
	kfree_skb(skb);
	goto out;
}
496
EXPORT_SYMBOL(__sk_receive_skb);
497
498
499

struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
{
Eric Dumazet's avatar
Eric Dumazet committed
500
	struct dst_entry *dst = __sk_dst_get(sk);
501
502

	if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
503
		sk_tx_queue_clear(sk);
504
		RCU_INIT_POINTER(sk->sk_dst_cache, NULL);
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
		dst_release(dst);
		return NULL;
	}

	return dst;
}
EXPORT_SYMBOL(__sk_dst_check);

struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie)
{
	struct dst_entry *dst = sk_dst_get(sk);

	if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
		sk_dst_reset(sk);
		dst_release(dst);
		return NULL;
	}

	return dst;
}
EXPORT_SYMBOL(sk_dst_check);

527
528
static int sock_setbindtodevice(struct sock *sk, char __user *optval,
				int optlen)
529
530
531
{
	int ret = -ENOPROTOOPT;
#ifdef CONFIG_NETDEVICES
532
	struct net *net = sock_net(sk);
533
534
535
536
537
	char devname[IFNAMSIZ];
	int index;

	/* Sorry... */
	ret = -EPERM;
538
	if (!ns_capable(net->user_ns, CAP_NET_RAW))
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
		goto out;

	ret = -EINVAL;
	if (optlen < 0)
		goto out;

	/* Bind this socket to a particular device like "eth0",
	 * as specified in the passed interface name. If the
	 * name is "" or the option length is zero the socket
	 * is not bound.
	 */
	if (optlen > IFNAMSIZ - 1)
		optlen = IFNAMSIZ - 1;
	memset(devname, 0, sizeof(devname));

	ret = -EFAULT;
	if (copy_from_user(devname, optval, optlen))
		goto out;

558
559
	index = 0;
	if (devname[0] != '\0') {
560
		struct net_device *dev;
561

562
563
564
565
566
		rcu_read_lock();
		dev = dev_get_by_name_rcu(net, devname);
		if (dev)
			index = dev->ifindex;
		rcu_read_unlock();
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
		ret = -ENODEV;
		if (!dev)
			goto out;
	}

	lock_sock(sk);
	sk->sk_bound_dev_if = index;
	sk_dst_reset(sk);
	release_sock(sk);

	ret = 0;

out:
#endif

	return ret;
}

585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
static int sock_getbindtodevice(struct sock *sk, char __user *optval,
				int __user *optlen, int len)
{
	int ret = -ENOPROTOOPT;
#ifdef CONFIG_NETDEVICES
	struct net *net = sock_net(sk);
	char devname[IFNAMSIZ];

	if (sk->sk_bound_dev_if == 0) {
		len = 0;
		goto zero;
	}

	ret = -EINVAL;
	if (len < IFNAMSIZ)
		goto out;

602
603
	ret = netdev_get_name(net, devname, sk->sk_bound_dev_if);
	if (ret)
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
		goto out;

	len = strlen(devname) + 1;

	ret = -EFAULT;
	if (copy_to_user(optval, devname, len))
		goto out;

zero:
	ret = -EFAULT;
	if (put_user(len, optlen))
		goto out;

	ret = 0;

out:
#endif

	return ret;
}

625
626
627
628
629
630
631
632
static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
{
	if (valbool)
		sock_set_flag(sk, bit);
	else
		sock_reset_flag(sk, bit);
}

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
bool sk_mc_loop(struct sock *sk)
{
	if (dev_recursion_level())
		return false;
	if (!sk)
		return true;
	switch (sk->sk_family) {
	case AF_INET:
		return inet_sk(sk)->mc_loop;
#if IS_ENABLED(CONFIG_IPV6)
	case AF_INET6:
		return inet6_sk(sk)->mc_loop;
#endif
	}
	WARN_ON(1);
	return true;
}
EXPORT_SYMBOL(sk_mc_loop);

Linus Torvalds's avatar
Linus Torvalds committed
652
653
654
655
656
657
/*
 *	This is meant for all protocols to use and covers goings on
 *	at the socket level. Everything here is generic.
 */

int sock_setsockopt(struct socket *sock, int level, int optname,
658
		    char __user *optval, unsigned int optlen)
Linus Torvalds's avatar
Linus Torvalds committed
659
{
Eric Dumazet's avatar
Eric Dumazet committed
660
	struct sock *sk = sock->sk;
Linus Torvalds's avatar
Linus Torvalds committed
661
662
663
664
	int val;
	int valbool;
	struct linger ling;
	int ret = 0;
665

Linus Torvalds's avatar
Linus Torvalds committed
666
667
668
669
	/*
	 *	Options without arguments
	 */

670
	if (optname == SO_BINDTODEVICE)
671
		return sock_setbindtodevice(sk, optval, optlen);
672

673
674
	if (optlen < sizeof(int))
		return -EINVAL;
675

Linus Torvalds's avatar
Linus Torvalds committed
676
677
	if (get_user(val, (int __user *)optval))
		return -EFAULT;
678

Eric Dumazet's avatar
Eric Dumazet committed
679
	valbool = val ? 1 : 0;
Linus Torvalds's avatar
Linus Torvalds committed
680
681
682

	lock_sock(sk);

Eric Dumazet's avatar
Eric Dumazet committed
683
	switch (optname) {
684
	case SO_DEBUG:
Eric Dumazet's avatar
Eric Dumazet committed
685
		if (val && !capable(CAP_NET_ADMIN))
686
			ret = -EACCES;
Eric Dumazet's avatar
Eric Dumazet committed
687
		else
688
			sock_valbool_flag(sk, SOCK_DBG, valbool);
689
690
		break;
	case SO_REUSEADDR:
691
		sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
692
		break;
Tom Herbert's avatar
Tom Herbert committed
693
694
695
	case SO_REUSEPORT:
		sk->sk_reuseport = valbool;
		break;
696
	case SO_TYPE:
697
	case SO_PROTOCOL:
698
	case SO_DOMAIN:
699
700
701
702
	case SO_ERROR:
		ret = -ENOPROTOOPT;
		break;
	case SO_DONTROUTE:
703
		sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
704
705
706
707
708
709
		break;
	case SO_BROADCAST:
		sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
		break;
	case SO_SNDBUF:
		/* Don't error on this BSD doesn't and if you think
710
711
712
713
714
		 * about it this is right. Otherwise apps have to
		 * play 'guess the biggest size' games. RCVBUF/SNDBUF
		 * are treated in BSD as hints
		 */
		val = min_t(u32, val, sysctl_wmem_max);
715
set_sndbuf:
716
		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
717
718
		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
		/* Wake up sending tasks if we upped the value. */
719
720
		sk->sk_write_space(sk);
		break;
Linus Torvalds's avatar
Linus Torvalds committed
721

722
723
724
725
726
727
	case SO_SNDBUFFORCE:
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
			break;
		}
		goto set_sndbuf;
728

729
730
	case SO_RCVBUF:
		/* Don't error on this BSD doesn't and if you think
731
732
733
734
735
		 * about it this is right. Otherwise apps have to
		 * play 'guess the biggest size' games. RCVBUF/SNDBUF
		 * are treated in BSD as hints
		 */
		val = min_t(u32, val, sysctl_rmem_max);
736
set_rcvbuf:
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
		sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
		/*
		 * We double it on the way in to account for
		 * "struct sk_buff" etc. overhead.   Applications
		 * assume that the SO_RCVBUF setting they make will
		 * allow that much actual data to be received on that
		 * socket.
		 *
		 * Applications are unaware that "struct sk_buff" and
		 * other overheads allocate from the receive buffer
		 * during socket buffer allocation.
		 *
		 * And after considering the possible alternatives,
		 * returning the value we actually used in getsockopt
		 * is the most desirable behavior.
		 */
753
		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
754
755
756
757
758
		break;

	case SO_RCVBUFFORCE:
		if (!capable(CAP_NET_ADMIN)) {
			ret = -EPERM;
Linus Torvalds's avatar
Linus Torvalds committed
759
			break;
760
761
		}
		goto set_rcvbuf;
Linus Torvalds's avatar
Linus Torvalds committed
762

763
	case SO_KEEPALIVE:
Linus Torvalds's avatar
Linus Torvalds committed
764
#ifdef CONFIG_INET
765
766
		if (sk->sk_protocol == IPPROTO_TCP &&
		    sk->sk_type == SOCK_STREAM)
767
			tcp_set_keepalive(sk, valbool);
Linus Torvalds's avatar
Linus Torvalds committed
768
#endif
769
770
771
772
773
774
775
776
		sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
		break;

	case SO_OOBINLINE:
		sock_valbool_flag(sk, SOCK_URGINLINE, valbool);
		break;

	case SO_NO_CHECK:
777
		sk->sk_no_check_tx = valbool;
778
779
780
		break;

	case SO_PRIORITY:
781
782
		if ((val >= 0 && val <= 6) ||
		    ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
783
784
785
786
787
788
789
790
			sk->sk_priority = val;
		else
			ret = -EPERM;
		break;

	case SO_LINGER:
		if (optlen < sizeof(ling)) {
			ret = -EINVAL;	/* 1003.1g */
Linus Torvalds's avatar
Linus Torvalds committed
791
			break;
792
		}
Eric Dumazet's avatar
Eric Dumazet committed
793
		if (copy_from_user(&ling, optval, sizeof(ling))) {
794
			ret = -EFAULT;
Linus Torvalds's avatar
Linus Torvalds committed
795
			break;
796
797
798
799
		}
		if (!ling.l_onoff)
			sock_reset_flag(sk, SOCK_LINGER);
		else {
Linus Torvalds's avatar
Linus Torvalds committed
800
#if (BITS_PER_LONG == 32)
801
802
			if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
				sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
Linus Torvalds's avatar
Linus Torvalds committed
803
			else
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
#endif
				sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
			sock_set_flag(sk, SOCK_LINGER);
		}
		break;

	case SO_BSDCOMPAT:
		sock_warn_obsolete_bsdism("setsockopt");
		break;

	case SO_PASSCRED:
		if (valbool)
			set_bit(SOCK_PASSCRED, &sock->flags);
		else
			clear_bit(SOCK_PASSCRED, &sock->flags);
		break;

	case SO_TIMESTAMP:
822
	case SO_TIMESTAMPNS:
823
		if (valbool)  {
824
825
826
827
			if (optname == SO_TIMESTAMP)
				sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
			else
				sock_set_flag(sk, SOCK_RCVTSTAMPNS);
828
			sock_set_flag(sk, SOCK_RCVTSTAMP);
829
			sock_enable_timestamp(sk, SOCK_TIMESTAMP);
830
		} else {
831
			sock_reset_flag(sk, SOCK_RCVTSTAMP);
832
833
			sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
		}
834
835
		break;

836
837
	case SO_TIMESTAMPING:
		if (val & ~SOF_TIMESTAMPING_MASK) {
838
			ret = -EINVAL;
839
840
			break;
		}
841

842
		if (val & SOF_TIMESTAMPING_OPT_ID &&
843
		    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
844
845
			if (sk->sk_protocol == IPPROTO_TCP &&
			    sk->sk_type == SOCK_STREAM) {
846
847
				if ((1 << sk->sk_state) &
				    (TCPF_CLOSE | TCPF_LISTEN)) {
848
849
850
851
852
853
854
855
					ret = -EINVAL;
					break;
				}
				sk->sk_tskey = tcp_sk(sk)->snd_una;
			} else {
				sk->sk_tskey = 0;
			}
		}
856
		sk->sk_tsflags = val;
857
858
859
860
861
		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
			sock_enable_timestamp(sk,
					      SOCK_TIMESTAMPING_RX_SOFTWARE);
		else
			sock_disable_timestamp(sk,
862
					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
863
864
		break;

865
866
867
868
869
870
871
872
873
874
875
876
877
	case SO_RCVLOWAT:
		if (val < 0)
			val = INT_MAX;
		sk->sk_rcvlowat = val ? : 1;
		break;

	case SO_RCVTIMEO:
		ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen);
		break;

	case SO_SNDTIMEO:
		ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);
		break;
Linus Torvalds's avatar
Linus Torvalds committed
878

879
880
881
882
	case SO_ATTACH_FILTER:
		ret = -EINVAL;
		if (optlen == sizeof(struct sock_fprog)) {
			struct sock_fprog fprog;
Linus Torvalds's avatar
Linus Torvalds committed
883

884
885
			ret = -EFAULT;
			if (copy_from_user(&fprog, optval, sizeof(fprog)))
Linus Torvalds's avatar
Linus Torvalds committed
886
				break;
887
888
889
890
891

			ret = sk_attach_filter(&fprog, sk);
		}
		break;

892
893
894
895
896
897
898
899
900
901
902
903
904
	case SO_ATTACH_BPF:
		ret = -EINVAL;
		if (optlen == sizeof(u32)) {
			u32 ufd;

			ret = -EFAULT;
			if (copy_from_user(&ufd, optval, sizeof(ufd)))
				break;

			ret = sk_attach_bpf(ufd, sk);
		}
		break;

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
	case SO_ATTACH_REUSEPORT_CBPF:
		ret = -EINVAL;
		if (optlen == sizeof(struct sock_fprog)) {
			struct sock_fprog fprog;

			ret = -EFAULT;
			if (copy_from_user(&fprog, optval, sizeof(fprog)))
				break;

			ret = sk_reuseport_attach_filter(&fprog, sk);
		}
		break;

	case SO_ATTACH_REUSEPORT_EBPF:
		ret = -EINVAL;
		if (optlen == sizeof(u32)) {
			u32 ufd;

			ret = -EFAULT;
			if (copy_from_user(&ufd, optval, sizeof(ufd)))
				break;

			ret = sk_reuseport_attach_bpf(ufd, sk);
		}
		break;

931
	case SO_DETACH_FILTER:
932
		ret = sk_detach_filter(sk);
933
		break;
Linus Torvalds's avatar
Linus Torvalds committed
934

935
936
937
938
939
940
941
	case SO_LOCK_FILTER:
		if (sock_flag(sk, SOCK_FILTER_LOCKED) && !valbool)
			ret = -EPERM;
		else
			sock_valbool_flag(sk, SOCK_FILTER_LOCKED, valbool);
		break;

942
943
944
945
946
947
	case SO_PASSSEC:
		if (valbool)
			set_bit(SOCK_PASSSEC, &sock->flags);
		else
			clear_bit(SOCK_PASSSEC, &sock->flags);
		break;
948
	case SO_MARK:
949
		if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
950
			ret = -EPERM;
Eric Dumazet's avatar
Eric Dumazet committed
951
		else
952
953
			sk->sk_mark = val;
		break;
954

955
	case SO_RXQ_OVFL:
956
		sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
957
		break;
958
959
960
961
962

	case SO_WIFI_STATUS:
		sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
		break;

963
964
	case SO_PEEK_OFF:
		if (sock->ops->set_peek_off)
965
			ret = sock->ops->set_peek_off(sk, val);
966
967
968
		else
			ret = -EOPNOTSUPP;
		break;
969
970
971
972
973

	case SO_NOFCS:
		sock_valbool_flag(sk, SOCK_NOFCS, valbool);
		break;

974
975
976
977
	case SO_SELECT_ERR_QUEUE:
		sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool);
		break;

978
#ifdef CONFIG_NET_RX_BUSY_POLL
979
	case SO_BUSY_POLL:
980
981
982
983
984
985
986
987
988
989
990
		/* allow unprivileged users to decrease the value */
		if ((val > sk->sk_ll_usec) && !capable(CAP_NET_ADMIN))
			ret = -EPERM;
		else {
			if (val < 0)
				ret = -EINVAL;
			else
				sk->sk_ll_usec = val;
		}
		break;
#endif
991
992
993
994
995
996
997

	case SO_MAX_PACING_RATE:
		sk->sk_max_pacing_rate = val;
		sk->sk_pacing_rate = min(sk->sk_pacing_rate,
					 sk->sk_max_pacing_rate);
		break;

998
999
1000
1001
	case SO_INCOMING_CPU:
		sk->sk_incoming_cpu = val;
		break;

1002
1003
1004
1005
	case SO_CNX_ADVICE:
		if (val == 1)
			dst_negative_advice(sk);
		break;
1006
1007
1008
	default:
		ret = -ENOPROTOOPT;
		break;
1009
	}
Linus Torvalds's avatar
Linus Torvalds committed
1010
1011
1012
	release_sock(sk);
	return ret;
}
Eric Dumazet's avatar
Eric Dumazet committed
1013
EXPORT_SYMBOL(sock_setsockopt);
Linus Torvalds's avatar
Linus Torvalds committed
1014
1015


stephen hemminger's avatar
stephen hemminger committed
1016
1017
static void cred_to_ucred(struct pid *pid, const struct cred *cred,
			  struct ucred *ucred)
1018
1019
1020
1021
1022
1023
{
	ucred->pid = pid_vnr(pid);
	ucred->uid = ucred->gid = -1;
	if (cred) {
		struct user_namespace *current_ns = current_user_ns();

1024
1025
		ucred->uid = from_kuid_munged(current_ns, cred->euid);
		ucred->gid = from_kgid_munged(current_ns, cred->egid);
1026
1027
1028
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
1029
1030
1031
1032
int sock_getsockopt(struct socket *sock, int level, int optname,
		    char __user *optval, int __user *optlen)
{
	struct sock *sk = sock->sk;
1033

1034
	union {
1035
1036
		int val;
		struct linger ling;
Linus Torvalds's avatar
Linus Torvalds committed
1037
1038
		struct timeval tm;
	} v;
1039

1040
	int lv = sizeof(int);
Linus Torvalds's avatar
Linus Torvalds committed
1041
	int len;
1042

1043
	if (get_user(len, optlen))
1044
		return -EFAULT;
1045
	if (len < 0)
Linus Torvalds's avatar
Linus Torvalds committed
1046
		return -EINVAL;
1047

1048
	memset(&v, 0, sizeof(v));
1049

Eric Dumazet's avatar
Eric Dumazet committed
1050
	switch (optname) {
1051
1052
1053
1054
1055
1056
1057
1058
1059
	case SO_DEBUG:
		v.val = sock_flag(sk, SOCK_DBG);
		break;

	case SO_DONTROUTE:
		v.val = sock_flag(sk, SOCK_LOCALROUTE);
		break;

	case SO_BROADCAST:
Eric Dumazet's avatar
Eric Dumazet committed
1060
		v.val = sock_flag(sk, SOCK_BROADCAST);
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
		break;

	case SO_SNDBUF:
		v.val = sk->sk_sndbuf;
		break;

	case SO_RCVBUF:
		v.val = sk->sk_rcvbuf;
		break;

	case SO_REUSEADDR:
		v.val = sk->sk_reuse;
		break;

Tom Herbert's avatar
Tom Herbert committed
1075
1076
1077
1078
	case SO_REUSEPORT:
		v.val = sk->sk_reuseport;
		break;

1079
	case SO_KEEPALIVE:
Eric Dumazet's avatar
Eric Dumazet committed
1080
		v.val = sock_flag(sk, SOCK_KEEPOPEN);
1081
1082
1083
1084
1085
1086
		break;

	case SO_TYPE:
		v.val = sk->sk_type;
		break;

1087
1088
1089
1090
	case SO_PROTOCOL:
		v.val = sk->sk_protocol;
		break;

1091
1092
1093
1094
	case SO_DOMAIN:
		v.val = sk->sk_family;
		break;

1095
1096
	case SO_ERROR:
		v.val = -sock_error(sk);
Eric Dumazet's avatar
Eric Dumazet committed
1097
		if (v.val == 0)
1098
1099
1100
1101
			v.val = xchg(&sk->sk_err_soft, 0);
		break;

	case SO_OOBINLINE:
Eric Dumazet's avatar
Eric Dumazet committed
1102
		v.val = sock_flag(sk, SOCK_URGINLINE);
1103
1104
1105
		break;

	case SO_NO_CHECK:
1106
		v.val = sk->sk_no_check_tx;
1107
1108
1109
1110
1111
1112
1113
1114
		break;

	case SO_PRIORITY:
		v.val = sk->sk_priority;
		break;

	case SO_LINGER:
		lv		= sizeof(v.ling);
Eric Dumazet's avatar
Eric Dumazet committed
1115
		v.ling.l_onoff	= sock_flag(sk, SOCK_LINGER);
1116
1117
1118
1119
1120
1121
1122
1123
		v.ling.l_linger	= sk->sk_lingertime / HZ;
		break;

	case SO_BSDCOMPAT:
		sock_warn_obsolete_bsdism("getsockopt");
		break;

	case SO_TIMESTAMP:
1124
1125
1126
1127
1128
1129
		v.val = sock_flag(sk, SOCK_RCVTSTAMP) &&
				!sock_flag(sk, SOCK_RCVTSTAMPNS);
		break;

	case SO_TIMESTAMPNS:
		v.val = sock_flag(sk, SOCK_RCVTSTAMPNS);
1130
1131
		break;

1132
	case SO_TIMESTAMPING:
1133
		v.val = sk->sk_tsflags;
1134
1135
		break;

1136
	case SO_RCVTIMEO:
Eric Dumazet's avatar
Eric Dumazet committed
1137
		lv = sizeof(struct timeval);
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
		if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) {
			v.tm.tv_sec = 0;
			v.tm.tv_usec = 0;
		} else {
			v.tm.tv_sec = sk->sk_rcvtimeo / HZ;
			v.tm.tv_usec = ((sk->sk_rcvtimeo % HZ) * 1000000) / HZ;
		}
		break;

	case SO_SNDTIMEO:
Eric Dumazet's avatar
Eric Dumazet committed
1148
		lv = sizeof(struct timeval);
1149
1150
1151
1152
1153
1154
1155
1156
		if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) {
			v.tm.tv_sec = 0;
			v.tm.tv_usec = 0;
		} else {
			v.tm.tv_sec = sk->sk_sndtimeo / HZ;
			v.tm.tv_usec = ((sk->sk_sndtimeo % HZ) * 1000000) / HZ;
		}
		break;
Linus Torvalds's avatar
Linus Torvalds committed
1157

1158
1159
1160
	case SO_RCVLOWAT:
		v.val = sk->sk_rcvlowat;
		break;
Linus Torvalds's avatar
Linus Torvalds committed
1161

1162
	case SO_SNDLOWAT:
Eric Dumazet's avatar
Eric Dumazet committed
1163
		v.val = 1;
1164
		break;
Linus Torvalds's avatar
Linus Torvalds committed
1165

1166
	case SO_PASSCRED:
1167
		v.val = !!test_bit(SOCK_PASSCRED, &sock->flags);
1168
		break;
Linus Torvalds's avatar
Linus Torvalds committed
1169

1170
	case SO_PEERCRED:
1171
1172
1173
1174
1175
1176
	{
		struct ucred peercred;
		if (len > sizeof(peercred))
			len = sizeof(peercred);
		cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred);
		if (copy_to_user(optval, &peercred, len))
1177
1178
			return -EFAULT;
		goto lenout;
1179
	}
Linus Torvalds's avatar
Linus Torvalds committed
1180

1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
	case SO_PEERNAME:
	{
		char address[128];

		if (sock->ops->getname(sock, (struct sockaddr *)address, &lv, 2))
			return -ENOTCONN;
		if (lv < len)
			return -EINVAL;
		if (copy_to_user(optval, address, len))
			return -EFAULT;
		goto lenout;
	}
Linus Torvalds's avatar
Linus Torvalds committed
1193

1194
1195
1196
1197
1198
1199
	/* Dubious BSD thing... Probably nobody even uses it, but
	 * the UNIX standard wants it for whatever reason... -DaveM
	 */
	case SO_ACCEPTCONN:
		v.val = sk->sk_state == TCP_LISTEN;
		break;
Linus Torvalds's avatar
Linus Torvalds committed
1200

1201
	case SO_PASSSEC:
1202
		v.val = !!test_bit(SOCK_PASSSEC, &sock->flags);
1203
		break;
1204

1205
1206
	case SO_PEERSEC:
		return security_socket_getpeersec_stream(sock, optval, optlen, len);
Linus Torvalds's avatar
Linus Torvalds committed
1207

1208
1209
1210
1211
	case SO_MARK:
		v.val = sk->sk_mark;
		break;

1212
	case SO_RXQ_OVFL:
Eric Dumazet's avatar
Eric Dumazet committed
1213
		v.val = sock_flag(sk, SOCK_RXQ_OVFL);
1214
1215
		break;

1216
	case SO_WIFI_STATUS:
Eric Dumazet's avatar
Eric Dumazet committed
1217
		v.val = sock_flag(sk, SOCK_WIFI_STATUS);
1218
1219
		break;

1220
1221
1222
1223
1224
1225
	case SO_PEEK_OFF:
		if (!sock->ops->set_peek_off)
			return -EOPNOTSUPP;

		v.val = sk->sk_peek_off;
		break;
1226
	case SO_NOFCS:
Eric Dumazet's avatar
Eric Dumazet committed
1227
		v.val = sock_flag(sk, SOCK_NOFCS);
1228
		break;
1229

1230
	case SO_BINDTODEVICE:
1231
1232
		return sock_getbindtodevice(sk, optval, optlen, len);

1233
1234
1235
1236
1237
1238
	case SO_GET_FILTER:
		len = sk_get_filter(sk, (struct sock_filter __user *)optval, len);
		if (len < 0)
			return len;

		goto lenout;
1239

1240
1241
1242
1243
	case SO_LOCK_FILTER:
		v.val = sock_flag(sk, SOCK_FILTER_LOCKED);
		break;

1244
1245
1246
1247
	case SO_BPF_EXTENSIONS:
		v.val = bpf_tell_extensions();
		break;

1248
1249
1250
1251
	case SO_SELECT_ERR_QUEUE:
		v.val = sock_flag(sk, SOCK_SELECT_ERR_QUEUE);
		break;

1252
#ifdef CONFIG_NET_RX_BUSY_POLL
1253
	case SO_BUSY_POLL:
1254
1255
1256
1257
		v.val = sk->sk_ll_usec;
		break;
#endif

1258
1259
1260
1261
	case SO_MAX_PACING_RATE:
		v.val = sk->sk_max_pacing_rate;
		break;

Eric Dumazet's avatar
Eric Dumazet committed
1262
1263
1264
1265
	case SO_INCOMING_CPU:
		v.val = sk->sk_incoming_cpu;
		break;

1266
	default:
1267
1268
1269
		/* We implement the SO_SNDLOWAT etc to not be settable
		 * (1003.1g 7).
		 */
1270
		return -ENOPROTOOPT;
Linus Torvalds's avatar
Linus Torvalds committed
1271
	}
1272

Linus Torvalds's avatar
Linus Torvalds committed
1273
1274
1275
1276
1277
	if (len > lv)
		len = lv;
	if (copy_to_user(optval, &v, len))
		return -EFAULT;
lenout:
1278
1279
1280
	if (put_user(len, optlen))
		return -EFAULT;
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1281
1282
}

1283
1284
1285
1286
1287
/*
 * Initialize an sk_lock.
 *
 * (We also register the sk_lock with the lock validator.)
 */
Dave Jones's avatar
Dave Jones committed
1288
static inline void sock_lock_init(struct sock *sk)