TOMOYO Linux(undone)

Andrew.Hann發表於2014-12-08

目錄

1. TOMOYO Introduction
2. TOMOYO Sourcecode Analysis

 

1. Introduction

TOMOYO是一款基於LSM Framework實現的LSMs(安全模組)

Relevant Link:

http://lxr.free-electrons.com/source/Documentation/security/tomoyo.txt

 

2. TOMOYO Sourcecode Analysis

以網路連線狀態函式(sys_connect)的監控(tomoyo_socket_connect)的監控log作為例子

/source/security/tomoyo/tomoyo.c

/**
* tomoyo_socket_connect - Check permission for connect().
*
* @sock:     Pointer to "struct socket".
* @addr:     Pointer to "struct sockaddr".
* @addr_len: Size of @addr.
*
* Returns 0 on success, negative value otherwise.
*/
static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr, int addr_len)
{
    return tomoyo_socket_connect_permission(sock, addr, addr_len);
}

/source/security/tomoyo/network.c

/**
* tomoyo_sock_family - Get socket's family.
*
* @sk: Pointer to "struct sock".
*
* Returns one of PF_INET, PF_INET6, PF_UNIX or 0.
*/
static u8 tomoyo_sock_family(struct sock *sk)
{
     u8 family;

    if (tomoyo_kernel_service())
        return 0;
    family = sk->sk_family;
    switch (family) 
    {
        case PF_INET:
        case PF_INET6:
        case PF_UNIX:
            return family;
        default:
            return 0;
    }
}

/**
* tomoyo_socket_connect_permission - Check permission for setting the remote address of a socket.
*
* @sock:     Pointer to "struct socket".
* @addr:     Pointer to "struct sockaddr".
* @addr_len: Size of @addr.
*
* Returns 0 on success, negative value otherwise.
*/
int tomoyo_socket_connect_permission(struct socket *sock, struct sockaddr *addr, int addr_len)
{
    struct tomoyo_addr_info address;
    //Get socket's family.(family是鏈路層的概念)
    const u8 family = tomoyo_sock_family(sock->sk);
    //socket的型別(TCP、UDP...)(type是傳輸層的概念)
    const unsigned int type = sock->type;

    if (!family)
        return 0;
    address.protocol = type;
    switch (type) 
    {
        case SOCK_DGRAM:
        case SOCK_RAW:
            address.operation = TOMOYO_NETWORK_SEND;
            break;
        case SOCK_STREAM:
        case SOCK_SEQPACKET:
            address.operation = TOMOYO_NETWORK_CONNECT;
            break;
        default:
            return 0;
    }
    if (family == PF_UNIX)
        return tomoyo_check_unix_address(addr, addr_len, &address);

    return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol, &address);
}


/* Structure for holding socket address. */
struct tomoyo_addr_info 
{
    u8 protocol;
    u8 operation;
    struct tomoyo_inet_addr_info inet;
    struct tomoyo_unix_addr_info unix0;
};
 

static int tomoyo_check_inet_address(const struct sockaddr *addr, const unsigned int addr_len, const u16 port, struct tomoyo_addr_info *address)
{
    struct tomoyo_inet_addr_info *i = &address->inet;
    
    switch (addr->sa_family) 
    {
        case AF_INET6:
            if (addr_len < SIN6_LEN_RFC2133)
                goto skip;
            i->is_ipv6 = true;
            i->address = (__be32 *)((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
            i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
            break;
        case AF_INET:
            if (addr_len < sizeof(struct sockaddr_in))
                goto skip;
            i->is_ipv6 = false;
            i->address = (__be32 *) &((struct sockaddr_in *) addr)->sin_addr;
            i->port = ((struct sockaddr_in *) addr)->sin_port;
            break;
        default:
            goto skip;
    }
    if (address->protocol == SOCK_RAW)
        i->port = htons(port);
    return tomoyo_inet_entry(address);
    skip:
        return 0;
}

Relevant Link:

 

Copyright (c) 2014 LittleHann All rights reserved

 

相關文章