2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-05 08:45:22 +00:00

parser: add support for autobind sockets

af_unix allows for sockets to be bound to a name that is autogenerated.
Currently this type of binding is only supported by a very generic
rule.

  unix (bind) type=dgram,

but this allows both sockets with specified names and anonymous
sockets. Extend unix rule syntax to support specifying just an
auto bind socket by specifying addr=auto

eg.

  unix (bind) addr=auto,

It is important to note that addr=auto only works for the bind
permission as once the socket is bound to an autogenerated address,
the addr with have a valid unique value that can be matched against
with a regular

  addr=@name

expression

Fixes: https://bugs.launchpad.net/apparmor/+bug/1867216
MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/521
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen
2020-09-10 13:51:59 -07:00
parent c9d01a325d
commit 0a52cf81e3
17 changed files with 290 additions and 6 deletions

View File

@@ -29,6 +29,9 @@
#include "profile.h"
#include "af_unix.h"
/* See unix(7) for autobind address definiation */
#define autobind_address_pattern "\\x00[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]";
int parse_unix_mode(const char *str_mode, int *mode, int fail)
{
return parse_X_mode("unix", AA_VALID_NET_PERMS, str_mode, mode, fail);
@@ -54,7 +57,9 @@ void unix_rule::move_conditionals(struct cond_entry *conds)
}
if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix socket", &addr, ent);
if (addr[0] != '@' && strcmp(addr, "none") != 0)
if (addr[0] != '@' &&
!(strcmp(addr, "none") == 0 ||
strcmp(addr, "auto") == 0))
yyerror("unix rule: invalid value for addr='%s'\n", addr);
}
@@ -82,7 +87,9 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds)
}
if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix", &peer_addr, ent);
if (peer_addr[0] != '@' && strcmp(peer_addr, "none") != 0)
if ((peer_addr[0] != '@') &&
!(strcmp(peer_addr, "none") == 0 ||
strcmp(peer_addr, "auto") == 0))
yyerror("unix rule: invalid value for addr='%s'\n", peer_addr);
}
}
@@ -222,6 +229,12 @@ bool unix_rule::write_addr(std::ostringstream &buffer, const char *addr)
if (strcmp(addr, "none") == 0) {
/* anonymous */
buffer << "\\x01";
} else if (strcmp(addr, "auto") == 0) {
/* autobind - special autobind rule written already
* just generate pattern that matches autobind
* generated addresses.
*/
buffer << autobind_address_pattern;
} else {
/* skip leading @ */
ptype = convert_aaregex_to_pcre(addr + 1, 0, glob_null, buf, &pos);
@@ -323,6 +336,33 @@ int unix_rule::gen_policy_re(Profile &prof)
mask &= ~AA_NET_CREATE;
}
/* write special pattern for autobind? Will not grant bind
* on any specific address
*/
if ((mask & AA_NET_BIND) && (!addr || (strcmp(addr, "auto") == 0))) {
std::ostringstream tmp;
tmp << buffer.str();
/* todo: change to out of band separator */
/* skip addr, its 0 length */
tmp << "\\x00";
/* local label option */
if (!write_label(tmp, label))
goto fail;
/* seperator */
tmp << "\\x00";
buf = tmp.str();
if (!prof.policy.rules->add_rule(buf.c_str(), deny,
map_perms(AA_NET_BIND),
map_perms(audit & AA_NET_BIND),
dfaflags))
goto fail;
/* clear if auto, else generic need to generate addr below */
if (addr)
mask &= ~AA_NET_BIND;
}
if (mask) {
/* local addr */
if (!write_addr(buffer, addr))