0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "include/apparmor.h"
0012 #include "include/audit.h"
0013 #include "include/cred.h"
0014 #include "include/label.h"
0015 #include "include/net.h"
0016 #include "include/policy.h"
0017 #include "include/secid.h"
0018
0019 #include "net_names.h"
0020
0021
0022 struct aa_sfs_entry aa_sfs_entry_network[] = {
0023 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
0024 { }
0025 };
0026
0027 static const char * const net_mask_names[] = {
0028 "unknown",
0029 "send",
0030 "receive",
0031 "unknown",
0032
0033 "create",
0034 "shutdown",
0035 "connect",
0036 "unknown",
0037
0038 "setattr",
0039 "getattr",
0040 "setcred",
0041 "getcred",
0042
0043 "chmod",
0044 "chown",
0045 "chgrp",
0046 "lock",
0047
0048 "mmap",
0049 "mprot",
0050 "unknown",
0051 "unknown",
0052
0053 "accept",
0054 "bind",
0055 "listen",
0056 "unknown",
0057
0058 "setopt",
0059 "getopt",
0060 "unknown",
0061 "unknown",
0062
0063 "unknown",
0064 "unknown",
0065 "unknown",
0066 "unknown",
0067 };
0068
0069
0070
0071 void audit_net_cb(struct audit_buffer *ab, void *va)
0072 {
0073 struct common_audit_data *sa = va;
0074
0075 if (address_family_names[sa->u.net->family])
0076 audit_log_format(ab, " family=\"%s\"",
0077 address_family_names[sa->u.net->family]);
0078 else
0079 audit_log_format(ab, " family=\"unknown(%d)\"",
0080 sa->u.net->family);
0081 if (sock_type_names[aad(sa)->net.type])
0082 audit_log_format(ab, " sock_type=\"%s\"",
0083 sock_type_names[aad(sa)->net.type]);
0084 else
0085 audit_log_format(ab, " sock_type=\"unknown(%d)\"",
0086 aad(sa)->net.type);
0087 audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
0088
0089 if (aad(sa)->request & NET_PERMS_MASK) {
0090 audit_log_format(ab, " requested_mask=");
0091 aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
0092 net_mask_names, NET_PERMS_MASK);
0093
0094 if (aad(sa)->denied & NET_PERMS_MASK) {
0095 audit_log_format(ab, " denied_mask=");
0096 aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
0097 net_mask_names, NET_PERMS_MASK);
0098 }
0099 }
0100 if (aad(sa)->peer) {
0101 audit_log_format(ab, " peer=");
0102 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
0103 FLAGS_NONE, GFP_ATOMIC);
0104 }
0105 }
0106
0107
0108 int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
0109 u32 request, u16 family, int type)
0110 {
0111 struct aa_perms perms = { };
0112 unsigned int state;
0113 __be16 buffer[2];
0114
0115 AA_BUG(family >= AF_MAX);
0116 AA_BUG(type < 0 || type >= SOCK_MAX);
0117
0118 if (profile_unconfined(profile))
0119 return 0;
0120 state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
0121 if (!state)
0122 return 0;
0123
0124 buffer[0] = cpu_to_be16(family);
0125 buffer[1] = cpu_to_be16((u16) type);
0126 state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
0127 4);
0128 aa_compute_perms(profile->policy.dfa, state, &perms);
0129 aa_apply_modes_to_perms(profile, &perms);
0130
0131 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
0132 }
0133
0134 int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
0135 int type, int protocol)
0136 {
0137 struct aa_profile *profile;
0138 DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
0139
0140 return fn_for_each_confined(label, profile,
0141 aa_profile_af_perm(profile, &sa, request, family,
0142 type));
0143 }
0144
0145 static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
0146 struct sock *sk)
0147 {
0148 struct aa_sk_ctx *ctx = SK_CTX(sk);
0149 int error = 0;
0150
0151 AA_BUG(!label);
0152 AA_BUG(!sk);
0153
0154 if (ctx->label != kernel_t && !unconfined(label)) {
0155 struct aa_profile *profile;
0156 DEFINE_AUDIT_SK(sa, op, sk);
0157
0158 error = fn_for_each_confined(label, profile,
0159 aa_profile_af_sk_perm(profile, &sa, request, sk));
0160 }
0161
0162 return error;
0163 }
0164
0165 int aa_sk_perm(const char *op, u32 request, struct sock *sk)
0166 {
0167 struct aa_label *label;
0168 int error;
0169
0170 AA_BUG(!sk);
0171 AA_BUG(in_interrupt());
0172
0173
0174 label = begin_current_label_crit_section();
0175 error = aa_label_sk_perm(label, op, request, sk);
0176 end_current_label_crit_section(label);
0177
0178 return error;
0179 }
0180
0181
0182 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
0183 struct socket *sock)
0184 {
0185 AA_BUG(!label);
0186 AA_BUG(!sock);
0187 AA_BUG(!sock->sk);
0188
0189 return aa_label_sk_perm(label, op, request, sock->sk);
0190 }
0191
0192 #ifdef CONFIG_NETWORK_SECMARK
0193 static int apparmor_secmark_init(struct aa_secmark *secmark)
0194 {
0195 struct aa_label *label;
0196
0197 if (secmark->label[0] == '*') {
0198 secmark->secid = AA_SECID_WILDCARD;
0199 return 0;
0200 }
0201
0202 label = aa_label_strn_parse(&root_ns->unconfined->label,
0203 secmark->label, strlen(secmark->label),
0204 GFP_ATOMIC, false, false);
0205
0206 if (IS_ERR(label))
0207 return PTR_ERR(label);
0208
0209 secmark->secid = label->secid;
0210
0211 return 0;
0212 }
0213
0214 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
0215 struct common_audit_data *sa)
0216 {
0217 int i, ret;
0218 struct aa_perms perms = { };
0219
0220 if (profile->secmark_count == 0)
0221 return 0;
0222
0223 for (i = 0; i < profile->secmark_count; i++) {
0224 if (!profile->secmark[i].secid) {
0225 ret = apparmor_secmark_init(&profile->secmark[i]);
0226 if (ret)
0227 return ret;
0228 }
0229
0230 if (profile->secmark[i].secid == secid ||
0231 profile->secmark[i].secid == AA_SECID_WILDCARD) {
0232 if (profile->secmark[i].deny)
0233 perms.deny = ALL_PERMS_MASK;
0234 else
0235 perms.allow = ALL_PERMS_MASK;
0236
0237 if (profile->secmark[i].audit)
0238 perms.audit = ALL_PERMS_MASK;
0239 }
0240 }
0241
0242 aa_apply_modes_to_perms(profile, &perms);
0243
0244 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
0245 }
0246
0247 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
0248 u32 secid, const struct sock *sk)
0249 {
0250 struct aa_profile *profile;
0251 DEFINE_AUDIT_SK(sa, op, sk);
0252
0253 return fn_for_each_confined(label, profile,
0254 aa_secmark_perm(profile, request, secid,
0255 &sa));
0256 }
0257 #endif