Sorry, I failed to send this message to netdev ml. Please ignore.

On Mon, 09 Jul 2007 13:29:44 +0900
Tetsuo Handa <[EMAIL PROTECTED]> wrote:

> 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 <[EMAIL PROTECTED]>
> ---
>  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);
> -
> To unsubscribe from this list: send the line \"unsubscribe 
> linux-security-module\" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to