parser: Convert af_unix rules to support addr= rather than path=

This patch converts the path= modifier to the af_unix rules to use
addr= instead.

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
Steve Beattie 2014-09-03 14:02:25 -07:00
parent 5b46e3b334
commit e85777a57c
13 changed files with 72 additions and 70 deletions

View file

@ -37,7 +37,7 @@ int parse_unix_mode(const char *str_mode, int *mode, int fail)
static struct supported_cond supported_conds[] = {
{ "path", true, false, false, either_cond },
{ "addr", true, false, false, either_cond },
{ NULL, false, false, false, local_cond }, /* sentinal */
};
@ -53,10 +53,10 @@ void unix_rule::move_conditionals(struct cond_entry *conds)
ent->name);
continue;
}
if (strcmp(ent->name, "path") == 0) {
move_conditional_value("unix socket", &path, ent);
if (path[0] != '@' && strcmp(path, "none") != 0)
yyerror("unix rule: invalid value for path='%s'\n", path);
if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix socket", &addr, ent);
if (addr[0] != '@' && strcmp(addr, "none") != 0)
yyerror("unix rule: invalid value for addr='%s'\n", addr);
}
/* TODO: add conditionals for
@ -81,16 +81,16 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds)
ent->name);
continue;
}
if (strcmp(ent->name, "path") == 0) {
move_conditional_value("unix", &peer_path, ent);
if (peer_path[0] != '@' && strcmp(path, "none") != 0)
yyerror("unix rule: invalid value for path='%s'\n", peer_path);
if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix", &peer_addr, ent);
if (peer_addr[0] != '@' && strcmp(addr, "none") != 0)
yyerror("unix rule: invalid value for addr='%s'\n", peer_addr);
}
}
}
unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied):
af_rule("unix"), path(NULL), peer_path(NULL)
af_rule("unix"), addr(NULL), peer_addr(NULL)
{
if (type_p != 0xffffffff) {
sock_type_n = type_p;
@ -105,7 +105,7 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied):
unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
struct cond_entry *peer_conds):
af_rule("unix"), path(NULL), peer_path(NULL)
af_rule("unix"), addr(NULL), peer_addr(NULL)
{
move_conditionals(conds);
move_peer_conditionals(peer_conds);
@ -138,16 +138,16 @@ unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
ostream &unix_rule::dump_local(ostream &os)
{
af_rule::dump_local(os);
if (path)
os << "path='" << path << "'";
if (addr)
os << "addr='" << addr << "'";
return os;
}
ostream &unix_rule::dump_peer(ostream &os)
{
af_rule::dump_peer(os);
if (peer_path)
os << "path='" << peer_path << "'";
if (peer_addr)
os << "addr='" << peer_addr << "'";
return os;
}
@ -157,10 +157,10 @@ int unix_rule::expand_variables(void)
int error = af_rule::expand_variables();
if (error)
return error;
error = expand_entry_variables(&path);
error = expand_entry_variables(&addr);
if (error)
return error;
error = expand_entry_variables(&peer_path);
error = expand_entry_variables(&peer_addr);
if (error)
return error;
@ -266,12 +266,12 @@ int unix_rule::gen_policy_re(Profile &prof)
}
/* local addr */
if (path) {
if (strcmp(path, "none") == 0) {
if (addr) {
if (strcmp(addr, "none") == 0) {
buffer << "\\x01";
} else {
/* skip leading @ */
ptype = convert_aaregex_to_pcre(path + 1, 0, buf, &pos);
ptype = convert_aaregex_to_pcre(addr + 1, 0, buf, &pos);
if (ptype == ePatternInvalid)
goto fail;
/* kernel starts abstract with \0 */
@ -349,12 +349,12 @@ int unix_rule::gen_policy_re(Profile &prof)
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_ADDR;
/* peer addr */
if (peer_path) {
if (strcmp(peer_path, "none") == 0) {
if (peer_addr) {
if (strcmp(peer_addr, "none") == 0) {
buffer << "\\x01";
} else {
/* skip leading @ */
ptype = convert_aaregex_to_pcre(peer_path + 1, 0, buf, &pos);
ptype = convert_aaregex_to_pcre(peer_addr + 1, 0, buf, &pos);
if (ptype == ePatternInvalid)
goto fail;
/* kernel starts abstract with \0 */

View file

@ -31,8 +31,8 @@ class unix_rule: public af_rule {
void move_peer_conditionals(struct cond_entry *conds);
void downgrade_rule(Profile &prof);
public:
char *path;
char *peer_path;
char *addr;
char *peer_addr;
int mode;
int audit;
bool deny;
@ -42,12 +42,12 @@ public:
struct cond_entry *peer_conds);
virtual ~unix_rule()
{
free(path);
free(peer_path);
free(addr);
free(peer_addr);
};
virtual bool has_peer_conds(void) {
return af_rule::has_peer_conds() || peer_path;
return af_rule::has_peer_conds() || peer_addr;
}
virtual ostream &dump_local(ostream &os);

View file

@ -175,13 +175,13 @@ B<TYPE COND> = 'type' '=' ( <AARE> | '(' ( '"' <AARE> '"' | <AARE> )+ ')' )
B<PROTO COND> = 'protocol' '=' ( <AARE> | '(' ( '"' <AARE> '"' | <AARE> )+ ')' )
B<UNIX LOCAL EXPR> = ( I<UNIX PATH COND> | I<UNIX LABEL COND> | I<UNIX ATTR COND> | I<UNIX OPT COND> )*
B<UNIX LOCAL EXPR> = ( I<UNIX ADDRESS COND> | I<UNIX LABEL COND> | I<UNIX ATTR COND> | I<UNIX OPT COND> )*
each cond can appear at most once
B<UNIX PEER EXPR> = 'peer' '=' ( I<UNIX PATH COND> | I<UNIX LABEL COND> )+
B<UNIX PEER EXPR> = 'peer' '=' ( I<UNIX ADDRESS COND> | I<UNIX LABEL COND> )+
each cond can appear at most once
B<UNIX PATH COND> 'path' '=' ( <AARE> | '(' '"' <AARE> '"' | <AARE> ')' )
B<UNIX ADDRESS COND> 'addr' '=' ( <AARE> | '(' '"' <AARE> '"' | <AARE> ')' )
B<UNIX LABEL COND> 'label' '=' ( <AARE> | '(' '"' <AARE> '"' | <AARE> ')' )
@ -897,26 +897,28 @@ domain sockets, see man 7 unix for more information.
=head3 Unix socket paths
The path component of a unix domain socket is specified by the
path=
conditional. If a path conditional is not specified as part of a rule
then the rule matches both abstract and anonymous sockets.
The path address component of a unix domain socket is specified by the
addr=
In apparmor the path of an abstract unix domain socket begins with the
I<@> character, similar to how they are reported by netstat -x. The name
then follows and may contain pattern matching and any characters including
the null character. In apparmor null characters must be specified by using
an escape sequence I<\000> or I<\x00>. The pattern matching is the same
as is used by path matching so * will not match I</> even though it
has no special meaning with in an abstract socket name. Eg.
unix path=@*,
conditional. If an address conditional is not specified as part of
a rule then the rule matches both abstract and anonymous sockets.
Anonymous unix domain sockets have no path associated with them, however
it can be specified with the special I<none> keyword to indicate the
rule only applies to anonymous unix domain sockets. Eg.
unix path=none,
In apparmor the address of an abstract unix domain socket begins with
the I<@> character, similar to how they are reported (as paths) by
netstat -x. The address then follows and may contain pattern matching
and any characters including the null character. In apparmor null
characters must be specified by using an escape sequence I<\000> or
I<\x00>. The pattern matching is the same as is used by path matching
so * will not match I</> even though it has no special meaning with
in an abstract socket name. Eg.
unix addr=@*,
If the path component of a rule is not specified then the rule applies
Anonymous unix domain sockets have no address associated with
them, however it can be specified with the special I<none> keyword
to indicate the rule only applies to anonymous unix domain sockets. Eg.
unix addr=none,
If the address component of a rule is not specified then the rule applies
to both abstract and anonymous sockets.
=head3 Unix socket permissions
@ -925,7 +927,7 @@ socket permissions are the union of all the listed unix rule permissions.
Unix domain socket rules are broad and general and become more restrictive
as further information is specified. Policy may be specified down to
the path and label level. The content of the communication is not
the addr and label level. The content of the communication is not
examined.
Unix socket rule permissions are implied when a rule does not explicitly
@ -961,20 +963,20 @@ create, bind, listen, shutdown, getattr, or setattr permissions.
unix type=dgram,
unix path=none
unix addr=none
unix path=@foo,
unix addr=@foo,
unix type=stream path=@foo,
unix type=stream addr=@foo,
unix server path=@foo,
unix server addr=@foo,
unix accept path=@foo peer=(label=/bar),
unix accept addr=@foo peer=(label=/bar),
unix receive path=@foo peer=(label=/bar),
unix receive addr=@foo peer=(label=/bar),
unix path=none
unix addr=none
=head3 Abstract unix domain sockets autobind
@ -1000,7 +1002,7 @@ Eg.
Fine grained mediation rules however can not be lossly converted back
to the coarse grained network rule. Eg
unix bind path=@example,
unix bind addr=@example,
Has no exact match under coarse grained network rules, the closest match is
the much wider permission rule of.

View file

@ -4,5 +4,5 @@
#
profile foo {
unix bind peer=(path=@foo ),
unix bind peer=(addr=@foo ),
}

View file

@ -4,5 +4,5 @@
#
profile foo {
unix bind label=foo path=@bar,
unix bind label=foo addr=@bar,
}

View file

@ -3,7 +3,7 @@
#=EXRESULT FAIL
#
# path must be none for anonymous or start with @ for abstract
# path address must be none for anonymous or start with @ for abstract
profile foo {
unix send peer(path=wat),
unix send peer(addr=wat),
}

View file

@ -1,8 +1,8 @@
#
#=DESCRIPTION unix rule with a bad path regex expansion
#=DESCRIPTION unix rule with a bad addr regex expansion
#=EXRESULT FAIL
#
profile foo {
unix send path=@foo{one,two peer=(label=splat),
unix send addr=@foo{one,two peer=(label=splat),
}

View file

@ -4,5 +4,5 @@
#
profile foo {
unix bind path=abcd]efg,
unix bind addr=abcd]efg,
}

View file

@ -1,8 +1,8 @@
#
#=DESCRIPTION unix rule with a bad path regex expansion
#=DESCRIPTION unix rule with a bad path address regex expansion
#=EXRESULT FAIL
#
profile foo {
unix send path=/some/random/{path peer=(label=splat),
unix send addr=/some/random/{path peer=(label=splat),
}

View file

@ -3,5 +3,5 @@
#=EXRESULT PASS
profile a_profile {
unix path=@SomeService,
unix addr=@SomeService,
}

View file

@ -3,5 +3,5 @@
#=EXRESULT PASS
profile a_profile {
unix (send) path=none,
unix (send) addr=none,
}

View file

@ -3,5 +3,5 @@
#=EXRESULT PASS
profile a_profile {
unix (send) path=@foo,
unix (send) addr=@foo,
}

View file

@ -3,5 +3,5 @@
#=EXRESULT PASS
profile a_profile {
unix (send) peer=(path=@foo),
unix (send) peer=(addr=@foo),
}