函数源码

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source File:security\smack\smack_lsm.c Create Date:2022-07-27 20:53:35
首页 Copyright©Brick

4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
/**
 * smack_inet_conn_request - Smack access check on connect
 * @sk: socket involved
 * @skb: packet
 * @req: unused
 *
 * Returns 0 if a task with the packet label could write to
 * the socket, otherwise an error code
 */
static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
                   struct request_sock *req)
{
    u16 family = sk->sk_family;
    struct smack_known *skp;
    struct socket_smack *ssp = sk->sk_security;
    struct netlbl_lsm_secattr secattr;
    struct sockaddr_in addr;
    struct iphdr *hdr;
    struct smack_known *hskp;
    int rc;
    struct smk_audit_info ad;
#ifdef CONFIG_AUDIT
    struct lsm_network_audit net;
#endif
 
#if IS_ENABLED(CONFIG_IPV6)
    if (family == PF_INET6) {
        /*
         * Handle mapped IPv4 packets arriving
         * via IPv6 sockets. Don't set up netlabel
         * processing on IPv6.
         */
        if (skb->protocol == htons(ETH_P_IP))
            family = PF_INET;
        else
            return 0;
    }
#endif /* CONFIG_IPV6 */
 
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
    /*
     * If there is a secmark use it rather than the CIPSO label.
     * If there is no secmark fall back to CIPSO.
     * The secmark is assumed to reflect policy better.
     */
    if (skb && skb->secmark != 0) {
        skp = smack_from_secid(skb->secmark);
        goto access_check;
    }
#endif /* CONFIG_SECURITY_SMACK_NETFILTER */
 
    netlbl_secattr_init(&secattr);
    rc = netlbl_skbuff_getattr(skb, family, &secattr);
    if (rc == 0)
        skp = smack_from_secattr(&secattr, ssp);
    else
        skp = &smack_known_huh;
    netlbl_secattr_destroy(&secattr);
 
#ifdef CONFIG_SECURITY_SMACK_NETFILTER
access_check:
#endif
 
#ifdef CONFIG_AUDIT
    smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
    ad.a.u.net->family = family;
    ad.a.u.net->netif = skb->skb_iif;
    ipv4_skb_to_auditdata(skb, &ad.a, NULL);
#endif
    /*
     * Receiving a packet requires that the other end be able to write
     * here. Read access is not required.
     */
    rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
    rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc);
    if (rc != 0)
        return rc;
 
    /*
     * Save the peer's label in the request_sock so we can later setup
     * smk_packet in the child socket so that SO_PEERCRED can report it.
     */
    req->peer_secid = skp->smk_secid;
 
    /*
     * We need to decide if we want to label the incoming connection here
     * if we do we only need to label the request_sock and the stack will
     * propagate the wire-label to the sock when it is created.
     */
    hdr = ip_hdr(skb);
    addr.sin_addr.s_addr = hdr->saddr;
    rcu_read_lock();
    hskp = smack_ipv4host_label(&addr);
    rcu_read_unlock();
 
    if (hskp == NULL)
        rc = netlbl_req_setattr(req, &skp->smk_netlabel);
    else
        netlbl_req_delattr(req);
 
    return rc;
}