#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched/signal.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/socket.h>
#include <linux/un.h>
#include <linux/fcntl.h>
#include <linux/filter.h>
#include <linux/termios.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/mount.h>
#include <net/checksum.h>
#include <linux/security.h>
#include <linux/splice.h>
#include <linux/freezer.h>
#include <linux/file.h>
#include <linux/btf_ids.h>
#include <linux/bpf-cgroup.h>
static atomic_long_t unix_nr_socks;
static struct hlist_head bsd_socket_buckets[UNIX_HASH_SIZE / 2];
static spinlock_t bsd_socket_locks[UNIX_HASH_SIZE / 2];
#ifdef CONFIG_PROVE_LOCKING
#define cmp_ptr(l, r) …
static int unix_table_lock_cmp_fn(const struct lockdep_map *a,
const struct lockdep_map *b)
{ … }
static int unix_state_lock_cmp_fn(const struct lockdep_map *_a,
const struct lockdep_map *_b)
{ … }
static int unix_recvq_lock_cmp_fn(const struct lockdep_map *_a,
const struct lockdep_map *_b)
{ … }
#endif
static unsigned int unix_unbound_hash(struct sock *sk)
{ … }
static unsigned int unix_bsd_hash(struct inode *i)
{ … }
static unsigned int unix_abstract_hash(struct sockaddr_un *sunaddr,
int addr_len, int type)
{ … }
static void unix_table_double_lock(struct net *net,
unsigned int hash1, unsigned int hash2)
{ … }
static void unix_table_double_unlock(struct net *net,
unsigned int hash1, unsigned int hash2)
{ … }
#ifdef CONFIG_SECURITY_NETWORK
static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
#else
static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{
return true;
}
#endif
static inline int unix_our_peer(struct sock *sk, struct sock *osk)
{ … }
static inline int unix_may_send(struct sock *sk, struct sock *osk)
{ … }
static inline int unix_recvq_full_lockless(const struct sock *sk)
{ … }
struct sock *unix_peer_get(struct sock *s)
{ … }
EXPORT_SYMBOL_GPL(…);
static struct unix_address *unix_create_addr(struct sockaddr_un *sunaddr,
int addr_len)
{ … }
static inline void unix_release_addr(struct unix_address *addr)
{ … }
static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
{ … }
static int unix_mkname_bsd(struct sockaddr_un *sunaddr, int addr_len)
{ … }
static void __unix_remove_socket(struct sock *sk)
{ … }
static void __unix_insert_socket(struct net *net, struct sock *sk)
{ … }
static void __unix_set_addr_hash(struct net *net, struct sock *sk,
struct unix_address *addr, unsigned int hash)
{ … }
static void unix_remove_socket(struct net *net, struct sock *sk)
{ … }
static void unix_insert_unbound_socket(struct net *net, struct sock *sk)
{ … }
static void unix_insert_bsd_socket(struct sock *sk)
{ … }
static void unix_remove_bsd_socket(struct sock *sk)
{ … }
static struct sock *__unix_find_socket_byname(struct net *net,
struct sockaddr_un *sunname,
int len, unsigned int hash)
{ … }
static inline struct sock *unix_find_socket_byname(struct net *net,
struct sockaddr_un *sunname,
int len, unsigned int hash)
{ … }
static struct sock *unix_find_socket_byinode(struct inode *i)
{ … }
static int unix_dgram_peer_wake_relay(wait_queue_entry_t *q, unsigned mode, int flags,
void *key)
{ … }
static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
{ … }
static void unix_dgram_peer_wake_disconnect(struct sock *sk,
struct sock *other)
{ … }
static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
struct sock *other)
{ … }
static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
{ … }
static int unix_writable(const struct sock *sk, unsigned char state)
{ … }
static void unix_write_space(struct sock *sk)
{ … }
static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
{ … }
static void unix_sock_destructor(struct sock *sk)
{ … }
static void unix_release_sock(struct sock *sk, int embrion)
{ … }
static void init_peercred(struct sock *sk)
{ … }
static void update_peercred(struct sock *sk)
{ … }
static void copy_peercred(struct sock *sk, struct sock *peersk)
{ … }
static int unix_listen(struct socket *sock, int backlog)
{ … }
static int unix_release(struct socket *);
static int unix_bind(struct socket *, struct sockaddr *, int);
static int unix_stream_connect(struct socket *, struct sockaddr *,
int addr_len, int flags);
static int unix_socketpair(struct socket *, struct socket *);
static int unix_accept(struct socket *, struct socket *, struct proto_accept_arg *arg);
static int unix_getname(struct socket *, struct sockaddr *, int);
static __poll_t unix_poll(struct file *, struct socket *, poll_table *);
static __poll_t unix_dgram_poll(struct file *, struct socket *,
poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
#endif
static int unix_shutdown(struct socket *, int);
static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
struct pipe_inode_info *, size_t size,
unsigned int flags);
static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor);
static int unix_dgram_connect(struct socket *, struct sockaddr *,
int, int);
static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
int);
#ifdef CONFIG_PROC_FS
static int unix_count_nr_fds(struct sock *sk)
{ … }
static void unix_show_fdinfo(struct seq_file *m, struct socket *sock)
{ … }
#else
#define unix_show_fdinfo …
#endif
static const struct proto_ops unix_stream_ops = …;
static const struct proto_ops unix_dgram_ops = …;
static const struct proto_ops unix_seqpacket_ops = …;
static void unix_close(struct sock *sk, long timeout)
{ … }
static void unix_unhash(struct sock *sk)
{ … }
static bool unix_bpf_bypass_getsockopt(int level, int optname)
{ … }
struct proto unix_dgram_proto = …;
struct proto unix_stream_proto = …;
static struct sock *unix_create1(struct net *net, struct socket *sock, int kern, int type)
{ … }
static int unix_create(struct net *net, struct socket *sock, int protocol,
int kern)
{ … }
static int unix_release(struct socket *sock)
{ … }
static struct sock *unix_find_bsd(struct sockaddr_un *sunaddr, int addr_len,
int type)
{ … }
static struct sock *unix_find_abstract(struct net *net,
struct sockaddr_un *sunaddr,
int addr_len, int type)
{ … }
static struct sock *unix_find_other(struct net *net,
struct sockaddr_un *sunaddr,
int addr_len, int type)
{ … }
static int unix_autobind(struct sock *sk)
{ … }
static int unix_bind_bsd(struct sock *sk, struct sockaddr_un *sunaddr,
int addr_len)
{ … }
static int unix_bind_abstract(struct sock *sk, struct sockaddr_un *sunaddr,
int addr_len)
{ … }
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{ … }
static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
{ … }
static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
{ … }
static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags)
{ … }
static long unix_wait_for_peer(struct sock *other, long timeo)
__releases(&unix_sk(other)->lock)
{ … }
static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{ … }
static int unix_socketpair(struct socket *socka, struct socket *sockb)
{ … }
static void unix_sock_inherit_flags(const struct socket *old,
struct socket *new)
{ … }
static int unix_accept(struct socket *sock, struct socket *newsock,
struct proto_accept_arg *arg)
{ … }
static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
{ … }
static inline bool too_many_unix_fds(struct task_struct *p)
{ … }
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
{ … }
static void unix_destruct_scm(struct sk_buff *skb)
{ … }
static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
{ … }
static bool unix_passcred_enabled(const struct socket *sock,
const struct sock *other)
{ … }
static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
const struct sock *other)
{ … }
static bool unix_skb_scm_eq(struct sk_buff *skb,
struct scm_cookie *scm)
{ … }
static void scm_stat_add(struct sock *sk, struct sk_buff *skb)
{ … }
static void scm_stat_del(struct sock *sk, struct sk_buff *skb)
{ … }
static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{ … }
#define UNIX_SKB_FRAGS_SZ …
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other,
struct scm_cookie *scm, bool fds_sent)
{ … }
#endif
static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{ … }
static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{ … }
static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{ … }
static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{ … }
int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size,
int flags)
{ … }
static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int flags)
{ … }
static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
{ … }
static long unix_stream_data_wait(struct sock *sk, long timeo,
struct sk_buff *last, unsigned int last_len,
bool freezable)
{ … }
static unsigned int unix_skb_len(const struct sk_buff *skb)
{ … }
struct unix_stream_read_state { … };
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
static int unix_stream_recv_urg(struct unix_stream_read_state *state)
{ … }
static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
int flags, int copied)
{ … }
#endif
static int unix_stream_read_skb(struct sock *sk, skb_read_actor_t recv_actor)
{ … }
static int unix_stream_read_generic(struct unix_stream_read_state *state,
bool freezable)
{ … }
static int unix_stream_read_actor(struct sk_buff *skb,
int skip, int chunk,
struct unix_stream_read_state *state)
{ … }
int __unix_stream_recvmsg(struct sock *sk, struct msghdr *msg,
size_t size, int flags)
{ … }
static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{ … }
static int unix_stream_splice_actor(struct sk_buff *skb,
int skip, int chunk,
struct unix_stream_read_state *state)
{ … }
static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe,
size_t size, unsigned int flags)
{ … }
static int unix_shutdown(struct socket *sock, int mode)
{ … }
long unix_inq_len(struct sock *sk)
{ … }
EXPORT_SYMBOL_GPL(…);
long unix_outq_len(struct sock *sk)
{ … }
EXPORT_SYMBOL_GPL(…);
static int unix_open_file(struct sock *sk)
{ … }
static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static int unix_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{ … }
#endif
static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wait)
{ … }
static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{ … }
#ifdef CONFIG_PROC_FS
#define BUCKET_SPACE …
#define get_bucket(x) …
#define get_offset(x) …
#define set_bucket_offset(b, o) …
static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
{ … }
static struct sock *unix_get_first(struct seq_file *seq, loff_t *pos)
{ … }
static struct sock *unix_get_next(struct seq_file *seq, struct sock *sk,
loff_t *pos)
{ … }
static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
{ … }
static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static void unix_seq_stop(struct seq_file *seq, void *v)
{ … }
static int unix_seq_show(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations unix_seq_ops = …;
#ifdef CONFIG_BPF_SYSCALL
struct bpf_unix_iter_state { … };
struct bpf_iter__unix { … };
static int unix_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
struct unix_sock *unix_sk, uid_t uid)
{ … }
static int bpf_iter_unix_hold_batch(struct seq_file *seq, struct sock *start_sk)
{ … }
static void bpf_iter_unix_put_batch(struct bpf_unix_iter_state *iter)
{ … }
static int bpf_iter_unix_realloc_batch(struct bpf_unix_iter_state *iter,
unsigned int new_batch_sz)
{ … }
static struct sock *bpf_iter_unix_batch(struct seq_file *seq,
loff_t *pos)
{ … }
static void *bpf_iter_unix_seq_start(struct seq_file *seq, loff_t *pos)
{ … }
static void *bpf_iter_unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ … }
static int bpf_iter_unix_seq_show(struct seq_file *seq, void *v)
{ … }
static void bpf_iter_unix_seq_stop(struct seq_file *seq, void *v)
{ … }
static const struct seq_operations bpf_iter_unix_seq_ops = …;
#endif
#endif
static const struct net_proto_family unix_family_ops = …;
static int __net_init unix_net_init(struct net *net)
{ … }
static void __net_exit unix_net_exit(struct net *net)
{ … }
static struct pernet_operations unix_net_ops = …;
#if defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_PROC_FS)
DEFINE_BPF_ITER_FUNC(unix, struct bpf_iter_meta *meta,
struct unix_sock *unix_sk, uid_t uid)
#define INIT_BATCH_SZ …
static int bpf_iter_init_unix(void *priv_data, struct bpf_iter_aux_info *aux)
{ … }
static void bpf_iter_fini_unix(void *priv_data)
{ … }
static const struct bpf_iter_seq_info unix_seq_info = …;
static const struct bpf_func_proto *
bpf_iter_unix_get_func_proto(enum bpf_func_id func_id,
const struct bpf_prog *prog)
{ … }
static struct bpf_iter_reg unix_reg_info = …;
static void __init bpf_iter_register(void)
{ … }
#endif
static int __init af_unix_init(void)
{ … }
fs_initcall(af_unix_init);