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:
@@ -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))
|
||||
|
Reference in New Issue
Block a user