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:
parent
5b46e3b334
commit
e85777a57c
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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.
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
profile foo {
|
profile foo {
|
||||||
unix bind peer=(path=@foo ),
|
unix bind peer=(addr=@foo ),
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
profile foo {
|
profile foo {
|
||||||
unix bind label=foo path=@bar,
|
unix bind label=foo addr=@bar,
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,5 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
profile foo {
|
profile foo {
|
||||||
unix bind path=abcd]efg,
|
unix bind addr=abcd]efg,
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
#=EXRESULT PASS
|
#=EXRESULT PASS
|
||||||
|
|
||||||
profile a_profile {
|
profile a_profile {
|
||||||
unix path=@SomeService,
|
unix addr=@SomeService,
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
#=EXRESULT PASS
|
#=EXRESULT PASS
|
||||||
|
|
||||||
profile a_profile {
|
profile a_profile {
|
||||||
unix (send) path=none,
|
unix (send) addr=none,
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
#=EXRESULT PASS
|
#=EXRESULT PASS
|
||||||
|
|
||||||
profile a_profile {
|
profile a_profile {
|
||||||
unix (send) path=@foo,
|
unix (send) addr=@foo,
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
#=EXRESULT PASS
|
#=EXRESULT PASS
|
||||||
|
|
||||||
profile a_profile {
|
profile a_profile {
|
||||||
unix (send) peer=(path=@foo),
|
unix (send) peer=(addr=@foo),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user