2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 10:07:12 +00:00

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[] = { 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 */ { NULL, false, false, false, local_cond }, /* sentinal */
}; };
@ -53,10 +53,10 @@ void unix_rule::move_conditionals(struct cond_entry *conds)
ent->name); ent->name);
continue; continue;
} }
if (strcmp(ent->name, "path") == 0) { if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix socket", &path, ent); move_conditional_value("unix socket", &addr, ent);
if (path[0] != '@' && strcmp(path, "none") != 0) if (addr[0] != '@' && strcmp(addr, "none") != 0)
yyerror("unix rule: invalid value for path='%s'\n", path); yyerror("unix rule: invalid value for addr='%s'\n", addr);
} }
/* TODO: add conditionals for /* TODO: add conditionals for
@ -81,16 +81,16 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds)
ent->name); ent->name);
continue; continue;
} }
if (strcmp(ent->name, "path") == 0) { if (strcmp(ent->name, "addr") == 0) {
move_conditional_value("unix", &peer_path, ent); move_conditional_value("unix", &peer_addr, ent);
if (peer_path[0] != '@' && strcmp(path, "none") != 0) if (peer_addr[0] != '@' && strcmp(addr, "none") != 0)
yyerror("unix rule: invalid value for path='%s'\n", peer_path); yyerror("unix rule: invalid value for addr='%s'\n", peer_addr);
} }
} }
} }
unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): 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) { if (type_p != 0xffffffff) {
sock_type_n = type_p; 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, unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
struct cond_entry *peer_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_conditionals(conds);
move_peer_conditionals(peer_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) ostream &unix_rule::dump_local(ostream &os)
{ {
af_rule::dump_local(os); af_rule::dump_local(os);
if (path) if (addr)
os << "path='" << path << "'"; os << "addr='" << addr << "'";
return os; return os;
} }
ostream &unix_rule::dump_peer(ostream &os) ostream &unix_rule::dump_peer(ostream &os)
{ {
af_rule::dump_peer(os); af_rule::dump_peer(os);
if (peer_path) if (peer_addr)
os << "path='" << peer_path << "'"; os << "addr='" << peer_addr << "'";
return os; return os;
} }
@ -157,10 +157,10 @@ int unix_rule::expand_variables(void)
int error = af_rule::expand_variables(); int error = af_rule::expand_variables();
if (error) if (error)
return error; return error;
error = expand_entry_variables(&path); error = expand_entry_variables(&addr);
if (error) if (error)
return error; return error;
error = expand_entry_variables(&peer_path); error = expand_entry_variables(&peer_addr);
if (error) if (error)
return error; return error;
@ -266,12 +266,12 @@ int unix_rule::gen_policy_re(Profile &prof)
} }
/* local addr */ /* local addr */
if (path) { if (addr) {
if (strcmp(path, "none") == 0) { if (strcmp(addr, "none") == 0) {
buffer << "\\x01"; buffer << "\\x01";
} else { } else {
/* skip leading @ */ /* 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) if (ptype == ePatternInvalid)
goto fail; goto fail;
/* kernel starts abstract with \0 */ /* 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; buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << CMD_ADDR;
/* peer addr */ /* peer addr */
if (peer_path) { if (peer_addr) {
if (strcmp(peer_path, "none") == 0) { if (strcmp(peer_addr, "none") == 0) {
buffer << "\\x01"; buffer << "\\x01";
} else { } else {
/* skip leading @ */ /* 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) if (ptype == ePatternInvalid)
goto fail; goto fail;
/* kernel starts abstract with \0 */ /* 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 move_peer_conditionals(struct cond_entry *conds);
void downgrade_rule(Profile &prof); void downgrade_rule(Profile &prof);
public: public:
char *path; char *addr;
char *peer_path; char *peer_addr;
int mode; int mode;
int audit; int audit;
bool deny; bool deny;
@ -42,12 +42,12 @@ public:
struct cond_entry *peer_conds); struct cond_entry *peer_conds);
virtual ~unix_rule() virtual ~unix_rule()
{ {
free(path); free(addr);
free(peer_path); free(peer_addr);
}; };
virtual bool has_peer_conds(void) { 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); 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<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 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 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> ')' ) 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 =head3 Unix socket paths
The path component of a unix domain socket is specified by the The path address component of a unix domain socket is specified by the
path= addr=
conditional. If a path conditional is not specified as part of a rule
then the rule matches both abstract and anonymous sockets.
In apparmor the path of an abstract unix domain socket begins with the conditional. If an address conditional is not specified as part of
I<@> character, similar to how they are reported by netstat -x. The name a rule then the rule matches both abstract and anonymous sockets.
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=@*,
Anonymous unix domain sockets have no path associated with them, however In apparmor the address of an abstract unix domain socket begins with
it can be specified with the special I<none> keyword to indicate the the I<@> character, similar to how they are reported (as paths) by
rule only applies to anonymous unix domain sockets. Eg. netstat -x. The address then follows and may contain pattern matching
unix path=none, 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. to both abstract and anonymous sockets.
=head3 Unix socket permissions =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 Unix domain socket rules are broad and general and become more restrictive
as further information is specified. Policy may be specified down to 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. examined.
Unix socket rule permissions are implied when a rule does not explicitly 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 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 =head3 Abstract unix domain sockets autobind
@ -1000,7 +1002,7 @@ Eg.
Fine grained mediation rules however can not be lossly converted back Fine grained mediation rules however can not be lossly converted back
to the coarse grained network rule. Eg 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 Has no exact match under coarse grained network rules, the closest match is
the much wider permission rule of. the much wider permission rule of.

View File

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

View File

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

View File

@ -3,7 +3,7 @@
#=EXRESULT FAIL #=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 { 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 #=EXRESULT FAIL
# #
profile foo { 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 { 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 #=EXRESULT FAIL
# #
profile foo { 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 #=EXRESULT PASS
profile a_profile { profile a_profile {
unix path=@SomeService, unix addr=@SomeService,
} }

View File

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

View File

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

View File

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