123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /*
- * AppArmor security module
- *
- * This file contains AppArmor network mediation
- *
- * Copyright (C) 1998-2008 Novell/SUSE
- * Copyright 2009-2017 Canonical Ltd.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- */
- #include "include/apparmor.h"
- #include "include/audit.h"
- #include "include/cred.h"
- #include "include/label.h"
- #include "include/net.h"
- #include "include/policy.h"
- #include "net_names.h"
- struct aa_sfs_entry aa_sfs_entry_network[] = {
- AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
- { }
- };
- static const char * const net_mask_names[] = {
- "unknown",
- "send",
- "receive",
- "unknown",
- "create",
- "shutdown",
- "connect",
- "unknown",
- "setattr",
- "getattr",
- "setcred",
- "getcred",
- "chmod",
- "chown",
- "chgrp",
- "lock",
- "mmap",
- "mprot",
- "unknown",
- "unknown",
- "accept",
- "bind",
- "listen",
- "unknown",
- "setopt",
- "getopt",
- "unknown",
- "unknown",
- "unknown",
- "unknown",
- "unknown",
- "unknown",
- };
- /* audit callback for net specific fields */
- void audit_net_cb(struct audit_buffer *ab, void *va)
- {
- struct common_audit_data *sa = va;
- audit_log_format(ab, " family=");
- if (address_family_names[sa->u.net->family])
- audit_log_string(ab, address_family_names[sa->u.net->family]);
- else
- audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
- audit_log_format(ab, " sock_type=");
- if (sock_type_names[aad(sa)->net.type])
- audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
- else
- audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
- audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
- if (aad(sa)->request & NET_PERMS_MASK) {
- audit_log_format(ab, " requested_mask=");
- aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
- net_mask_names, NET_PERMS_MASK);
- if (aad(sa)->denied & NET_PERMS_MASK) {
- audit_log_format(ab, " denied_mask=");
- aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
- net_mask_names, NET_PERMS_MASK);
- }
- }
- if (aad(sa)->peer) {
- audit_log_format(ab, " peer=");
- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
- FLAGS_NONE, GFP_ATOMIC);
- }
- }
- /* Generic af perm */
- int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
- u32 request, u16 family, int type)
- {
- struct aa_perms perms = { };
- unsigned int state;
- __be16 buffer[2];
- AA_BUG(family >= AF_MAX);
- AA_BUG(type < 0 || type >= SOCK_MAX);
- if (profile_unconfined(profile))
- return 0;
- state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
- if (!state)
- return 0;
- buffer[0] = cpu_to_be16(family);
- buffer[1] = cpu_to_be16((u16) type);
- state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
- 4);
- aa_compute_perms(profile->policy.dfa, state, &perms);
- aa_apply_modes_to_perms(profile, &perms);
- return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
- }
- int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
- int type, int protocol)
- {
- struct aa_profile *profile;
- DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
- return fn_for_each_confined(label, profile,
- aa_profile_af_perm(profile, &sa, request, family,
- type));
- }
- static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
- struct sock *sk)
- {
- int error = 0;
- AA_BUG(!label);
- AA_BUG(!sk);
- if (!unconfined(label)) {
- struct aa_profile *profile;
- DEFINE_AUDIT_SK(sa, op, sk);
- error = fn_for_each_confined(label, profile,
- aa_profile_af_sk_perm(profile, &sa, request, sk));
- }
- return error;
- }
- int aa_sk_perm(const char *op, u32 request, struct sock *sk)
- {
- struct aa_label *label;
- int error;
- AA_BUG(!sk);
- AA_BUG(in_interrupt());
- /* TODO: switch to begin_current_label ???? */
- label = begin_current_label_crit_section();
- error = aa_label_sk_perm(label, op, request, sk);
- end_current_label_crit_section(label);
- return error;
- }
- int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
- struct socket *sock)
- {
- AA_BUG(!label);
- AA_BUG(!sock);
- AA_BUG(!sock->sk);
- return aa_label_sk_perm(label, op, request, sock->sk);
- }
|