* [RFC] Allow LSM to use IP address/port number. (was Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.)
[not found] ` <200707061343.03942.paul.moore@hp.com>
@ 2007-07-09 5:33 ` Tetsuo Handa
2007-07-09 7:26 ` [RFC] Allow LSM to use IP address/port number David Miller
0 siblings, 1 reply; 12+ messages in thread
From: Tetsuo Handa @ 2007-07-09 5:33 UTC (permalink / raw)
To: netdev; +Cc: linux-security-module, chrisw
Hello.
This thread is from http://marc.info/?t=118346457000005&r=1&w=2 .
I want to use tcp_wrapper-like filtering using LSM.
But it seems that there are cases (recvmsg() and read()?) where
__sock_recvmsg() is called with msg->name == NULL and msg->msg_namelen == 0
that makes what I want to do impossible.
To make IP address and port number always available,
some changes in socket layer are needed.
Since I'm not getting objection from LSM-ml so far,
I'm now adding netdev-ml because this patch is related to socket layer.
Are there ways to receive messages other than recv()/recvfrom()/recvmsg()/read()?
If recv()/recvfrom()/recvmsg()/read() are all ways to receive messages,
the following patch seems to allow LSM to use IP address and port number.
The following patch allocates buffer for receiving IP address and port number
even if userland doesn't request them.
Is this change no problem?
Regards.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
include/linux/security.h | 38 ++++++++++++++++++++++++++++++++++----
net/socket.c | 40 ++++++++++++++++++++++++++++++++++------
security/dummy.c | 11 +++++++++--
3 files changed, 77 insertions(+), 12 deletions(-)
diff -upr a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h 2007-07-03 10:07:14.000000000 +0900
+++ b/include/linux/security.h 2007-07-09 10:51:04.000000000 +0900
@@ -748,8 +748,12 @@ struct request_sock;
* @socket_post_accept:
* This hook allows a security module to copy security
* information into the newly created socket's inode.
+ * This hook also allows a security module to filter connections
+ * from unwanted peers.
+ * The connection will be aborted if this hook returns nonzero.
* @sock contains the listening socket structure.
* @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
* @socket_sendmsg:
* Check permission before transmitting a message to another socket.
* @sock contains the socket structure.
@@ -763,6 +767,15 @@ struct request_sock;
* @size contains the size of message structure.
* @flags contains the operational flags.
* Return 0 if permission is granted.
+ * @socket_post_recvmsg:
+ * Check peer's address after receiving a message from a socket.
+ * This hook allows a security module to filter messages
+ * from unwanted peers.
+ * @sock contains the socket structure.
+ * @msg contains the message structure.
+ * @size contains the size of message structure.
+ * @flags contains the operational flags.
+ * Return 0 if permission is granted.
* @socket_getsockname:
* Check permission before the local address (name) of the socket object
* @sock is retrieved.
@@ -1343,12 +1356,14 @@ struct security_operations {
struct sockaddr * address, int addrlen);
int (*socket_listen) (struct socket * sock, int backlog);
int (*socket_accept) (struct socket * sock, struct socket * newsock);
- void (*socket_post_accept) (struct socket * sock,
+ int (*socket_post_accept) (struct socket *sock,
struct socket * newsock);
int (*socket_sendmsg) (struct socket * sock,
struct msghdr * msg, int size);
int (*socket_recvmsg) (struct socket * sock,
struct msghdr * msg, int size, int flags);
+ int (*socket_post_recvmsg) (struct socket *sock, struct msghdr *msg,
+ int size, int flags);
int (*socket_getsockname) (struct socket * sock);
int (*socket_getpeername) (struct socket * sock);
int (*socket_getsockopt) (struct socket * sock, int level, int optname);
@@ -2853,10 +2868,10 @@ static inline int security_socket_accept
return security_ops->socket_accept(sock, newsock);
}
-static inline void security_socket_post_accept(struct socket * sock,
+static inline int security_socket_post_accept(struct socket *sock,
struct socket * newsock)
{
- security_ops->socket_post_accept(sock, newsock);
+ return security_ops->socket_post_accept(sock, newsock);
}
static inline int security_socket_sendmsg(struct socket * sock,
@@ -2872,6 +2887,13 @@ static inline int security_socket_recvms
return security_ops->socket_recvmsg(sock, msg, size, flags);
}
+static inline int security_socket_post_recvmsg(struct socket *sock,
+ struct msghdr *msg,
+ int size, int flags)
+{
+ return security_ops->socket_post_recvmsg(sock, msg, size, flags);
+}
+
static inline int security_socket_getsockname(struct socket * sock)
{
return security_ops->socket_getsockname(sock);
@@ -3016,9 +3038,10 @@ static inline int security_socket_accept
return 0;
}
-static inline void security_socket_post_accept(struct socket * sock,
+static inline int security_socket_post_accept(struct socket *sock,
struct socket * newsock)
{
+ return 0;
}
static inline int security_socket_sendmsg(struct socket * sock,
@@ -3034,6 +3057,13 @@ static inline int security_socket_recvms
return 0;
}
+static inline int security_socket_post_recvmsg(struct socket *sock,
+ struct msghdr *msg,
+ int size, int flags)
+{
+ return 0;
+}
+
static inline int security_socket_getsockname(struct socket * sock)
{
return 0;
diff -upr a/net/socket.c b/net/socket.c
--- a/net/socket.c 2007-07-03 10:07:16.000000000 +0900
+++ b/net/socket.c 2007-07-09 10:44:25.000000000 +0900
@@ -636,7 +636,18 @@ static inline int __sock_recvmsg(struct
if (err)
return err;
- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ err = sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ /*
+ * Filter messages from unwanted peers.
+ * To be exact, this hook can't filter messages,
+ * this hook just returns an error code.
+ */
+ if (err >= 0) {
+ int ret = security_socket_post_recvmsg(sock, msg, size, flags);
+ if (ret)
+ err = ret;
+ }
+ return err;
}
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -649,8 +660,16 @@ int sock_recvmsg(struct socket *sock, st
init_sync_kiocb(&iocb, NULL);
iocb.private = &siocb;
ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
- if (-EIOCBQUEUED == ret)
+ if (-EIOCBQUEUED == ret) {
ret = wait_on_sync_kiocb(&iocb);
+ /* I can now check security_socket_post_recvmsg(). */
+ if (ret >= 0) {
+ int err = security_socket_post_recvmsg(sock, msg, size,
+ flags);
+ if (err)
+ ret = err;
+ }
+ }
return ret;
}
@@ -713,12 +732,14 @@ static ssize_t do_sock_read(struct msghd
struct socket *sock = file->private_data;
size_t size = 0;
int i;
+ /* only for security_socket_post_recvmsg() */
+ char address[MAX_SOCK_ADDR];
for (i = 0; i < nr_segs; i++)
size += iov[i].iov_len;
- msg->msg_name = NULL;
- msg->msg_namelen = 0;
+ msg->msg_name = address;
+ msg->msg_namelen = sizeof(address);
msg->msg_control = NULL;
msg->msg_controllen = 0;
msg->msg_iov = (struct iovec *)iov;
@@ -1438,13 +1459,16 @@ asmlinkage long sys_accept(int fd, struc
goto out_fd;
}
+ /* Filter connections from unwanted peers like TCP Wrapper. */
+ err = security_socket_post_accept(sock, newsock);
+ if (err)
+ goto out_fd;
+
/* File flags are not inherited via accept() unlike another OSes. */
fd_install(newfd, newfile);
err = newfd;
- security_socket_post_accept(sock, newsock);
-
out_put:
fput_light(sock->file, fput_needed);
out:
@@ -1938,6 +1962,10 @@ asmlinkage long sys_recvmsg(int fd, stru
goto out_freeiov;
total_len = err;
+ /* only for security_socket_post_recvmsg() */
+ msg_sys.msg_name = addr;
+ msg_sys.msg_namelen = sizeof(addr);
+
cmsg_ptr = (unsigned long)msg_sys.msg_control;
msg_sys.msg_flags = 0;
if (MSG_CMSG_COMPAT & flags)
diff -upr a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c 2007-04-26 12:08:32.000000000 +0900
+++ b/security/dummy.c 2007-07-09 10:39:59.000000000 +0900
@@ -737,10 +737,10 @@ static int dummy_socket_accept (struct s
return 0;
}
-static void dummy_socket_post_accept (struct socket *sock,
+static int dummy_socket_post_accept (struct socket *sock,
struct socket *newsock)
{
- return;
+ return 0;
}
static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg,
@@ -755,6 +755,12 @@ static int dummy_socket_recvmsg (struct
return 0;
}
+static int dummy_socket_post_recvmsg (struct socket *sock, struct msghdr *msg,
+ int size, int flags)
+{
+ return 0;
+}
+
static int dummy_socket_getsockname (struct socket *sock)
{
return 0;
@@ -1092,6 +1098,7 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, socket_post_accept);
set_to_dummy_if_null(ops, socket_sendmsg);
set_to_dummy_if_null(ops, socket_recvmsg);
+ set_to_dummy_if_null(ops, socket_post_recvmsg);
set_to_dummy_if_null(ops, socket_getsockname);
set_to_dummy_if_null(ops, socket_getpeername);
set_to_dummy_if_null(ops, socket_setsockopt);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 5:33 ` [RFC] Allow LSM to use IP address/port number. (was Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.) Tetsuo Handa
@ 2007-07-09 7:26 ` David Miller
2007-07-09 13:13 ` Tetsuo Handa
0 siblings, 1 reply; 12+ messages in thread
From: David Miller @ 2007-07-09 7:26 UTC (permalink / raw)
To: from-netdev; +Cc: netdev, linux-security-module, chrisw
From: Tetsuo Handa <from-netdev@i-love.sakura.ne.jp>
Date: Mon, 09 Jul 2007 14:33:01 +0900
> @@ -649,8 +660,16 @@ int sock_recvmsg(struct socket *sock, st
> init_sync_kiocb(&iocb, NULL);
> iocb.private = &siocb;
> ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
> - if (-EIOCBQUEUED == ret)
> + if (-EIOCBQUEUED == ret) {
> ret = wait_on_sync_kiocb(&iocb);
> + /* I can now check security_socket_post_recvmsg(). */
> + if (ret >= 0) {
> + int err = security_socket_post_recvmsg(sock, msg, size,
> + flags);
> + if (err)
> + ret = err;
> + }
> + }
> return ret;
> }
I don't think it's such a hot idea to return errors if the
wait_on_sync_kiocb() has returned success.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 7:26 ` [RFC] Allow LSM to use IP address/port number David Miller
@ 2007-07-09 13:13 ` Tetsuo Handa
2007-07-09 22:50 ` James Morris
0 siblings, 1 reply; 12+ messages in thread
From: Tetsuo Handa @ 2007-07-09 13:13 UTC (permalink / raw)
To: davem, netdev; +Cc: linux-security-module
Hello.
Thank you for your comment.
David Miller wrote:
> I don't think it's such a hot idea to return errors if the
> wait_on_sync_kiocb() has returned success.
My patch may return errors for non-wait_on_sync_kiocb() case too.
Are you saying only wait_on_sync_kiocb() case is bad?
If so, could you please explain me why?
The location I inserted a hook is "after aio event finished".
Both "struct kiocb" and "struct sock_iocb" are no longer in use.
So, I think this location can safely return errors.
If you are saying "don't return error after receiving data",
I'll explain you why I need hooks after receiving data.
What I want to do is to implement a kind of anti-virus software's
personal firewall feature.
It drops messages from unwanted IP address/ports.
(To be exact, it doesn't drop, it just tells userland process
not to use received messages by returning errors.)
security_socket_recvmsg() is called before retrieving a message.
I want a hook that is called after retrieving a message
so that I can use IP address and port number for judgement.
I also want to allow users judge interactively using a popup dialog.
To judge interactively, the hook has to be block-able.
If non-interactive, iptables is the appropriate location for filtering.
This is why I want to insert security_socket_post_recvmsg() hook here.
Regards.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 13:13 ` Tetsuo Handa
@ 2007-07-09 22:50 ` James Morris
2007-07-09 23:05 ` Stephen Hemminger
0 siblings, 1 reply; 12+ messages in thread
From: James Morris @ 2007-07-09 22:50 UTC (permalink / raw)
To: Tetsuo Handa; +Cc: davem, netdev, linux-security-module
On Mon, 9 Jul 2007, Tetsuo Handa wrote:
> It drops messages from unwanted IP address/ports.
> (To be exact, it doesn't drop, it just tells userland process
> not to use received messages by returning errors.)
This is broken.
You need to properly fail the network operation and ensure that the peers
are appropriately notified using the standard failure paths, not just
arbitrarily propagate errors to the local user.
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 22:50 ` James Morris
@ 2007-07-09 23:05 ` Stephen Hemminger
2007-07-09 23:41 ` James Morris
0 siblings, 1 reply; 12+ messages in thread
From: Stephen Hemminger @ 2007-07-09 23:05 UTC (permalink / raw)
To: James Morris; +Cc: Tetsuo Handa, davem, netdev, linux-security-module
On Mon, 9 Jul 2007 18:50:27 -0400 (EDT)
James Morris <jmorris@namei.org> wrote:
> On Mon, 9 Jul 2007, Tetsuo Handa wrote:
>
> > It drops messages from unwanted IP address/ports.
> > (To be exact, it doesn't drop, it just tells userland process
> > not to use received messages by returning errors.)
>
> This is broken.
>
> You need to properly fail the network operation and ensure that the peers
> are appropriately notified using the standard failure paths, not just
> arbitrarily propagate errors to the local user.
Isn't it better to hook into existing netfilter infrastructure somehow?
Just filtering by ports or IP addresses is tip of bigger security isolation issues.
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 23:05 ` Stephen Hemminger
@ 2007-07-09 23:41 ` James Morris
2007-07-10 4:11 ` Tetsuo Handa
2007-07-20 15:11 ` [PATCH 1/1] " Tetsuo Handa
0 siblings, 2 replies; 12+ messages in thread
From: James Morris @ 2007-07-09 23:41 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Tetsuo Handa, davem, netdev, linux-security-module
On Mon, 9 Jul 2007, Stephen Hemminger wrote:
> Isn't it better to hook into existing netfilter infrastructure somehow?
Yes, it has been suggested several times.
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] Allow LSM to use IP address/port number.
2007-07-09 23:41 ` James Morris
@ 2007-07-10 4:11 ` Tetsuo Handa
2007-07-20 15:11 ` [PATCH 1/1] " Tetsuo Handa
1 sibling, 0 replies; 12+ messages in thread
From: Tetsuo Handa @ 2007-07-10 4:11 UTC (permalink / raw)
To: James Morris; +Cc: netdev, linux-security-module
Thank you for your comment.
I have a question regarding netfilter infrastructure.
I want to filter messages using "task_struct->security".
Can the netfilter's queuing to userspace feature
get a list of "struct task_struct" who shares a socket
that is going to receive incoming messages?
My approach is not "is this socket allowed to receive from xxx.xxx.xxx.xxx port yy"
but "is this process allowed to receive from xxx.xxx.xxx.xxx port yy".
So, my approach is not using security context associated with a socket
but security context associated with a process.
If I can't use netfilter, there is no chance to filter before enqueuing
messages. So, I think propagating errors to the local user
after dequeuing messages is the only possible way.
Regards.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/1] Allow LSM to use IP address/port number.
2007-07-09 23:41 ` James Morris
2007-07-10 4:11 ` Tetsuo Handa
@ 2007-07-20 15:11 ` Tetsuo Handa
2007-07-20 15:28 ` James Morris
1 sibling, 1 reply; 12+ messages in thread
From: Tetsuo Handa @ 2007-07-20 15:11 UTC (permalink / raw)
To: jmorris, shemminger; +Cc: netdev, linux-security-module
Hello.
> > Isn't it better to hook into existing netfilter infrastructure somehow?
> Yes, it has been suggested several times.
I want to use a process's context who issued
accept()/recv()/recvfrom()/recvmsg()/read() requests.
But Stephen Smalley said at http://marc.info/?l=linux-security-module&m=118459899017487&w=2 that
> The socket can be inherited by a child task or passed via local IPC to
> an unrelated task, and then used by those other tasks. It isn't tied to
> the original allocating task's lifecycle in any way, nor is it
> guaranteed to only be used by that original allocating task. It can
> exist in zero, one or many tasks' file tables and still be receiving
> data, and can go from completely disassociated (i.e. not present in any
> tasks' file tables) to being associated.
I can't use netfilter infrastructure because
it is too early to know who the recipant process of the packet is.
The only chance to perform ip/port based filtering
using ACLs associated with the recipant process of the packet
is post-accept() and post-recvmsg().
Therefore, I re-post my patch again.
Regards.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
include/linux/security.h | 44 +++++++++++++++++++++++++++++++++++++-------
net/socket.c | 42 ++++++++++++++++++++++++++++++++++++------
security/dummy.c | 13 ++++++++++---
3 files changed, 83 insertions(+), 16 deletions(-)
diff -upr a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h 2007-07-20 22:55:38.000000000 +0900
+++ b/include/linux/security.h 2007-07-20 23:15:58.000000000 +0900
@@ -749,8 +749,12 @@ struct request_sock;
* @socket_post_accept:
* This hook allows a security module to copy security
* information into the newly created socket's inode.
+ * This hook also allows a security module to filter connections
+ * from unwanted peers.
+ * The connection will be aborted if this hook returns nonzero.
* @sock contains the listening socket structure.
* @newsock contains the newly created server socket for connection.
+ * Return 0 if permission is granted.
* @socket_sendmsg:
* Check permission before transmitting a message to another socket.
* @sock contains the socket structure.
@@ -764,6 +768,15 @@ struct request_sock;
* @size contains the size of message structure.
* @flags contains the operational flags.
* Return 0 if permission is granted.
+ * @socket_post_recvmsg:
+ * Check peer's address after receiving a message from a socket.
+ * This hook allows a security module to filter messages
+ * from unwanted peers.
+ * @sock contains the socket structure.
+ * @msg contains the message structure.
+ * @size contains the size of message structure.
+ * @flags contains the operational flags.
+ * Return 0 if permission is granted.
* @socket_getsockname:
* Check permission before the local address (name) of the socket object
* @sock is retrieved.
@@ -1345,12 +1358,14 @@ struct security_operations {
struct sockaddr * address, int addrlen);
int (*socket_listen) (struct socket * sock, int backlog);
int (*socket_accept) (struct socket * sock, struct socket * newsock);
- void (*socket_post_accept) (struct socket * sock,
- struct socket * newsock);
+ int (*socket_post_accept) (struct socket *sock,
+ struct socket *newsock);
int (*socket_sendmsg) (struct socket * sock,
struct msghdr * msg, int size);
int (*socket_recvmsg) (struct socket * sock,
struct msghdr * msg, int size, int flags);
+ int (*socket_post_recvmsg) (struct socket *sock, struct msghdr *msg,
+ int size, int flags);
int (*socket_getsockname) (struct socket * sock);
int (*socket_getpeername) (struct socket * sock);
int (*socket_getsockopt) (struct socket * sock, int level, int optname);
@@ -2860,10 +2875,10 @@ static inline int security_socket_accept
return security_ops->socket_accept(sock, newsock);
}
-static inline void security_socket_post_accept(struct socket * sock,
- struct socket * newsock)
+static inline int security_socket_post_accept(struct socket *sock,
+ struct socket *newsock)
{
- security_ops->socket_post_accept(sock, newsock);
+ return security_ops->socket_post_accept(sock, newsock);
}
static inline int security_socket_sendmsg(struct socket * sock,
@@ -2879,6 +2894,13 @@ static inline int security_socket_recvms
return security_ops->socket_recvmsg(sock, msg, size, flags);
}
+static inline int security_socket_post_recvmsg(struct socket *sock,
+ struct msghdr *msg,
+ int size, int flags)
+{
+ return security_ops->socket_post_recvmsg(sock, msg, size, flags);
+}
+
static inline int security_socket_getsockname(struct socket * sock)
{
return security_ops->socket_getsockname(sock);
@@ -3023,9 +3045,10 @@ static inline int security_socket_accept
return 0;
}
-static inline void security_socket_post_accept(struct socket * sock,
- struct socket * newsock)
+static inline int security_socket_post_accept(struct socket *sock,
+ struct socket *newsock)
{
+ return 0;
}
static inline int security_socket_sendmsg(struct socket * sock,
@@ -3041,6 +3064,13 @@ static inline int security_socket_recvms
return 0;
}
+static inline int security_socket_post_recvmsg(struct socket *sock,
+ struct msghdr *msg,
+ int size, int flags)
+{
+ return 0;
+}
+
static inline int security_socket_getsockname(struct socket * sock)
{
return 0;
diff -upr a/net/socket.c b/net/socket.c
--- a/net/socket.c 2007-07-20 22:55:53.000000000 +0900
+++ b/net/socket.c 2007-07-21 00:05:18.000000000 +0900
@@ -635,7 +635,19 @@ static inline int __sock_recvmsg(struct
if (err)
return err;
- return sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ err = sock->ops->recvmsg(iocb, sock, msg, size, flags);
+ /*
+ * Filter messages from unwanted peers.
+ * To be exact, this hook can't filter messages,
+ * this hook just returns an error code.
+ */
+ if (err >= 0) {
+ int ret;
+ ret = security_socket_post_recvmsg(sock, msg, size, flags);
+ if (ret)
+ err = ret;
+ }
+ return err;
}
int sock_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -648,8 +660,17 @@ int sock_recvmsg(struct socket *sock, st
init_sync_kiocb(&iocb, NULL);
iocb.private = &siocb;
ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
- if (-EIOCBQUEUED == ret)
+ if (-EIOCBQUEUED == ret) {
ret = wait_on_sync_kiocb(&iocb);
+ /* I can now check security_socket_post_recvmsg(). */
+ if (ret >= 0) {
+ int err;
+ err = security_socket_post_recvmsg(sock, msg, size,
+ flags);
+ if (err)
+ ret = err;
+ }
+ }
return ret;
}
@@ -712,12 +733,14 @@ static ssize_t do_sock_read(struct msghd
struct socket *sock = file->private_data;
size_t size = 0;
int i;
+ /* only for security_socket_post_recvmsg() */
+ char address[MAX_SOCK_ADDR];
for (i = 0; i < nr_segs; i++)
size += iov[i].iov_len;
- msg->msg_name = NULL;
- msg->msg_namelen = 0;
+ msg->msg_name = address;
+ msg->msg_namelen = sizeof(address);
msg->msg_control = NULL;
msg->msg_controllen = 0;
msg->msg_iov = (struct iovec *)iov;
@@ -1437,13 +1460,16 @@ asmlinkage long sys_accept(int fd, struc
goto out_fd;
}
+ /* Filter connections from unwanted peers like TCP Wrapper. */
+ err = security_socket_post_accept(sock, newsock);
+ if (err)
+ goto out_fd;
+
/* File flags are not inherited via accept() unlike another OSes. */
fd_install(newfd, newfile);
err = newfd;
- security_socket_post_accept(sock, newsock);
-
out_put:
fput_light(sock->file, fput_needed);
out:
@@ -1937,6 +1963,10 @@ asmlinkage long sys_recvmsg(int fd, stru
goto out_freeiov;
total_len = err;
+ /* only for security_socket_post_recvmsg() */
+ msg_sys.msg_name = addr;
+ msg_sys.msg_namelen = sizeof(addr);
+
cmsg_ptr = (unsigned long)msg_sys.msg_control;
msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
diff -upr a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c 2007-07-20 22:55:54.000000000 +0900
+++ b/security/dummy.c 2007-07-20 23:15:22.000000000 +0900
@@ -741,10 +741,10 @@ static int dummy_socket_accept (struct s
return 0;
}
-static void dummy_socket_post_accept (struct socket *sock,
- struct socket *newsock)
+static int dummy_socket_post_accept(struct socket *sock,
+ struct socket *newsock)
{
- return;
+ return 0;
}
static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg,
@@ -759,6 +759,12 @@ static int dummy_socket_recvmsg (struct
return 0;
}
+static int dummy_socket_post_recvmsg(struct socket *sock, struct msghdr *msg,
+ int size, int flags)
+{
+ return 0;
+}
+
static int dummy_socket_getsockname (struct socket *sock)
{
return 0;
@@ -1096,6 +1102,7 @@ void security_fixup_ops (struct security
set_to_dummy_if_null(ops, socket_post_accept);
set_to_dummy_if_null(ops, socket_sendmsg);
set_to_dummy_if_null(ops, socket_recvmsg);
+ set_to_dummy_if_null(ops, socket_post_recvmsg);
set_to_dummy_if_null(ops, socket_getsockname);
set_to_dummy_if_null(ops, socket_getpeername);
set_to_dummy_if_null(ops, socket_setsockopt);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/1] Allow LSM to use IP address/port number.
2007-07-20 15:11 ` [PATCH 1/1] " Tetsuo Handa
@ 2007-07-20 15:28 ` James Morris
2007-07-20 15:44 ` Patrick McHardy
0 siblings, 1 reply; 12+ messages in thread
From: James Morris @ 2007-07-20 15:28 UTC (permalink / raw)
To: Tetsuo Handa; +Cc: shemminger, netdev, linux-security-module, Patrick McHardy
On Sat, 21 Jul 2007, Tetsuo Handa wrote:
> I can't use netfilter infrastructure because
> it is too early to know who the recipant process of the packet is.
I think the way forward on this is to re-visit the idea of providing a
proper solution for the incoming packet/user match problem.
I posted one possible solution a couple of years ago (skfilter):
http://lwn.net/Articles/157137/
I think there has been some recent discussion by netfilter developers
about this issue, so perhaps you could talk to them (cd'd Patrick).
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/1] Allow LSM to use IP address/port number.
2007-07-20 15:28 ` James Morris
@ 2007-07-20 15:44 ` Patrick McHardy
2007-07-21 1:57 ` Tetsuo Handa
0 siblings, 1 reply; 12+ messages in thread
From: Patrick McHardy @ 2007-07-20 15:44 UTC (permalink / raw)
To: James Morris; +Cc: Tetsuo Handa, shemminger, netdev, linux-security-module
James Morris wrote:
> On Sat, 21 Jul 2007, Tetsuo Handa wrote:
>
>
>> I can't use netfilter infrastructure because
>> it is too early to know who the recipant process of the packet is.
>>
>
> I think the way forward on this is to re-visit the idea of providing a
> proper solution for the incoming packet/user match problem.
>
> I posted one possible solution a couple of years ago (skfilter):
> http://lwn.net/Articles/157137/
>
> I think there has been some recent discussion by netfilter developers
> about this issue, so perhaps you could talk to them (cd'd Patrick)
>
Even with socket filters netfilter doesn't know the final receipient
process, that is not known until it calls recvmsg and the data is read,
which is too late for netfilter.
Quoting Tetsuo:
> > So, my approach is not using security context associated with a socket
> > but security context associated with a process.
Isn't the socket context derived from the process context?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/1] Allow LSM to use IP address/port number.
2007-07-20 15:44 ` Patrick McHardy
@ 2007-07-21 1:57 ` Tetsuo Handa
2007-07-21 18:11 ` Casey Schaufler
0 siblings, 1 reply; 12+ messages in thread
From: Tetsuo Handa @ 2007-07-21 1:57 UTC (permalink / raw)
To: kaber, jmorris; +Cc: netdev, linux-security-module
Hello.
Patrick McHardy wrote:
> Quoting Tetsuo:
> > > So, my approach is not using security context associated with a socket
> > > but security context associated with a process.
> Isn't the socket context derived from the process context?
Not so regarding my case.
static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
{
sk->sk_security = current->security;
return 0;
}
will not help what I want to do.
So, I'm not planning to use "sk->sk_security".
I'm planning to use "current->security" at accept()/recvmsg() time.
What I want to do is to enforce subset of TCP Wrapper inside the kernel space
so that "IP/port based filtering for TCP and UDP is applied to ALL processes"
and "IP/port based filtering for TCP and UDP is not bypassed by processes that are
linked with TCP Wrapper library (even if accept()/recvmsg() syscalls are directly called)".
To receive source IP/port of a incoming packet, non-NULL msg->msg_name is needed for receiving them,
and I'm proposing modifications in net/socket.c .
Regards.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/1] Allow LSM to use IP address/port number.
2007-07-21 1:57 ` Tetsuo Handa
@ 2007-07-21 18:11 ` Casey Schaufler
0 siblings, 0 replies; 12+ messages in thread
From: Casey Schaufler @ 2007-07-21 18:11 UTC (permalink / raw)
To: Tetsuo Handa, kaber, jmorris; +Cc: netdev, linux-security-module
--- Tetsuo Handa <from-netdev@I-love.SAKURA.ne.jp> wrote:
>
> Hello.
>
> Patrick McHardy wrote:
> > Quoting Tetsuo:
> > > > So, my approach is not using security context associated with a socket
> > > > but security context associated with a process.
> > Isn't the socket context derived from the process context?
> Not so regarding my case.
>
> static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t
> priority)
> {
> sk->sk_security = current->security;
> return 0;
> }
>
> will not help what I want to do.
> So, I'm not planning to use "sk->sk_security".
Before you go too far down this path please note that the quoted
code is bad* because back pointers from sockets to tasks can't be
reliable. See later versions for more reasonable behavior.
> I'm planning to use "current->security" at accept()/recvmsg() time.
The delivery of packets and the completion of these syscalls are
related but independent events. Be careful about the relationship
between the events and the placement of your checks.
----
* Stephen had good comments on the details on list earlier.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-07-21 18:11 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200707032107.CBD30767.PtGMNNTS@I-love.SAKURA.ne.jp>
[not found] ` <200707061114.07419.paul.moore@hp.com>
[not found] ` <200707070225.AFC45609.MNStNTPG@I-love.SAKURA.ne.jp>
[not found] ` <200707061343.03942.paul.moore@hp.com>
2007-07-09 5:33 ` [RFC] Allow LSM to use IP address/port number. (was Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.) Tetsuo Handa
2007-07-09 7:26 ` [RFC] Allow LSM to use IP address/port number David Miller
2007-07-09 13:13 ` Tetsuo Handa
2007-07-09 22:50 ` James Morris
2007-07-09 23:05 ` Stephen Hemminger
2007-07-09 23:41 ` James Morris
2007-07-10 4:11 ` Tetsuo Handa
2007-07-20 15:11 ` [PATCH 1/1] " Tetsuo Handa
2007-07-20 15:28 ` James Morris
2007-07-20 15:44 ` Patrick McHardy
2007-07-21 1:57 ` Tetsuo Handa
2007-07-21 18:11 ` Casey Schaufler
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).