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