aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index cef79873b09d..928691c43408 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -85,7 +85,7 @@
85#include <linux/module.h> 85#include <linux/module.h>
86#include <linux/kernel.h> 86#include <linux/kernel.h>
87#include <linux/signal.h> 87#include <linux/signal.h>
88#include <linux/sched.h> 88#include <linux/sched/signal.h>
89#include <linux/errno.h> 89#include <linux/errno.h>
90#include <linux/string.h> 90#include <linux/string.h>
91#include <linux/stat.h> 91#include <linux/stat.h>
@@ -117,6 +117,7 @@
117#include <net/checksum.h> 117#include <net/checksum.h>
118#include <linux/security.h> 118#include <linux/security.h>
119#include <linux/freezer.h> 119#include <linux/freezer.h>
120#include <linux/file.h>
120 121
121struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; 122struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
122EXPORT_SYMBOL_GPL(unix_socket_table); 123EXPORT_SYMBOL_GPL(unix_socket_table);
@@ -635,7 +636,7 @@ static int unix_bind(struct socket *, struct sockaddr *, int);
635static int unix_stream_connect(struct socket *, struct sockaddr *, 636static int unix_stream_connect(struct socket *, struct sockaddr *,
636 int addr_len, int flags); 637 int addr_len, int flags);
637static int unix_socketpair(struct socket *, struct socket *); 638static int unix_socketpair(struct socket *, struct socket *);
638static int unix_accept(struct socket *, struct socket *, int); 639static int unix_accept(struct socket *, struct socket *, int, bool);
639static int unix_getname(struct socket *, struct sockaddr *, int *, int); 640static int unix_getname(struct socket *, struct sockaddr *, int *, int);
640static unsigned int unix_poll(struct file *, struct socket *, poll_table *); 641static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
641static unsigned int unix_dgram_poll(struct file *, struct socket *, 642static unsigned int unix_dgram_poll(struct file *, struct socket *,
@@ -1401,7 +1402,8 @@ static void unix_sock_inherit_flags(const struct socket *old,
1401 set_bit(SOCK_PASSSEC, &new->flags); 1402 set_bit(SOCK_PASSSEC, &new->flags);
1402} 1403}
1403 1404
1404static int unix_accept(struct socket *sock, struct socket *newsock, int flags) 1405static int unix_accept(struct socket *sock, struct socket *newsock, int flags,
1406 bool kern)
1405{ 1407{
1406 struct sock *sk = sock->sk; 1408 struct sock *sk = sock->sk;
1407 struct sock *tsk; 1409 struct sock *tsk;
@@ -2592,6 +2594,43 @@ long unix_outq_len(struct sock *sk)
2592} 2594}
2593EXPORT_SYMBOL_GPL(unix_outq_len); 2595EXPORT_SYMBOL_GPL(unix_outq_len);
2594 2596
2597static int unix_open_file(struct sock *sk)
2598{
2599 struct path path;
2600 struct file *f;
2601 int fd;
2602
2603 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
2604 return -EPERM;
2605
2606 unix_state_lock(sk);
2607 path = unix_sk(sk)->path;
2608 if (!path.dentry) {
2609 unix_state_unlock(sk);
2610 return -ENOENT;
2611 }
2612
2613 path_get(&path);
2614 unix_state_unlock(sk);
2615
2616 fd = get_unused_fd_flags(O_CLOEXEC);
2617 if (fd < 0)
2618 goto out;
2619
2620 f = dentry_open(&path, O_PATH, current_cred());
2621 if (IS_ERR(f)) {
2622 put_unused_fd(fd);
2623 fd = PTR_ERR(f);
2624 goto out;
2625 }
2626
2627 fd_install(fd, f);
2628out:
2629 path_put(&path);
2630
2631 return fd;
2632}
2633
2595static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 2634static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2596{ 2635{
2597 struct sock *sk = sock->sk; 2636 struct sock *sk = sock->sk;
@@ -2610,6 +2649,9 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2610 else 2649 else
2611 err = put_user(amount, (int __user *)arg); 2650 err = put_user(amount, (int __user *)arg);
2612 break; 2651 break;
2652 case SIOCUNIXFILE:
2653 err = unix_open_file(sk);
2654 break;
2613 default: 2655 default:
2614 err = -ENOIOCTLCMD; 2656 err = -ENOIOCTLCMD;
2615 break; 2657 break;