1*56974a6fSJohn Johansen /* 2*56974a6fSJohn Johansen * AppArmor security module 3*56974a6fSJohn Johansen * 4*56974a6fSJohn Johansen * This file contains AppArmor network mediation 5*56974a6fSJohn Johansen * 6*56974a6fSJohn Johansen * Copyright (C) 1998-2008 Novell/SUSE 7*56974a6fSJohn Johansen * Copyright 2009-2017 Canonical Ltd. 8*56974a6fSJohn Johansen * 9*56974a6fSJohn Johansen * This program is free software; you can redistribute it and/or 10*56974a6fSJohn Johansen * modify it under the terms of the GNU General Public License as 11*56974a6fSJohn Johansen * published by the Free Software Foundation, version 2 of the 12*56974a6fSJohn Johansen * License. 13*56974a6fSJohn Johansen */ 14*56974a6fSJohn Johansen 15*56974a6fSJohn Johansen #include "include/apparmor.h" 16*56974a6fSJohn Johansen #include "include/audit.h" 17*56974a6fSJohn Johansen #include "include/cred.h" 18*56974a6fSJohn Johansen #include "include/label.h" 19*56974a6fSJohn Johansen #include "include/net.h" 20*56974a6fSJohn Johansen #include "include/policy.h" 21*56974a6fSJohn Johansen 22*56974a6fSJohn Johansen #include "net_names.h" 23*56974a6fSJohn Johansen 24*56974a6fSJohn Johansen 25*56974a6fSJohn Johansen struct aa_sfs_entry aa_sfs_entry_network[] = { 26*56974a6fSJohn Johansen AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK), 27*56974a6fSJohn Johansen { } 28*56974a6fSJohn Johansen }; 29*56974a6fSJohn Johansen 30*56974a6fSJohn Johansen static const char * const net_mask_names[] = { 31*56974a6fSJohn Johansen "unknown", 32*56974a6fSJohn Johansen "send", 33*56974a6fSJohn Johansen "receive", 34*56974a6fSJohn Johansen "unknown", 35*56974a6fSJohn Johansen 36*56974a6fSJohn Johansen "create", 37*56974a6fSJohn Johansen "shutdown", 38*56974a6fSJohn Johansen "connect", 39*56974a6fSJohn Johansen "unknown", 40*56974a6fSJohn Johansen 41*56974a6fSJohn Johansen "setattr", 42*56974a6fSJohn Johansen "getattr", 43*56974a6fSJohn Johansen "setcred", 44*56974a6fSJohn Johansen "getcred", 45*56974a6fSJohn Johansen 46*56974a6fSJohn Johansen "chmod", 47*56974a6fSJohn Johansen "chown", 48*56974a6fSJohn Johansen "chgrp", 49*56974a6fSJohn Johansen "lock", 50*56974a6fSJohn Johansen 51*56974a6fSJohn Johansen "mmap", 52*56974a6fSJohn Johansen "mprot", 53*56974a6fSJohn Johansen "unknown", 54*56974a6fSJohn Johansen "unknown", 55*56974a6fSJohn Johansen 56*56974a6fSJohn Johansen "accept", 57*56974a6fSJohn Johansen "bind", 58*56974a6fSJohn Johansen "listen", 59*56974a6fSJohn Johansen "unknown", 60*56974a6fSJohn Johansen 61*56974a6fSJohn Johansen "setopt", 62*56974a6fSJohn Johansen "getopt", 63*56974a6fSJohn Johansen "unknown", 64*56974a6fSJohn Johansen "unknown", 65*56974a6fSJohn Johansen 66*56974a6fSJohn Johansen "unknown", 67*56974a6fSJohn Johansen "unknown", 68*56974a6fSJohn Johansen "unknown", 69*56974a6fSJohn Johansen "unknown", 70*56974a6fSJohn Johansen }; 71*56974a6fSJohn Johansen 72*56974a6fSJohn Johansen 73*56974a6fSJohn Johansen /* audit callback for net specific fields */ 74*56974a6fSJohn Johansen void audit_net_cb(struct audit_buffer *ab, void *va) 75*56974a6fSJohn Johansen { 76*56974a6fSJohn Johansen struct common_audit_data *sa = va; 77*56974a6fSJohn Johansen 78*56974a6fSJohn Johansen audit_log_format(ab, " family="); 79*56974a6fSJohn Johansen if (address_family_names[sa->u.net->family]) 80*56974a6fSJohn Johansen audit_log_string(ab, address_family_names[sa->u.net->family]); 81*56974a6fSJohn Johansen else 82*56974a6fSJohn Johansen audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family); 83*56974a6fSJohn Johansen audit_log_format(ab, " sock_type="); 84*56974a6fSJohn Johansen if (sock_type_names[aad(sa)->net.type]) 85*56974a6fSJohn Johansen audit_log_string(ab, sock_type_names[aad(sa)->net.type]); 86*56974a6fSJohn Johansen else 87*56974a6fSJohn Johansen audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type); 88*56974a6fSJohn Johansen audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); 89*56974a6fSJohn Johansen 90*56974a6fSJohn Johansen if (aad(sa)->request & NET_PERMS_MASK) { 91*56974a6fSJohn Johansen audit_log_format(ab, " requested_mask="); 92*56974a6fSJohn Johansen aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, 93*56974a6fSJohn Johansen net_mask_names, NET_PERMS_MASK); 94*56974a6fSJohn Johansen 95*56974a6fSJohn Johansen if (aad(sa)->denied & NET_PERMS_MASK) { 96*56974a6fSJohn Johansen audit_log_format(ab, " denied_mask="); 97*56974a6fSJohn Johansen aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, 98*56974a6fSJohn Johansen net_mask_names, NET_PERMS_MASK); 99*56974a6fSJohn Johansen } 100*56974a6fSJohn Johansen } 101*56974a6fSJohn Johansen if (aad(sa)->peer) { 102*56974a6fSJohn Johansen audit_log_format(ab, " peer="); 103*56974a6fSJohn Johansen aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, 104*56974a6fSJohn Johansen FLAGS_NONE, GFP_ATOMIC); 105*56974a6fSJohn Johansen } 106*56974a6fSJohn Johansen } 107*56974a6fSJohn Johansen 108*56974a6fSJohn Johansen /* Generic af perm */ 109*56974a6fSJohn Johansen int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, 110*56974a6fSJohn Johansen u32 request, u16 family, int type) 111*56974a6fSJohn Johansen { 112*56974a6fSJohn Johansen struct aa_perms perms = { }; 113*56974a6fSJohn Johansen unsigned int state; 114*56974a6fSJohn Johansen __be16 buffer[2]; 115*56974a6fSJohn Johansen 116*56974a6fSJohn Johansen AA_BUG(family >= AF_MAX); 117*56974a6fSJohn Johansen AA_BUG(type < 0 || type >= SOCK_MAX); 118*56974a6fSJohn Johansen 119*56974a6fSJohn Johansen if (profile_unconfined(profile)) 120*56974a6fSJohn Johansen return 0; 121*56974a6fSJohn Johansen state = PROFILE_MEDIATES(profile, AA_CLASS_NET); 122*56974a6fSJohn Johansen if (!state) 123*56974a6fSJohn Johansen return 0; 124*56974a6fSJohn Johansen 125*56974a6fSJohn Johansen buffer[0] = cpu_to_be16(family); 126*56974a6fSJohn Johansen buffer[1] = cpu_to_be16((u16) type); 127*56974a6fSJohn Johansen state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer, 128*56974a6fSJohn Johansen 4); 129*56974a6fSJohn Johansen aa_compute_perms(profile->policy.dfa, state, &perms); 130*56974a6fSJohn Johansen aa_apply_modes_to_perms(profile, &perms); 131*56974a6fSJohn Johansen 132*56974a6fSJohn Johansen return aa_check_perms(profile, &perms, request, sa, audit_net_cb); 133*56974a6fSJohn Johansen } 134*56974a6fSJohn Johansen 135*56974a6fSJohn Johansen int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, 136*56974a6fSJohn Johansen int type, int protocol) 137*56974a6fSJohn Johansen { 138*56974a6fSJohn Johansen struct aa_profile *profile; 139*56974a6fSJohn Johansen DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); 140*56974a6fSJohn Johansen 141*56974a6fSJohn Johansen return fn_for_each_confined(label, profile, 142*56974a6fSJohn Johansen aa_profile_af_perm(profile, &sa, request, family, 143*56974a6fSJohn Johansen type)); 144*56974a6fSJohn Johansen } 145*56974a6fSJohn Johansen 146*56974a6fSJohn Johansen static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, 147*56974a6fSJohn Johansen struct sock *sk) 148*56974a6fSJohn Johansen { 149*56974a6fSJohn Johansen struct aa_profile *profile; 150*56974a6fSJohn Johansen DEFINE_AUDIT_SK(sa, op, sk); 151*56974a6fSJohn Johansen 152*56974a6fSJohn Johansen AA_BUG(!label); 153*56974a6fSJohn Johansen AA_BUG(!sk); 154*56974a6fSJohn Johansen 155*56974a6fSJohn Johansen if (unconfined(label)) 156*56974a6fSJohn Johansen return 0; 157*56974a6fSJohn Johansen 158*56974a6fSJohn Johansen return fn_for_each_confined(label, profile, 159*56974a6fSJohn Johansen aa_profile_af_sk_perm(profile, &sa, request, sk)); 160*56974a6fSJohn Johansen } 161*56974a6fSJohn Johansen 162*56974a6fSJohn Johansen int aa_sk_perm(const char *op, u32 request, struct sock *sk) 163*56974a6fSJohn Johansen { 164*56974a6fSJohn Johansen struct aa_label *label; 165*56974a6fSJohn Johansen int error; 166*56974a6fSJohn Johansen 167*56974a6fSJohn Johansen AA_BUG(!sk); 168*56974a6fSJohn Johansen AA_BUG(in_interrupt()); 169*56974a6fSJohn Johansen 170*56974a6fSJohn Johansen /* TODO: switch to begin_current_label ???? */ 171*56974a6fSJohn Johansen label = begin_current_label_crit_section(); 172*56974a6fSJohn Johansen error = aa_label_sk_perm(label, op, request, sk); 173*56974a6fSJohn Johansen end_current_label_crit_section(label); 174*56974a6fSJohn Johansen 175*56974a6fSJohn Johansen return error; 176*56974a6fSJohn Johansen } 177*56974a6fSJohn Johansen 178*56974a6fSJohn Johansen 179*56974a6fSJohn Johansen int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, 180*56974a6fSJohn Johansen struct socket *sock) 181*56974a6fSJohn Johansen { 182*56974a6fSJohn Johansen AA_BUG(!label); 183*56974a6fSJohn Johansen AA_BUG(!sock); 184*56974a6fSJohn Johansen AA_BUG(!sock->sk); 185*56974a6fSJohn Johansen 186*56974a6fSJohn Johansen return aa_label_sk_perm(label, op, request, sock->sk); 187*56974a6fSJohn Johansen } 188