lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <6c60b9fb-c578-82ec-d422-a49169f077b6@informatik.uni-wuerzburg.de>
Date:   Tue, 19 Dec 2017 13:40:48 +0100
From:   Stefan Geißler 
        <stefan.geissler@...ormatik.uni-wuerzburg.de>
To:     netdev@...r.kernel.org
Subject: Reading header and payload at sock_recvmsg() and sock_sendmsg()

Hello netdev mailing list,

I am a PhD student from Germany and currently working on a project that
involves monitoring packets as they are passed from kernel space towards
user space applications. To achieve this, I applied the attached patch
to Kernel v4.4 and implemented the two functions below that are called
from - and with the parameters of - sock_recvmsg() and sock_sendmsg().
For every incoming packet I check if it belongs to the process I want to
monitor. If so, I get the header information as well as the payload and
save the current timestamp. Finally and set the current state to monitor
for the transmission of this packet. Then I compare the payloads of
outgoing packets until a match is found and print the time it took this
packet to travel through the user space.

However, I seem to be unable to get the socket information and data for
incoming packets in __i3_recv_monitor(), as the debug output is always
something like

Dec 19 08:49:51 localhost kernel: [413608.826373] [Packet received]
(13739)0.0.0.0;0;0.0.0.0;0;0;413595528124549
Dec 19 08:49:51 localhost kernel: [413608.831397] [Received data] (null)

Regarding outgoing packets in __i3_send_monitor(), I am at least able to
get the network information from the socket. My data pointer is empty as
well.

Dec 19 09:00:20 localhost kernel: [414238.178057] [Packet send]
(13739)192.168.200.19;36628;192.168.200.20;45110;6;414224859396846
Dec 19 09:00:20 localhost kernel: [414238.181216] [Send data] (null)

The context is that I want to monitor packet processing times of user
space applications that do not alter the payload before retransmitting
packets.

I was hoping that someone with more experience of the network stack
could point me towards what I am missing or doing wrong here.

I hope this is not totally the wrong place to ask such a question and
already thank you in advance!

Best regards,
Stefan

--------------------------------------------------------

void __i3_recv_monitor(struct socket * sock, struct msghdr * msg, size_t
len, int flags) {

  int i = 0;
  const struct iovec * iov;

  if (unlikely(current_state == WAIT_FOR_RECV) && ktime_to_ns(recv_time)
== 0 && current->pid == vnf_pid) {

    recv_time = ktime_get();

    if (unlikely(debug>=2)) printk(KERN_INFO "[Packet received]
(%u)%pI4;%u;%pI4;%d;%d;%lld\n",
				   current->pid,
				   &sock->sk->sk_rcv_saddr,
				   sock->sk->sk_num,
				   &sock->sk->sk_daddr,
				   sock->sk->sk_dport,
				   sock->sk->sk_protocol,
				   ktime_to_ns(recv_time));

    iov = msg->msg_iter.iov;
    recv_data = (char *)kmalloc(iov->iov_len, GFP_KERNEL);
    copy_from_user(recv_data, iov->iov_base, iov->iov_len);

    printk(KERN_INFO "[Received data] %s\n", *recv_data);

    current_state = WAIT_FOR_SEND;
  }
}


void __i3_send_monitor(struct socket * sock, struct msghdr * msg) {

  int i = 0;
  const struct iovec * iov;

    // I don't like this approach at all... think about something
different!!
  if (unlikely(current_state == WAIT_FOR_SEND) && current->pid == vnf_pid) {

    send_time = ktime_get();

    if (unlikely(debug>=2)) printk(KERN_INFO "[Packet send]
(%u)%pI4;%u;%pI4;%d;%d;%lld\n",
				   current->pid,
				   &sock->sk->sk_rcv_saddr,
				   sock->sk->sk_num,
				   &sock->sk->sk_daddr,
				   sock->sk->sk_dport,
				   sock->sk->sk_protocol,
				   ktime_to_ns(send_time));


    if (ktime_to_ns(recv_time) != 0) {

      iov = msg->msg_iter.iov;
      send_data = (char *)kmalloc(iov->iov_len, GFP_KERNEL);
      copy_from_user(send_data, iov->iov_base, iov->iov_len);

      printk(KERN_INFO "[Send data] %s\n", *send_data);

      if (unlikely(*recv_data == *send_data)) {
	proc_time = ktime_sub(send_time, recv_time);
	if (unlikely(debug>=2)) printk(KERN_INFO "[Processing time] %lld\n",
ktime_to_ns(proc_time));

	recv_time = ktime_set(0, 0);
	current_state = SLEEP;
	kfree(recv_data);
      }

      kfree(send_data);
    }
  }
}

--------------------------------------------------------

>From 7ef3d1efe53fbfb937e0c1e5200e1a8e40e220e9 Mon Sep 17 00:00:00 2001
From: Stefan Geissler <stefan.geissler@...ormatik.uni-wuerzburg.de>
Date: Tue, 14 Nov 2017 12:05:39 +0100
Subject: [PATCH 1/2] Added pointers to hook into socket calls for monitoring
 reasons

