Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 680486 Details for
Bug 851148
libmnl: provide an API to detect Netlink spoofing
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
[PATCH] libmnl: Add filtering support to library as a convienience
-libmnl-Add-filtering-support-to-library-as-a-convienience.patch (text/plain), 6.31 KB, created by
Neil Horman
on 2013-01-17 20:04:18 UTC
(
hide
)
Description:
[PATCH] libmnl: Add filtering support to library as a convienience
Filename:
MIME Type:
Creator:
Neil Horman
Created:
2013-01-17 20:04:18 UTC
Size:
6.31 KB
patch
obsolete
>From d1c1b77fae25b5cdbf5f6492ffc364b4f9befd75 Mon Sep 17 00:00:00 2001 >From: Neil Horman <nhorman@redhat.com> >Date: Thu, 17 Jan 2013 14:56:16 -0500 >Subject: [PATCH] libmnl: Add filtering support to library as a convienience > >Theres been recent discussion about detecting and discarding unwanted netlink >messages in libmnl, so that we can avoid having applications get spoofed by user >space processes sending messages with malformed netlink headers. Commonly >applications want to be able to only receive messages from the kernel, but >libmnl currently doesn't offer a mechanism to do that. This patch adds such a >mechanism. It creates a function mnl_socket_recvfrom_filter, that adds an >extra function pointer parameter which is used to interrogate recieved frames >and filter them based on a desired criteria. It also adds a convieninece >function mnl_recvfrom_filter_user which can be passed as the filter agrument in >mnl_socket_recvfrom_filter, so as to prevent individual applications from >re-inventing the wheel over and over again. > >Signed-off-by: Neil Horman <nhorman@tuxdriver.com> >--- > include/libmnl/libmnl.h | 4 ++ > src/socket.c | 99 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 92 insertions(+), 11 deletions(-) > >diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h >index a647fd9..8ce401a 100644 >--- a/include/libmnl/libmnl.h >+++ b/include/libmnl/libmnl.h >@@ -30,9 +30,13 @@ extern struct mnl_socket *mnl_socket_open(int type); > extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid); > extern int mnl_socket_close(struct mnl_socket *nl); > extern int mnl_socket_get_fd(const struct mnl_socket *nl); >+extern void mnl_skip_user_msg(int val); > extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl); > extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz); > extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz); >+extern ssize_t mnl_socket_recvfrom_filter(const struct mnl_socket *nl, void *buf, size_t size, >+ int(*filter)(const struct mnl_socket *, struct msghdr*)); >+extern int mnl_recvfrom_filter_user(const struct mnl_socket*, struct msghdr*); > extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len); > extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len); > >diff --git a/src/socket.c b/src/socket.c >index 6d54563..fec9f17 100644 >--- a/src/socket.c >+++ b/src/socket.c >@@ -188,6 +188,26 @@ mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len) > } > EXPORT_SYMBOL(mnl_socket_sendto); > >+static ssize_t >+__mnl_socket_recvfrom(const struct mnl_socket *nl, struct msghdr *msg) >+{ >+ ssize_t ret; >+ >+ ret = recvmsg(nl->fd, msg, 0); >+ if (ret == -1) >+ return ret; >+ >+ if (msg->msg_flags & MSG_TRUNC) { >+ errno = ENOSPC; >+ return -1; >+ } >+ if (msg->msg_namelen != sizeof(struct sockaddr_nl)) { >+ errno = EINVAL; >+ return -1; >+ } >+ return ret; >+} >+ > /** > * mnl_socket_recvfrom - receive a netlink message > * \param nl netlink socket obtained via mnl_socket_open() >@@ -205,6 +225,49 @@ EXPORT_SYMBOL(mnl_socket_sendto); > ssize_t > mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz) > { >+ struct sockaddr_nl addr; >+ struct iovec iov = { >+ .iov_base = buf, >+ .iov_len = bufsiz, >+ }; >+ struct msghdr msg = { >+ .msg_name = &addr, >+ .msg_namelen = sizeof(struct sockaddr_nl), >+ .msg_iov = &iov, >+ .msg_iovlen = 1, >+ .msg_control = NULL, >+ .msg_controllen = 0, >+ .msg_flags = 0, >+ }; >+ >+ return __mnl_socket_recvfrom(nl, &msg); >+} >+EXPORT_SYMBOL(mnl_socket_recvfrom); >+ >+/** >+ * mnl_socket_recvfrom_filter - receive a netlink message after filtering >+ * \param nl netlink socket obtained via mnl_socket_open() >+ * \param buf buffer that you want to use to store the netlink message >+ * \param bufsiz size of the buffer passed to store the netlink message >+ * \param filter function pointer to method to filter messages >+ * >+ * On error, it returns -1 and errno is appropriately set. If errno is set >+ * to ENOSPC, it means that the buffer that you have passed to store the >+ * netlink message is too small, so you have received a truncated message. >+ * To avoid this, you have to allocate a buffer of MNL_SOCKET_BUFFER_SIZE >+ * (which is 8KB, see linux/netlink.h for more information). Using this >+ * buffer size ensures that your buffer is big enough to store the netlink >+ * message without truncating it. For every frame that is successfully received >+ * the filter function is called (if set), a non-zero return from the filter >+ * function causes the message to be discarded, and the next message will be >+ * received. A zero return code from the filter function allows the messaged to >+ * be passed back to the caller. >+ * >+ */ >+ssize_t >+mnl_socket_recvfrom_filter(const struct mnl_socket *nl, void *buf, size_t bufsiz, >+ int(*filter)(const struct mnl_socket*, struct msghdr*)) >+{ > ssize_t ret; > struct sockaddr_nl addr; > struct iovec iov = { >@@ -220,21 +283,35 @@ mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz) > .msg_controllen = 0, > .msg_flags = 0, > }; >- ret = recvmsg(nl->fd, &msg, 0); >+retry: >+ ret = __mnl_socket_recvfrom(nl, &msg); > if (ret == -1) > return ret; >- >- if (msg.msg_flags & MSG_TRUNC) { >- errno = ENOSPC; >- return -1; >- } >- if (msg.msg_namelen != sizeof(struct sockaddr_nl)) { >- errno = EINVAL; >- return -1; >- } >+ if (filter && filter(nl, &msg)) >+ goto retry; > return ret; > } >-EXPORT_SYMBOL(mnl_socket_recvfrom); >+EXPORT_SYMBOL(mnl_socket_recvfrom_filter); >+ >+/** >+ * mnl_recvfrom_filter_user - helper function to filter user messages >+ * \param nl netlink socket that a message was received on >+ * \param msg - pointer to the msghdr of the received message >+ * >+ * This function is meant to be passed as the filter argument to >+ * mnl_socket_recvfrom_filter. It is a convienience function to automatically >+ * filter out messages originating from user space hosts. >+ * >+ * returns zero, if the message originated from the kernel >+ * returns non-zero if the message did not originate from the kernel >+ */ >+int mnl_recvfrom_filter_user(const struct mnl_socket *nl, struct msghdr *msg) >+{ >+ struct sockaddr_nl *addr = msg->msg_name; >+ >+ return (addr->nl_pid != 0); >+} >+EXPORT_SYMBOL(mnl_recvfrom_filter_user); > > /** > * mnl_socket_close - close a given netlink socket >-- >1.7.11.7 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 851148
: 680486 |
716400