4617 lines · 112.8 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * 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. * * Authors:	Ross Biro *		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 *					code. The ACK stuff can wait and needs major *					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: */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/unaligned.h>#include <linux/capability.h>#include <linux/errno.h>#include <linux/errqueue.h>#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/sched/mm.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/udp.h>#include <linux/init.h>#include <linux/highmem.h>#include <linux/user_namespace.h>#include <linux/static_key.h>#include <linux/memcontrol.h>#include <linux/prefetch.h>#include <linux/compat.h>#include <linux/mroute.h>#include <linux/mroute6.h>#include <linux/icmpv6.h> #include <linux/uaccess.h> #include <linux/netdevice.h>#include <net/protocol.h>#include <linux/skbuff.h>#include <linux/skbuff_ref.h>#include <net/net_namespace.h>#include <net/request_sock.h>#include <net/sock.h>#include <net/proto_memory.h>#include <linux/net_tstamp.h>#include <net/xfrm.h>#include <linux/ipsec.h>#include <net/cls_cgroup.h>#include <net/netprio_cgroup.h>#include <linux/sock_diag.h> #include <linux/filter.h>#include <net/sock_reuseport.h>#include <net/bpf_sk_storage.h> #include <trace/events/sock.h> #include <net/tcp.h>#include <net/busy_poll.h>#include <net/phonet/phonet.h> #include <linux/ethtool.h> #include <uapi/linux/pidfd.h> #include "dev.h" static DEFINE_MUTEX(proto_list_mutex);static LIST_HEAD(proto_list); static void sock_def_write_space_wfree(struct sock *sk, int wmem_alloc);static void sock_def_write_space(struct sock *sk); /** * 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 * @cap: The global 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 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 * * Test to see if the opener of the socket had when the socket was created * 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); /* * Each address family might have different locking rules, so we have * one slock key per address family and separate keys for internal and * userspace sockets. */static struct lock_class_key af_family_keys[AF_MAX];static struct lock_class_key af_family_kern_keys[AF_MAX];static struct lock_class_key af_family_slock_keys[AF_MAX];static struct lock_class_key af_family_kern_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): */ #define _sock_locks(x)						  \  x "AF_UNSPEC",	x "AF_UNIX"     ,	x "AF_INET"     , \  x "AF_AX25"  ,	x "AF_IPX"      ,	x "AF_APPLETALK", \  x "AF_NETROM",	x "AF_BRIDGE"   ,	x "AF_ATMPVC"   , \  x "AF_X25"   ,	x "AF_INET6"    ,	x "AF_ROSE"     , \  x "AF_DECnet",	x "AF_NETBEUI"  ,	x "AF_SECURITY" , \  x "AF_KEY"   ,	x "AF_NETLINK"  ,	x "AF_PACKET"   , \  x "AF_ASH"   ,	x "AF_ECONET"   ,	x "AF_ATMSVC"   , \  x "AF_RDS"   ,	x "AF_SNA"      ,	x "AF_IRDA"     , \  x "AF_PPPOX" ,	x "AF_WANPIPE"  ,	x "AF_LLC"      , \  x "27"       ,	x "28"          ,	x "AF_CAN"      , \  x "AF_TIPC"  ,	x "AF_BLUETOOTH",	x "IUCV"        , \  x "AF_RXRPC" ,	x "AF_ISDN"     ,	x "AF_PHONET"   , \  x "AF_IEEE802154",	x "AF_CAIF"	,	x "AF_ALG"      , \  x "AF_NFC"   ,	x "AF_VSOCK"    ,	x "AF_KCM"      , \  x "AF_QIPCRTR",	x "AF_SMC"	,	x "AF_XDP"	, \  x "AF_MCTP"  , \  x "AF_MAX" static const char *const af_family_key_strings[AF_MAX+1] = {	_sock_locks("sk_lock-")};static const char *const af_family_slock_key_strings[AF_MAX+1] = {	_sock_locks("slock-")};static const char *const af_family_clock_key_strings[AF_MAX+1] = {	_sock_locks("clock-")}; static const char *const af_family_kern_key_strings[AF_MAX+1] = {	_sock_locks("k-sk_lock-")};static const char *const af_family_kern_slock_key_strings[AF_MAX+1] = {	_sock_locks("k-slock-")};static const char *const af_family_kern_clock_key_strings[AF_MAX+1] = {	_sock_locks("k-clock-")};static const char *const af_family_rlock_key_strings[AF_MAX+1] = {	_sock_locks("rlock-")};static const char *const af_family_wlock_key_strings[AF_MAX+1] = {	_sock_locks("wlock-")};static const char *const af_family_elock_key_strings[AF_MAX+1] = {	_sock_locks("elock-")}; /* * sk_callback_lock and sk queues 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];static struct lock_class_key af_rlock_keys[AF_MAX];static struct lock_class_key af_wlock_keys[AF_MAX];static struct lock_class_key af_elock_keys[AF_MAX];static struct lock_class_key af_kern_callback_keys[AF_MAX]; /* Run time adjustable parameters. */__u32 sysctl_wmem_max __read_mostly = 4 << 20;EXPORT_SYMBOL(sysctl_wmem_max);__u32 sysctl_rmem_max __read_mostly = 4 << 20;EXPORT_SYMBOL(sysctl_rmem_max);__u32 sysctl_wmem_default __read_mostly = SK_WMEM_DEFAULT;__u32 sysctl_rmem_default __read_mostly = SK_RMEM_DEFAULT; DEFINE_STATIC_KEY_FALSE(memalloc_socks_key);EXPORT_SYMBOL_GPL(memalloc_socks_key); /** * 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;	static_branch_inc(&memalloc_socks_key);}EXPORT_SYMBOL_GPL(sk_set_memalloc); void sk_clear_memalloc(struct sock *sk){	sock_reset_flag(sk, SOCK_MEMALLOC);	sk->sk_allocation &= ~__GFP_MEMALLOC;	static_branch_dec(&memalloc_socks_key); 	/*	 * SOCK_MEMALLOC is allowed to ignore rmem limits to ensure forward	 * 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.	 */	sk_mem_reclaim(sk);}EXPORT_SYMBOL_GPL(sk_clear_memalloc); int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb){	int ret;	unsigned int noreclaim_flag; 	/* these should have been dropped before queueing */	BUG_ON(!sock_flag(sk, SOCK_MEMALLOC)); 	noreclaim_flag = memalloc_noreclaim_save();	ret = INDIRECT_CALL_INET(sk->sk_backlog_rcv,				 tcp_v6_do_rcv,				 tcp_v4_do_rcv,				 sk, skb);	memalloc_noreclaim_restore(noreclaim_flag); 	return ret;}EXPORT_SYMBOL(__sk_backlog_rcv); void sk_error_report(struct sock *sk){	sk->sk_error_report(sk); 	switch (sk->sk_family) {	case AF_INET:		fallthrough;	case AF_INET6:		trace_inet_sk_error_report(sk);		break;	default:		break;	}}EXPORT_SYMBOL(sk_error_report); int sock_get_timeout(long timeo, void *optval, bool old_timeval){	struct __kernel_sock_timeval tv; 	if (timeo == MAX_SCHEDULE_TIMEOUT) {		tv.tv_sec = 0;		tv.tv_usec = 0;	} else {		tv.tv_sec = timeo / HZ;		tv.tv_usec = ((timeo % HZ) * USEC_PER_SEC) / HZ;	} 	if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {		struct old_timeval32 tv32 = { tv.tv_sec, tv.tv_usec };		*(struct old_timeval32 *)optval = tv32;		return sizeof(tv32);	} 	if (old_timeval) {		struct __kernel_old_timeval old_tv;		old_tv.tv_sec = tv.tv_sec;		old_tv.tv_usec = tv.tv_usec;		*(struct __kernel_old_timeval *)optval = old_tv;		return sizeof(old_tv);	} 	*(struct __kernel_sock_timeval *)optval = tv;	return sizeof(tv);}EXPORT_SYMBOL(sock_get_timeout); int sock_copy_user_timeval(struct __kernel_sock_timeval *tv,			   sockptr_t optval, int optlen, bool old_timeval){	if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {		struct old_timeval32 tv32; 		if (optlen < sizeof(tv32))			return -EINVAL; 		if (copy_from_sockptr(&tv32, optval, sizeof(tv32)))			return -EFAULT;		tv->tv_sec = tv32.tv_sec;		tv->tv_usec = tv32.tv_usec;	} else if (old_timeval) {		struct __kernel_old_timeval old_tv; 		if (optlen < sizeof(old_tv))			return -EINVAL;		if (copy_from_sockptr(&old_tv, optval, sizeof(old_tv)))			return -EFAULT;		tv->tv_sec = old_tv.tv_sec;		tv->tv_usec = old_tv.tv_usec;	} else {		if (optlen < sizeof(*tv))			return -EINVAL;		if (copy_from_sockptr(tv, optval, sizeof(*tv)))			return -EFAULT;	} 	return 0;}EXPORT_SYMBOL(sock_copy_user_timeval); static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,			    bool old_timeval){	struct __kernel_sock_timeval tv;	int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval);	long val; 	if (err)		return err; 	if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)		return -EDOM; 	if (tv.tv_sec < 0) {		static int warned __read_mostly; 		WRITE_ONCE(*timeo_p, 0);		if (warned < 10 && net_ratelimit()) {			warned++;			pr_info("%s: `%s' (pid %d) tries to set negative timeout\n",				__func__, current->comm, task_pid_nr(current));		}		return 0;	}	val = MAX_SCHEDULE_TIMEOUT;	if ((tv.tv_sec || tv.tv_usec) &&	    (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)))		val = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec,						    USEC_PER_SEC / HZ);	WRITE_ONCE(*timeo_p, val);	return 0;} static bool sk_set_prio_allowed(const struct sock *sk, int val){	return ((val >= TC_PRIO_BESTEFFORT && val <= TC_PRIO_INTERACTIVE) ||		sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||		sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN));} static bool sock_needs_netstamp(const struct sock *sk){	switch (sk->sk_family) {	case AF_UNSPEC:	case AF_UNIX:		return false;	default:		return true;	}} static void sock_disable_timestamp(struct sock *sk, unsigned long flags){	if (sk->sk_flags & flags) {		sk->sk_flags &= ~flags;		if (sock_needs_netstamp(sk) &&		    !(sk->sk_flags & SK_FLAGS_TIMESTAMP))			net_disable_timestamp();	}}  int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb){	unsigned long flags;	struct sk_buff_head *list = &sk->sk_receive_queue; 	if (atomic_read(&sk->sk_rmem_alloc) >= READ_ONCE(sk->sk_rcvbuf)) {		sk_drops_inc(sk);		trace_sock_rcvqueue_full(sk, skb);		return -ENOMEM;	} 	if (!sk_rmem_schedule(sk, skb, skb->truesize)) {		sk_drops_inc(sk);

Lines 1–500 of 4617.