[PATCH 34/40] sock: safely expose kernel sockets to userspace

From: Peter Zijlstra
Date: Fri May 04 2007 - 06:38:11 EST


SOCK_KERNEL - avoids user-space from actually using this socket for anything.
This enables sticking kernel sockets into the files_table for identifying and
reference counting purposes.

(iSCSI wants to do this)

Signed-off-by: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Mike Christie <mchristi@xxxxxxxxxx>
---
include/net/sock.h | 1 +
net/socket.c | 10 +++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)

Index: linux-2.6-git/include/net/sock.h
===================================================================
--- linux-2.6-git.orig/include/net/sock.h 2007-03-22 11:29:07.000000000 +0100
+++ linux-2.6-git/include/net/sock.h 2007-03-22 11:29:08.000000000 +0100
@@ -394,6 +394,7 @@ enum sock_flags {
SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
SOCK_VMIO, /* the VM depends on us - make sure we're serviced */
+ SOCK_KERNEL, /* userspace cannot touch this socket */
};

static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
Index: linux-2.6-git/net/socket.c
===================================================================
--- linux-2.6-git.orig/net/socket.c 2007-03-22 11:28:58.000000000 +0100
+++ linux-2.6-git/net/socket.c 2007-03-26 12:00:36.000000000 +0200
@@ -353,7 +353,7 @@ static int sock_alloc_fd(struct file **f
return fd;
}

-static int sock_attach_fd(struct socket *sock, struct file *file)
+static noinline int sock_attach_fd(struct socket *sock, struct file *file)
{
struct qstr this;
char name[32];
@@ -381,6 +381,10 @@ static int sock_attach_fd(struct socket
file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
file->f_mode = FMODE_READ | FMODE_WRITE;
file->f_flags = O_RDWR;
+ if (unlikely(sock->sk && sock_flag(sock->sk, SOCK_KERNEL))) {
+ file->f_mode = 0;
+ file->f_flags = 0;
+ }
file->f_pos = 0;
file->private_data = sock;

@@ -806,6 +810,10 @@ static long sock_ioctl(struct file *file
int pid, err;

sock = file->private_data;
+
+ if (unlikely(sock_flag(sock->sk, SOCK_KERNEL)))
+ return -EBADF;
+
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
err = dev_ioctl(cmd, argp);
} else

--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/