---
 net/socket.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/socket.c b/net/socket.c
index d730ef9..57ee946 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -113,6 +113,13 @@ unsigned int sysctl_net_busy_read __read_mostly;
 unsigned int sysctl_net_busy_poll __read_mostly;
 #endif

+// Setup pointer to fill with external wrapper functions to monitor sockets
+void (*__i3_send_monitor_ptr)(struct sock *, struct msghdr *);
+void (*__i3_recv_monitor_ptr)(struct sock *, struct msghdr *, size_t ,
int);
+EXPORT_SYMBOL(__i3_send_monitor_ptr);
+EXPORT_SYMBOL(__i3_recv_monitor_ptr);
+
+
 static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to);
 static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from);
 static int sock_mmap(struct file *file, struct vm_area_struct *vma);
@@ -615,6 +622,8 @@ static inline int sock_sendmsg_nosec(struct socket
*sock, struct msghdr *msg)

 int sock_sendmsg(struct socket *sock, struct msghdr *msg)
 {
+	if ((unlikely(__i3_send_monitor_ptr))
+	  (*__i3_send_monitor_ptr)(sock, msg);
 	int err = security_socket_sendmsg(sock, msg,
 					  msg_data_left(msg));

@@ -716,6 +725,8 @@ static inline int sock_recvmsg_nosec(struct socket
*sock, struct msghdr *msg,
 int sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 		 int flags)
 {
+  	if (unlikely(__i3_recv_monitor_ptr))
+	    (*__i3_recv_monitor_ptr)(sock, msg, size, flags);
 	int err = security_socket_recvmsg(sock, msg, size, flags);

 	return err ?: sock_recvmsg_nosec(sock, msg, size, flags);
@@ -2479,6 +2490,11 @@ EXPORT_SYMBOL(sock_unregister);

 static int __init sock_init(void)
 {
+	// Ensure pointers are set to NULL as long as no module is loaded.
+	// Unsetting the pointers has to be handled by the module upon exit.
+	__i3_recv_monitor_ptr = NULL;
+	__i3_send_monitor_ptr = NULL;
+
 	int err;
 	/*
 	 *      Initialize the network sysctl infrastructure.
-- 
2.7.4


>From 262cf38d4c576f6399851e6f5ecbd3a73a62d416 Mon Sep 17 00:00:00 2001
From: Stefan Geissler <stefan.geissler@...ormatik.uni-wuerzburg.de>
Date: Tue, 14 Nov 2017 14:04:56 +0100
Subject: [PATCH 2/2] Fixed ISO C90 Warnings

---
 net/socket.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 57ee946..2e840a8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -114,8 +114,8 @@ unsigned int sysctl_net_busy_poll __read_mostly;
 #endif

 // Setup pointer to fill with external wrapper functions to monitor sockets
-void (*__i3_send_monitor_ptr)(struct sock *, struct msghdr *);
-void (*__i3_recv_monitor_ptr)(struct sock *, struct msghdr *, size_t ,
int);
+void (*__i3_send_monitor_ptr)(struct socket *, struct msghdr *);
+void (*__i3_recv_monitor_ptr)(struct socket *, struct msghdr *, size_t
, int);
 EXPORT_SYMBOL(__i3_send_monitor_ptr);
 EXPORT_SYMBOL(__i3_recv_monitor_ptr);

@@ -622,9 +622,10 @@ static inline int sock_sendmsg_nosec(struct socket
*sock, struct msghdr *msg)

 int sock_sendmsg(struct socket *sock, struct msghdr *msg)
 {
-	if ((unlikely(__i3_send_monitor_ptr))
+  	int err;
+	if (unlikely(__i3_send_monitor_ptr))
 	  (*__i3_send_monitor_ptr)(sock, msg);
-	int err = security_socket_sendmsg(sock, msg,
+	err = security_socket_sendmsg(sock, msg,
 					  msg_data_left(msg));

 	return err ?: sock_sendmsg_nosec(sock, msg);
@@ -725,9 +726,10 @@ static inline int sock_recvmsg_nosec(struct socket
*sock, struct msghdr *msg,
 int sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 		 int flags)
 {
+  	int err;
   	if (unlikely(__i3_recv_monitor_ptr))
 	    (*__i3_recv_monitor_ptr)(sock, msg, size, flags);
-	int err = security_socket_recvmsg(sock, msg, size, flags);
+	err = security_socket_recvmsg(sock, msg, size, flags);

 	return err ?: sock_recvmsg_nosec(sock, msg, size, flags);
 }
@@ -2489,13 +2491,14 @@ void sock_unregister(int family)
 EXPORT_SYMBOL(sock_unregister);

 static int __init sock_init(void)
-{
+{
+	int err;
+
 	// Ensure pointers are set to NULL as long as no module is loaded.
 	// Unsetting the pointers has to be handled by the module upon exit.
 	__i3_recv_monitor_ptr = NULL;
 	__i3_send_monitor_ptr = NULL;
-
-	int err;
+	
 	/*
 	 *      Initialize the network sysctl infrastructure.
 	 */
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