// SPDX-License-Identifier: GPL-2.0-only /* * Network port table * * SELinux must keep a mapping of network ports to labels/SIDs. This * mapping is maintained as part of the normal policy but a fast cache is * needed to reduce the lookup overhead. * * Author: Paul Moore <paul@paul-moore.com> * * This code is heavily based on the "netif" concept originally developed by * James Morris <jmorris@redhat.com> * (see security/selinux/netif.c for more information)
*/
/* * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
*/
/** * sel_netport_hashfn - Hashing function for the port table * @pnum: port number * * Description: * This is the hashing function for the port table, it returns the bucket * number for the given port. *
*/ staticunsignedint sel_netport_hashfn(u16 pnum)
{ return (pnum & (SEL_NETPORT_HASH_SIZE - 1));
}
/** * sel_netport_find - Search for a port record * @protocol: protocol * @pnum: port * * Description: * Search the network port table and return the matching record. If an entry * can not be found in the table return NULL. *
*/ staticstruct sel_netport *sel_netport_find(u8 protocol, u16 pnum)
{ unsignedint idx; struct sel_netport *port;
/** * sel_netport_insert - Insert a new port into the table * @port: the new port record * * Description: * Add a new port record to the network address hash table. *
*/ staticvoid sel_netport_insert(struct sel_netport *port)
{ unsignedint idx;
/* we need to impose a limit on the growth of the hash table so check
* this bucket to make sure it is within the specified bounds */
idx = sel_netport_hashfn(port->psec.port);
list_add_rcu(&port->list, &sel_netport_hash[idx].list); if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { struct sel_netport *tail;
tail = list_entry(
rcu_dereference_protected(
list_tail_rcu(&sel_netport_hash[idx].list),
lockdep_is_held(&sel_netport_lock)), struct sel_netport, list);
list_del_rcu(&tail->list);
kfree_rcu(tail, rcu);
} else
sel_netport_hash[idx].size++;
}
/** * sel_netport_sid_slow - Lookup the SID of a network address using the policy * @protocol: protocol * @pnum: port * @sid: port SID * * Description: * This function determines the SID of a network port by querying the security * policy. The result is added to the network port table to speedup future * queries. Returns zero on success, negative values on failure. *
*/ staticint sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
{ int ret; struct sel_netport *port; struct sel_netport *new;
spin_lock_bh(&sel_netport_lock);
port = sel_netport_find(protocol, pnum); if (port != NULL) {
*sid = port->psec.sid;
spin_unlock_bh(&sel_netport_lock); return 0;
}
ret = security_port_sid(protocol, pnum, sid); if (ret != 0) goto out;
/* If this memory allocation fails still return 0. The SID * is valid, it just won't be added to the cache.
*/ new = kmalloc(sizeof(*new), GFP_ATOMIC); if (new) {
new->psec.port = pnum;
new->psec.protocol = protocol;
new->psec.sid = *sid;
sel_netport_insert(new);
}
out:
spin_unlock_bh(&sel_netport_lock); if (unlikely(ret))
pr_warn("SELinux: failure in %s(), unable to determine network port label\n",
__func__); return ret;
}
/** * sel_netport_sid - Lookup the SID of a network port * @protocol: protocol * @pnum: port * @sid: port SID * * Description: * This function determines the SID of a network port using the fastest method * possible. First the port table is queried, but if an entry can't be found * then the policy is queried and the result is added to the table to speedup * future queries. Returns zero on success, negative values on failure. *
*/ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
{ struct sel_netport *port;
rcu_read_lock();
port = sel_netport_find(protocol, pnum); if (likely(port != NULL)) {
*sid = port->psec.sid;
rcu_read_unlock(); return 0;
}
rcu_read_unlock();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.