mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 14:25:52 +00:00
parser: add support for kernel 4.17 v8 networking
Make it so the parser can properly support network socket mediation in the upstream kernel, MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/521 Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
@@ -196,17 +196,11 @@ void unix_rule::downgrade_rule(Profile &prof) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t map_perms(uint32_t mask)
|
||||
{
|
||||
return (mask & 0x7f) |
|
||||
((mask & (AA_NET_GETATTR | AA_NET_SETATTR)) << (AA_OTHER_SHIFT - 8)) |
|
||||
((mask & (AA_NET_ACCEPT | AA_NET_BIND | AA_NET_LISTEN)) >> 4) | /* 2 + (AA_OTHER_SHIFT - 20) */
|
||||
((mask & (AA_NET_SETOPT | AA_NET_GETOPT)) >> 5); /* 5 + (AA_OTHER_SHIFT - 24) */
|
||||
}
|
||||
|
||||
void unix_rule::write_to_prot(std::ostringstream &buffer)
|
||||
{
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NET;
|
||||
int c = features_supports_networkv8 ? AA_CLASS_NETV8 : AA_CLASS_NET;
|
||||
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << c;
|
||||
writeu16(buffer, AF_UNIX);
|
||||
if (sock_type)
|
||||
writeu16(buffer, sock_type_n);
|
||||
@@ -306,7 +300,7 @@ int unix_rule::gen_policy_re(Profile &prof)
|
||||
*/
|
||||
downgrade_rule(prof);
|
||||
if (!features_supports_unix) {
|
||||
if (features_supports_network) {
|
||||
if (features_supports_network || features_supports_networkv8) {
|
||||
/* only warn if we are building against a kernel
|
||||
* that requires downgrading */
|
||||
if (warnflags & WARN_RULE_DOWNGRADED)
|
||||
|
@@ -91,6 +91,15 @@ struct aa_network_entry {
|
||||
struct aa_network_entry *next;
|
||||
};
|
||||
|
||||
static inline uint32_t map_perms(uint32_t mask)
|
||||
{
|
||||
return (mask & 0x7f) |
|
||||
((mask & (AA_NET_GETATTR | AA_NET_SETATTR)) << (AA_OTHER_SHIFT - 8)) |
|
||||
((mask & (AA_NET_ACCEPT | AA_NET_BIND | AA_NET_LISTEN)) >> 4) | /* 2 + (AA_OTHER_SHIFT - 20) */
|
||||
((mask & (AA_NET_SETOPT | AA_NET_GETOPT)) >> 5); /* 5 + (AA_OTHER_SHIFT - 24) */
|
||||
};
|
||||
|
||||
|
||||
int parse_net_mode(const char *str_mode, int *mode, int fail);
|
||||
extern struct aa_network_entry *new_network_ent(unsigned int family,
|
||||
unsigned int type,
|
||||
|
@@ -330,6 +330,7 @@ extern int net_af_max_override;
|
||||
extern int kernel_load;
|
||||
extern int kernel_supports_setload;
|
||||
extern int features_supports_network;
|
||||
extern int features_supports_networkv8;
|
||||
extern int kernel_supports_policydb;
|
||||
extern int kernel_supports_diff_encode;
|
||||
extern int features_supports_mount;
|
||||
|
@@ -67,6 +67,7 @@ int net_af_max_override = -1; /* use kernel to determine af_max */
|
||||
int kernel_load = 1;
|
||||
int kernel_supports_setload = 0; /* kernel supports atomic set loads */
|
||||
int features_supports_network = 0; /* kernel supports network rules */
|
||||
int features_supports_networkv8 = 0; /* kernel supports 4.17 network rules */
|
||||
int features_supports_unix = 0; /* kernel supports unix socket rules */
|
||||
int kernel_supports_policydb = 0; /* kernel supports new policydb */
|
||||
int features_supports_mount = 0; /* kernel supports mount rules */
|
||||
|
@@ -459,7 +459,9 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
|
||||
sd_serialize_rlimits(buf, &profile->rlimits);
|
||||
|
||||
/* choice to support / downgrade needs to already have been made */
|
||||
if (profile->net.allow && features_supports_network) {
|
||||
if (features_supports_networkv8) {
|
||||
/* nothing - encoded in policydb */
|
||||
} else if (profile->net.allow && features_supports_network) {
|
||||
size_t i;
|
||||
sd_write_array(buf, "net_allowed_af", get_af_max());
|
||||
for (i = 0; i < get_af_max(); i++) {
|
||||
@@ -470,7 +472,7 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
|
||||
sd_write_uint16(buf, profile->net.deny[i] & profile->net.quiet[i]);
|
||||
}
|
||||
sd_write_arrayend(buf);
|
||||
} else if (profile->net.allow && (warnflags & WARN_RULE_NOT_ENFORCED))
|
||||
} else if (profile->net.allow)
|
||||
pwarn(WARN_RULE_NOT_ENFORCED, _("profile %s network rules not enforced\n"), profile->name);
|
||||
|
||||
if (profile->policy.dfa) {
|
||||
|
@@ -881,6 +881,9 @@ void set_supported_features()
|
||||
features_supports_network = features_intersect(kernel_features,
|
||||
policy_features,
|
||||
"network");
|
||||
features_supports_networkv8 = features_intersect(kernel_features,
|
||||
policy_features,
|
||||
"network_v8");
|
||||
features_supports_unix = features_intersect(kernel_features,
|
||||
policy_features,
|
||||
"network/af_unix");
|
||||
|
@@ -840,6 +840,80 @@ int post_process_policydb_ents(Profile *prof)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static bool gen_net_rule(Profile *prof, u16 family, unsigned int type_mask,
|
||||
bool audit, bool deny) {
|
||||
std::ostringstream buffer;
|
||||
std::string buf;
|
||||
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NETV8;
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((family & 0xff00) >> 8);
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (family & 0xff);
|
||||
if (type_mask > 0xffff) {
|
||||
buffer << "..";
|
||||
} else {
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << ((type_mask & 0xff00) >> 8);
|
||||
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << (type_mask & 0xff);
|
||||
}
|
||||
buf = buffer.str();
|
||||
if (!prof->policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_VALID_NET_PERMS),
|
||||
audit ? map_perms(AA_VALID_NET_PERMS) : 0,
|
||||
dfaflags))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gen_af_rules(Profile *prof, u16 family, unsigned int type_mask,
|
||||
unsigned int audit_mask, bool deny)
|
||||
{
|
||||
if (type_mask > 0xffff && audit_mask > 0xffff) {
|
||||
/* instead of generating multiple rules wild card type */
|
||||
return gen_net_rule(prof, family, type_mask, audit_mask, deny);
|
||||
} else {
|
||||
int t;
|
||||
/* generate rules for types that are set */
|
||||
for (t = 0; t < 16; t++) {
|
||||
if (type_mask & (1 << t)) {
|
||||
if (!gen_net_rule(prof, family, t,
|
||||
audit_mask & (1 << t),
|
||||
deny))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool post_process_policydb_net(Profile *prof)
|
||||
{
|
||||
u16 af;
|
||||
|
||||
/* no network rules defined so we don't have generate them */
|
||||
if (!prof->net.allow)
|
||||
return true;
|
||||
|
||||
/* generate rules if the af has something set */
|
||||
for (af = AF_UNSPEC; af < get_af_max(); af++) {
|
||||
if (prof->net.allow[af] ||
|
||||
prof->net.deny[af] ||
|
||||
prof->net.audit[af] ||
|
||||
prof->net.quiet[af]) {
|
||||
if (!gen_af_rules(prof, af, prof->net.allow[af],
|
||||
prof->net.audit[af],
|
||||
false))
|
||||
return false;
|
||||
if (!gen_af_rules(prof, af, prof->net.deny[af],
|
||||
prof->net.quiet[af],
|
||||
true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MAKE_STR(X) #X
|
||||
#define CLASS_STR(X) "\\d" MAKE_STR(X)
|
||||
#define MAKE_SUB_STR(X) "\\000" MAKE_STR(X)
|
||||
@@ -851,6 +925,7 @@ static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS);
|
||||
static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL);
|
||||
static const char *mediates_ptrace = CLASS_STR(AA_CLASS_PTRACE);
|
||||
static const char *mediates_extended_net = CLASS_STR(AA_CLASS_NET);
|
||||
static const char *mediates_netv8 = CLASS_STR(AA_CLASS_NETV8);
|
||||
static const char *mediates_net_unix = CLASS_SUB_STR(AA_CLASS_NET, AF_UNIX);
|
||||
|
||||
int process_profile_policydb(Profile *prof)
|
||||
@@ -863,6 +938,9 @@ int process_profile_policydb(Profile *prof)
|
||||
|
||||
if (!post_process_policydb_ents(prof))
|
||||
goto out;
|
||||
/* TODO: move to network class */
|
||||
if (features_supports_networkv8 && !post_process_policydb_net(prof))
|
||||
goto out;
|
||||
|
||||
/* insert entries to show indicate what compiler/policy expects
|
||||
* to be supported
|
||||
@@ -884,6 +962,9 @@ int process_profile_policydb(Profile *prof)
|
||||
if (features_supports_ptrace &&
|
||||
!prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, dfaflags))
|
||||
goto out;
|
||||
if (features_supports_networkv8 &&
|
||||
!prof->policy.rules->add_rule(mediates_netv8, 0, AA_MAY_READ, 0, dfaflags))
|
||||
goto out;
|
||||
if (features_supports_unix &&
|
||||
(!prof->policy.rules->add_rule(mediates_extended_net, 0, AA_MAY_READ, 0, dfaflags) ||
|
||||
!prof->policy.rules->add_rule(mediates_net_unix, 0, AA_MAY_READ, 0, dfaflags)))
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#define AA_CLASS_NS_DOMAIN 8
|
||||
#define AA_CLASS_PTRACE 9
|
||||
#define AA_CLASS_SIGNAL 10
|
||||
|
||||
#define AA_CLASS_NETV8 14
|
||||
#define AA_CLASS_LABEL 16
|
||||
|
||||
/* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */
|
||||
|
Reference in New Issue
Block a user