Skip to content

Instantly share code, notes, and snippets.

@johnchen902
Created June 23, 2017 14:29
Show Gist options
  • Save johnchen902/7854075c32c9d9405d26cdfd883ea234 to your computer and use it in GitHub Desktop.
Save johnchen902/7854075c32c9d9405d26cdfd883ea234 to your computer and use it in GitHub Desktop.
Operation System Project 2 (Kernel Patch)
diff -Nur linux-4.11-copy/drivers/char/Kconfig linux-4.11/drivers/char/Kconfig
--- linux-4.11-copy/drivers/char/Kconfig 2017-05-01 10:47:48.000000000 +0800
+++ linux-4.11/drivers/char/Kconfig 2017-06-23 20:07:55.645195892 +0800
@@ -548,6 +548,18 @@
The mmtimer device allows direct userspace access to the
Altix system timer.
+config SOCKET_SERVER
+ tristate "Character-device that listen and write to a socket"
+ default m
+ help
+ The socket_server device allows writing to a socket.
+
+config SOCKET_CLIENT
+ tristate "Character-device that read from a socket"
+ default m
+ help
+ The socket_client device allows reading from a socket.
+
config UV_MMTIMER
tristate "UV_MMTIMER Memory mapped RTC for SGI UV"
depends on X86_UV
diff -Nur linux-4.11-copy/drivers/char/Makefile linux-4.11/drivers/char/Makefile
--- linux-4.11-copy/drivers/char/Makefile 2017-05-01 10:47:48.000000000 +0800
+++ linux-4.11/drivers/char/Makefile 2017-06-23 20:07:55.645195892 +0800
@@ -45,6 +45,9 @@
obj-$(CONFIG_GPIO_TB0219) += tb0219.o
obj-$(CONFIG_TELCLOCK) += tlclk.o
+obj-$(CONFIG_SOCKET_SERVER) += socket_server.o
+obj-$(CONFIG_SOCKET_CLIENT) += socket_client.o
+
obj-$(CONFIG_MWAVE) += mwave/
obj-y += agp/
obj-$(CONFIG_PCMCIA) += pcmcia/
diff -Nur linux-4.11-copy/drivers/char/socket_client.c linux-4.11/drivers/char/socket_client.c
--- linux-4.11-copy/drivers/char/socket_client.c 1970-01-01 08:00:00.000000000 +0800
+++ linux-4.11/drivers/char/socket_client.c 2017-06-23 20:07:55.645195892 +0800
@@ -0,0 +1,165 @@
+/*
+ * Character-device that read from a socket.
+ *
+ * Copyright (c) 2017 Pochang Chen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/audit.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/uaccess.h>
+
+MODULE_AUTHOR("Pochang Chen <[email protected]>");
+MODULE_DESCRIPTION("Socket client device");
+MODULE_LICENSE("GPL");
+
+#define SOCKET_CLIENT_IOCTL_CONNECT _IOW(0x88, 0x08, struct sockaddr)
+
+struct socket_client_data {
+ struct socket *sock;
+};
+
+static ssize_t socket_client_read_iter(struct kiocb *iocb,
+ struct iov_iter *to)
+{
+ struct file *file = iocb->ki_filp;
+ struct socket_client_data *data = file->private_data;
+ struct socket *sock = data->sock;
+ struct msghdr msg = {.msg_iter = *to,
+ .msg_iocb = iocb};
+ ssize_t res;
+
+ if (!sock)
+ return -ENOTCONN;
+
+ if (iocb->ki_pos != 0)
+ return -ESPIPE;
+
+ if (!iov_iter_count(to))
+ return 0;
+
+ if (file->f_flags & O_NONBLOCK)
+ msg.msg_flags = MSG_DONTWAIT;
+
+ res = sock_recvmsg(sock, &msg, msg.msg_flags);
+ *to = msg.msg_iter;
+ return res;
+}
+
+static long socket_client_ioctl_connect(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err;
+ struct socket *sock;
+ struct sockaddr_storage address;
+ struct socket_client_data *data;
+ const int addrlen = sizeof(struct sockaddr);
+
+ err = move_addr_to_kernel((void __user *) arg, addrlen, &address);
+ if (err < 0)
+ goto out_release;
+
+ err = sock_create(AF_INET, SOCK_STREAM, 0, &sock);
+ if (err < 0)
+ goto out;
+
+ err = kernel_connect(sock, (struct sockaddr *) &address,
+ addrlen, file->f_flags);
+ if (err)
+ goto out_release;
+
+ err = kernel_sock_shutdown(sock, SHUT_WR);
+ if (err)
+ goto out_release;
+
+ // XXX spin_lock(&file->f_lock);
+ data = file->private_data;
+ if (data->sock) {
+ // XXX spin_unlock(&file->f_lock);
+ err = -EISCONN;
+ goto out_release;
+ }
+ data->sock = sock;
+ // XXX spin_unlock(&file->f_lock);
+
+ return 0;
+
+out_release:
+ sock_release(sock);
+out:
+ return err;
+}
+
+static long socket_client_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err;
+
+ switch (cmd) {
+ case SOCKET_CLIENT_IOCTL_CONNECT:
+ err = socket_client_ioctl_connect(file, cmd, arg);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+static int socket_client_open(struct inode *inode, struct file *file)
+{
+ struct socket_client_data *data;
+
+ data = kzalloc(sizeof(struct socket_client_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ file->private_data = data;
+ nonseekable_open(inode, file);
+
+ return 0;
+}
+
+static int socket_client_release(struct inode *inode, struct file *file)
+{
+ struct socket_client_data *data;
+ struct socket *sock;
+
+ // XXX spin_lock(&file->f_lock);
+ data = file->private_data;
+ sock = data->sock;
+ data->sock = NULL;
+ // XXX spin_unlock(&file->f_lock);
+
+ if (sock)
+ sock_release(sock);
+ kfree(file->private_data);
+ return 0;
+}
+
+static const struct file_operations socket_client_fops = {
+ .owner = THIS_MODULE,
+ .read_iter = socket_client_read_iter,
+ .unlocked_ioctl = socket_client_ioctl,
+ .open = socket_client_open,
+ .release = socket_client_release,
+};
+
+static struct miscdevice socket_client = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "socket_client",
+ .fops = &socket_client_fops,
+};
+
+module_misc_device(socket_client);
diff -Nur linux-4.11-copy/drivers/char/socket_server.c linux-4.11/drivers/char/socket_server.c
--- linux-4.11-copy/drivers/char/socket_server.c 1970-01-01 08:00:00.000000000 +0800
+++ linux-4.11/drivers/char/socket_server.c 2017-06-23 20:07:55.645195892 +0800
@@ -0,0 +1,171 @@
+/*
+ * Character-device that accept and write to a socket.
+ *
+ * Copyright (c) 2017 Pochang Chen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/audit.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/uaccess.h>
+
+MODULE_AUTHOR("Pochang Chen <[email protected]>");
+MODULE_DESCRIPTION("Socket server device");
+MODULE_LICENSE("GPL");
+
+#define SOCKET_SERVER_IOCTL_ACCEPT _IOW(0x88, 0x29, struct sockaddr)
+
+struct socket_server_data {
+ struct socket *sock;
+};
+
+static ssize_t socket_server_write_iter(struct kiocb *iocb,
+ struct iov_iter *from)
+{
+ struct file *file = iocb->ki_filp;
+ struct socket_server_data *data = file->private_data;
+ struct socket *sock = data->sock;
+ struct msghdr msg = {.msg_iter = *from,
+ .msg_iocb = iocb};
+ ssize_t res;
+
+ if (!sock)
+ return -ENOTCONN;
+
+ if (iocb->ki_pos != 0)
+ return -ESPIPE;
+
+ if (file->f_flags & O_NONBLOCK)
+ msg.msg_flags = MSG_DONTWAIT;
+
+ res = sock_sendmsg(sock, &msg);
+ *from = msg.msg_iter;
+ return res;
+}
+
+static long socket_server_ioctl_accept(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err;
+ struct socket *sock, *newsock;
+ struct sockaddr_storage address;
+ struct socket_server_data *data;
+ const int addrlen = sizeof(struct sockaddr);
+
+ err = move_addr_to_kernel((void __user *) arg, addrlen, &address);
+ if (err < 0)
+ goto out_release;
+
+ err = sock_create(AF_INET, SOCK_STREAM, 0, &sock);
+ if (err < 0)
+ goto out;
+
+ err = kernel_bind(sock, (struct sockaddr *) &address, addrlen);
+ if (err)
+ goto out_release;
+
+ err = kernel_listen(sock, 1);
+ if (err)
+ goto out_release;
+
+ err = kernel_accept(sock, &newsock, file->f_flags);
+ if (err < 0)
+ goto out_release;
+
+ err = kernel_sock_shutdown(newsock, SHUT_RD);
+ if (err)
+ goto out_release_new;
+
+ // XXX spin_lock(&file->f_lock);
+ data = file->private_data;
+ if (data->sock) {
+ // XXX spin_unlock(&file->f_lock);
+ err = -EISCONN;
+ goto out_release_new;
+ }
+ data->sock = newsock;
+ // XXX spin_unlock(&file->f_lock);
+
+out_release:
+ sock_release(sock);
+out:
+ return err;
+out_release_new:
+ sock_release(newsock);
+ goto out_release;
+}
+
+static long socket_server_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err;
+
+ switch (cmd) {
+ case SOCKET_SERVER_IOCTL_ACCEPT:
+ err = socket_server_ioctl_accept(file, cmd, arg);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+static int socket_server_open(struct inode *inode, struct file *file)
+{
+ struct socket_server_data *data;
+
+ data = kzalloc(sizeof(struct socket_server_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ file->private_data = data;
+ nonseekable_open(inode, file);
+
+ return 0;
+}
+
+static int socket_server_release(struct inode *inode, struct file *file)
+{
+ struct socket_server_data *data;
+ struct socket *sock;
+
+ // XXX spin_lock(&file->f_lock);
+ data = file->private_data;
+ sock = data->sock;
+ data->sock = NULL;
+ // XXX spin_unlock(&file->f_lock);
+
+ if (sock)
+ sock_release(sock);
+ kfree(file->private_data);
+ return 0;
+}
+
+static const struct file_operations socket_server_fops = {
+ .owner = THIS_MODULE,
+ .write_iter = socket_server_write_iter,
+ .unlocked_ioctl = socket_server_ioctl,
+ .open = socket_server_open,
+ .release = socket_server_release,
+ // TODO implement
+};
+
+static struct miscdevice socket_server = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "socket_server",
+ .fops = &socket_server_fops,
+};
+
+module_misc_device(socket_server);
diff -Nur linux-4.11-copy/net/socket.c linux-4.11/net/socket.c
--- linux-4.11-copy/net/socket.c 2017-05-01 10:47:48.000000000 +0800
+++ linux-4.11/net/socket.c 2017-06-23 20:07:56.558529274 +0800
@@ -195,6 +195,7 @@
return -EFAULT;
return audit_sockaddr(ulen, kaddr);
}
+EXPORT_SYMBOL(move_addr_to_kernel);
/**
* move_addr_to_user - copy an address to user space
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment