2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 14:25:52 +00:00

parser: add implicit set variable @{profile_name} to profile symbol

table

This patch adds the creation of an implicit set variable
@{profile_name} for use within policy. It expands to:

  - a given profile name if specified; e.g. for
      'profile flappy_bird /some/pattern/match* { [...] }'
    @{profile_name} would expand to 'flappy_bird'
  - if no given name, the match pattern; e.g. for
      '/usr/bin/doge_bird { [...] }'
    @{profile_name} would expand to '/usr/bin/doge_bird'
  - hats and child profiles will include the fully qualified name; e.g.
    the 'doge' hat in the /usr/bin/flappy_bird profile would cause
    @{profile_name} to expand to '/usr/bin/flappy_bird//doge' within the
    'doge' hat, and '/usr/bin/flappy_bird' outside of it in the profile.

There are some parsing tests added, but more tests are needed to verify
that expansion occurs properly (I've verified manually using parser
dumps of the added tests, but automated checks are needed).

The @{profile_name} variable is expected to be most useful in the
context of signal and ptrace rules (e.g. for specifying that an app
can send itself signals).

Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
Steve Beattie
2014-04-23 16:38:29 -07:00
parent e9019eb650
commit a67d9be5a2
11 changed files with 226 additions and 8 deletions

View File

@@ -330,6 +330,50 @@ char *get_next_set_value(struct set_value **list)
return ret;
}
/* delete_symbol
* removes an individual variable from the symbol table. We don't
* support this in the language, but for special variables that change
* between profiles, we need this.
*/
int delete_set_var(const char *var_name)
{
int rc = 0;
struct symtab **result, *n, *var;
n = new_symtab_entry(var_name);
if (!n) {
rc = ENOMEM;
goto out;
}
result = (struct symtab **) tfind(n, &my_symtab, (comparison_fn_t) &compare_symtabs);
if (!result) {
/* XXX Warning? */
goto out;
}
var = (*result);
result = (struct symtab **) tdelete(n, &my_symtab, (comparison_fn_t) &compare_symtabs);
if (!result) {
PERROR("ASSERT: delete_set_var: tfind found var %s but tdelete failed to delete it\n",
var_name);
exit(1);
}
if (var->type != sd_set) {
PERROR("ASSERT: delete_set_var: deleting %s but is a boolean variable\n",
var_name);
exit(1);
}
free_symtab(var);
out:
free_symtab(n);
return rc;
}
static void *seenlist = NULL;
static int is_seen(const char *var)
@@ -708,6 +752,21 @@ int test_expand_set_var_during_dump(void)
return rc;
}
int test_delete_set_var(void)
{
int rc = 0;
int retval;
retval = new_set_var("deleteme", "delete this variable");
MY_TEST(retval == 0, "new delete set variable");
retval = delete_set_var("deleteme");
MY_TEST(retval == 0, "delete set variable");
free_symtabs();
return rc;
}
int main(void)
{
int rc = 0;
@@ -740,6 +799,10 @@ int main(void)
if (rc == 0)
rc = retval;
retval = test_delete_set_var();
if (rc == 0)
rc = retval;
retval = new_set_var("test", "test value");
MY_TEST(retval == 0, "new set variable 1");