2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-05 08:45:22 +00:00

Compare commits

...

27 Commits

Author SHA1 Message Date
John Johansen
c50858a877 Update permission mapping for changes made to the upstream kernel patch.
The changes are around how user data is handled.

1. permissions are mapped before data is matched
2. If data is to be mapped a AA_CONT_MATCH flag is set in the permissions
   which allows data matching to continue.
3. If data auditing is to occur the AA_AUDIT_MNT_DATA flag is set

This allows better control over matching and auditing of data which can
be binary and should not be matched or audited

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 12:54:34 -07:00
John Johansen
a11efe838a Fix the bare file rule so that it grants access to to root
file, should grant access to all files paths on the system but it does
not currently allow access to /

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 12:16:56 -07:00
John Johansen
d6dc04d737 Fix pivot_root to support named transitions correctly
Rename the pivotroot rule to pivot_root to match the command and the fn
and fix it to support named transition correctly leveraging the parsing
action used for exec transitions.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 12:14:15 -07:00
John Johansen
feeea88a58 Fix the case where no flags match
Currently the backend doesn't like it (blows up) when the a vector entry is
empty.  For the case where no flags match build_mnt_flags generates an
alternation of an impossible entry and nothing

  (impossible|)

This provides the effect of a null entry without having an empty vector
entry.  Unfortunately the impossible entry is not correct.

Note: how this is done needs to be changed and fixed in the next release
this is just a minimal patch to get it working for 2.8


Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 12:10:35 -07:00
John Johansen
36d44a3b25 Fix the mount flags set generated by the parser
When generating the flag set the parser was not generating the complete
set when flags where not consecutive.  This is because the len value
was not being reset for each flag considered, so once it was set for
a flag, then the next flag would have to be set to reset it else the
output string was still incremented by the old len value.

  Eg.
  echo "/t { mount options=rbind, }" | apparmor_parser -QT -D rule-exprs

  results in
  rule: \x07[^\000]*\x00[^\000]*\x00[^\000]*\x00\x0d  ->

  however \x0d only covers the bind and not the recursive flag

This is fixed by adding a continue to the flags generation loop for the
else case.

  resulting the dump from above generating

  rule: \x07[^\000]*\x00[^\000]*\x00[^\000]*\x00\x0d\x0f  ->

  \x0d\x0f covers both of the required flags

Also fix the flags output to allow for the allow any flags case.  This
was being screened out.  By masking the flags even when no flags where
specified.

  this results in a difference of

  echo "/t { mount, }" | apparmor_parser -QT -D rule-exprs

    rule: \x07[^\000]*\x00[^\000]*\x00[^\000]*\x00(\x01|)(\x02|)(\x03|)(\x04|)(\x05|)\x00[^\000]*

  becoming
    \x07[^\000]*\x00[^\000]*\x00[^\000]*\x00[^\000]*\x00[^\000]*

  which is simplified and covers all permissions vs. the first rule output

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 09:03:48 -07:00
John Johansen
fc5f4dc86f Revert commit: -r 1955 Default profiles to be chroot relative
This commit causes policy problems because we do not have chroot rules
and policy extension to support it.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-15 08:59:56 -07:00
John Johansen
59c0bb0f46 Fix minimize.sh test to screen out more parser error messages by grepping
closer to the expected -O dfa-states output
2012-03-09 06:48:03 -08:00
John Johansen
fae11e12cf Mark the minimize test as executable 2012-03-09 05:54:54 -08:00
John Johansen
e0a74881bf Bump version for 2.8-beta2 2012-03-09 04:44:37 -08:00
John Johansen
ce38857061 tag apparmor_2.8-beta2 2012-03-09 04:27:47 -08:00
John Johansen
c8e134930f Fix the "Kernel features are written to cache:" test
the cache test is failing because it assumes that kernel features are
stored in a file instead of a directory

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:25:03 -08:00
John Johansen
3876299fa0 Fix caching when used with a newer kernel with the feature directory
On newer kernels the features directory causes the creation of a
cache/.feature file that contains newline characters.  This causes the
feature comparison to fail, because get_flags_string() uses fgets
which stop reading in the feature file after the first newline.

This caches the features comparision to compare a single line of the
file against the full kernel feature directory resulting in caching
failure.

Worse this also means the cache won't get updated as the parser doesn't
change what set gets caches after the .feature file gets created.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:24:20 -08:00
John Johansen
b0b2bde160 Fix permissions attached to the bare file keyword
file,

was not given the correct permissions.  It was only being given the owner
set of permissions.  This would result in rejects when trying look at
files owned by other users

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:23:25 -08:00
John Johansen
3a1b7bb54c Fix infinite loop bug in normalization.
There are some rare occassions, when lots of alternations are used that
tree simplification can result in an expression of
  (E | (E | E)) or (E . (E . E))   where E is the epsnode

both of these expressions will lead to an inifinite loop in normalize_tree
as the epsnode test
       if ((&epsnode == t->child[dir]) &&
       	        (&epsnode != t->child[!dir]) &&
		      	         dynamic_cast<TwoChildNode *>(t)) {

and the tree node rotation test
    	} else if ((dynamic_cast<AltNode *>(t) &&
	           dynamic_cast<AltNode *>(t->child[dir])) ||
		   			   (dynamic_cast<CatNode *>(t) &&
					   			    dynamic_cast<CatNode *>(t->child[dir]))) {

end up undoing each others work, ie.

                eps flip                 rotate
  (E | (E | E)) --------> ((E | E) | E) -------> (E | (E | E))

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:22:42 -08:00
John Johansen
04ef92ca94 Fix a couple build warnings in mount.c
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:21:54 -08:00
John Johansen
d7a6860a23 Fix Make file for mount.c so that warnings are emitted during a build
Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:21:06 -08:00
John Johansen
5e361a4a05 Fix dfa minimization to deal with exec conflicts
Minimization was failing because it was too agressive.  It was minimizing
as if there was only 1 accept condition.  This allowed it to remove more
states but at the cost of loosing unique permission sets, they where
being combined into single commulative perms.  This means that audit,
deny, xtrans, ... info on one path would be applied to all other paths
that it was combined with during minimization.

This means that we need to retain the unique accept states, not allowing
them to be combined into a single state.  To do this we put each unique
permission set into its own partition at the start of minimization.

The states within a partition have the  same permissions and can be combined
within the other states in the partition as the loss of unique path
information is will not result in a conflict.

This is similar to what perm hashing used to do but deny information is
still being correctly applied and carried.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:20:19 -08:00
John Johansen
cf5f7ef9c2 Fix the x intersection consistency test
The in x intersection consistency test for minimization was failing because
it was screening off the AA_MAY_EXEC permission before passing the exec
information to the consistency test fn.  This resulted in the consistency
test fn not testing the consistency because it treated the permission set
as not having x permissions.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:19:24 -08:00
John Johansen
811d8aefa3 Fix transition character reporting of dfa dumps
Make them report a hex value strings instead of the default C++
\vvvvv

Make them consistent,
- Dump to report the default transition and what isn't transitioned
  on it.


Signed-off-by: John Johansen <john.johansen@canonical.com>
2012-03-09 04:18:35 -08:00
John Johansen
37f446dd79 Fix/cleanup the permission reporting for the dfa dumps
The permission reporting was not reporting the full set of permission
flags and was inconsistent between the dump routines.

Report permissions as the quad (allow/deny/audit/quiet) in hex.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:17:47 -08:00
John Johansen
1a01b5c296 Fix/cleanup the dfa dump routines output to provide state label
Fix the transitions states output so that they output the state label
instead of the state address.  That is
  {1} -> 0x10831a0:  /
now becomes
  {1} -> {2}:  /

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-09 04:14:34 -08:00
Jamie Strandboge
b47197b881 allow read access to ~/.drirc
Bug-Ubuntu: https://launchpad.net/bugs/941506

Acked-By: Jamie Strandboge <jamie@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-02 15:09:21 -06:00
Jamie Strandboge
3e5ae57164 Description: allow read access to /usr/share/texmf/fonts
Bug-Ubuntu: https://launchpad.net/bugs/941503

Acked-By: Jamie Strandboge <jamie@canonical.com>
Acked-By: Steve Beattie <sbeattie@ubuntu.com>
2012-03-02 15:08:03 -06:00
Jamie Strandboge
a0048ec064 ubuntu-browsers.d/java: update to fix LP: #945019 2012-03-02 13:03:04 -06:00
Jamie Strandboge
c35e10f875 fix path to java in ubuntu-browsers.d/java
Bug-Ubuntu: https://launchpad.net/bugs/943161

Acked-By: Jamie Strandboge <jamie@canonical.com>
2012-03-02 11:18:11 -06:00
Jamie Strandboge
46d9aae952 include /etc/drirc in the X abstraction
Bug-Ubuntu: https://launchpad.net/bugs/918879

Acked-By: Jamie Strandboge <jamie@canonical.com>
Signed-off-by: Kees Cook <kees@ubuntu.com>
2012-02-28 12:50:20 -06:00
John Johansen
bd67bb909a tag apparmor 2.8 beta1 release as 2.7.99 2012-02-24 04:38:24 -08:00
23 changed files with 493 additions and 115 deletions

View File

@@ -1 +1 @@
2.7.99
2.7.100

View File

@@ -200,6 +200,9 @@ parser_alias.o: parser_alias.c parser.h
parser_common.o: parser_common.c parser.h
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
mount.o: mount.c mount.h parser.h immunix.h
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
parser_version.h: Makefile
@echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
@mv -f .ver $@

View File

@@ -96,6 +96,9 @@
#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE)
#define ALL_USER_EXEC (AA_USER_EXEC | AA_USER_EXEC_TYPE)
#define ALL_OTHER_EXEC (AA_OTHER_EXEC | AA_OTHER_EXEC_TYPE)
#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \
(AA_MAY_LINK << AA_OTHER_SHIFT))

View File

@@ -223,7 +223,7 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny,
tree->dump(cerr);
if (deny)
cerr << " deny";
cerr << " (" << hex << allow <<"/" << audit << dec << ")";
cerr << " (0x" << hex << allow <<"/" << audit << dec << ")";
accept->dump(cerr);
cerr << "\n\n";
}

View File

@@ -187,14 +187,22 @@ void normalize_tree(Node *t, int dir)
return;
for (;;) {
if ((&epsnode == t->child[dir]) &&
(&epsnode != t->child[!dir]) &&
dynamic_cast<TwoChildNode *>(t)) {
if (dynamic_cast<TwoChildNode *>(t) &&
(&epsnode == t->child[dir]) &&
(&epsnode != t->child[!dir])) {
// (E | a) -> (a | E)
// Ea -> aE
Node *c = t->child[dir];
t->child[dir] = t->child[!dir];
t->child[!dir] = c;
// Test for E | (E | E) and E . (E . E) which will
// result in an infinite loop
Node *c = t->child[!dir];
if (dynamic_cast<TwoChildNode *>(c) &&
&epsnode == c->child[dir] &&
&epsnode == c->child[!dir]) {
c->release();
c = &epsnode;
}
t->child[dir] = c;
t->child[!dir] = &epsnode;
// Don't break here as 'a' may be a tree that
// can be pulled up.
} else if ((dynamic_cast<AltNode *>(t) &&

View File

@@ -431,7 +431,7 @@ int DFA::apply_and_clear_deny(void)
/* minimize the number of dfa states */
void DFA::minimize(dfaflags_t flags)
{
map<size_t, Partition *> perm_map;
map<pair<uint64_t, size_t>, Partition *> perm_map;
list<Partition *> partitions;
/* Set up the initial partitions
@@ -448,20 +448,18 @@ void DFA::minimize(dfaflags_t flags)
int final_accept = 0;
for (Partition::iterator i = states.begin(); i != states.end(); i++) {
size_t hash = 0;
if (!(*i)->perms.is_null())
/* combine all states carrying accept info together
into an single initial parition */
hash = 1;
uint64_t permtype = ((uint64_t) (PACK_AUDIT_CTL((*i)->perms.audit, (*i)->perms.quiet & (*i)->perms.deny)) << 32) | (uint64_t) (*i)->perms.allow;
if (flags & DFA_CONTROL_MINIMIZE_HASH_TRANS)
hash |= hash_trans(*i) << 1;
map<size_t, Partition *>::iterator p = perm_map.find(hash);
hash |= hash_trans(*i);
pair<uint64_t, size_t> group = make_pair(permtype, hash);
map<pair<uint64_t, size_t>, Partition *>::iterator p = perm_map.find(group);
if (p == perm_map.end()) {
Partition *part = new Partition();
part->push_back(*i);
perm_map.insert(make_pair(hash, part));
perm_map.insert(make_pair(group, part));
partitions.push_back(part);
(*i)->partition = part;
if (hash & 1)
if (permtype)
accept_count++;
} else {
(*i)->partition = p->second;
@@ -633,12 +631,12 @@ void DFA::dump(ostream & os)
if (*i == start || !(*i)->perms.is_null()) {
os << **i;
if (*i == start)
os << " <==";
if ((*i)->perms.allow) {
os << " (0x" << hex << (*i)->perms.allow << " "
<< (*i)->perms.deny << " "
<< (*i)->perms.audit << " "
<< (*i)->perms.audit << dec << ')';
os << " <== (allow/deny/audit/quiet)";
if (!(*i)->perms.is_null()) {
os << " (0x " << hex << (*i)->perms.allow << "/"
<< (*i)->perms.deny << "/"
<< (*i)->perms.audit << "/"
<< (*i)->perms.quiet << ')';
}
os << "\n";
}
@@ -646,12 +644,34 @@ void DFA::dump(ostream & os)
os << "\n";
for (Partition::iterator i = states.begin(); i != states.end(); i++) {
if ((*i)->otherwise != nonmatching)
os << **i << " -> " << (*i)->otherwise << "\n";
Chars excluded;
for (StateTrans::iterator j = (*i)->trans.begin();
j != (*i)->trans.end(); j++) {
os << **i << " -> " << j->second << ": "
<< j->first << "\n";
if (j->second == nonmatching) {
excluded.insert(j->first);
} else {
os << **i << " -> " << *(j)->second << ": 0x"
<< hex << (int) j->first;
if (isprint(j->first))
os << " " << j->first;
os << "\n";
}
}
if ((*i)->otherwise != nonmatching) {
os << **i << " -> " << *(*i)->otherwise << ": [";
if (!excluded.empty()) {
os << "^";
for (Chars::iterator k = excluded.begin();
k != excluded.end(); k++) {
if (isprint(*k))
os << *k;
else
os << "\\0x" << hex << (int) *k;
}
}
os << "]\n";
}
}
os << "\n";
@@ -672,10 +692,12 @@ void DFA::dump_dot_graph(ostream & os)
if (*i == start) {
os << "\t\tstyle=bold" << "\n";
}
uint32_t perms = (*i)->perms.allow;
if (perms) {
os << "\t\tlabel=\"" << **i << "\\n("
<< perms << ")\"" << "\n";
if (!(*i)->perms.is_null()) {
os << "\t\tlabel=\"" << **i << "\\n(0x " << hex
<< (*i)->perms.allow << "/"
<< (*i)->perms.deny << "/"
<< (*i)->perms.audit << "/"
<< (*i)->perms.quiet << ")\"\n";
}
os << "\t]" << "\n";
}
@@ -688,18 +710,26 @@ void DFA::dump_dot_graph(ostream & os)
else {
os << "\t\"" << **i << "\" -> \"" << *j->second
<< "\" [" << "\n";
os << "\t\tlabel=\"" << j->first << "\"\n";
os << "\t]" << "\n";
os << "\t\tlabel=\"";
if (isprint(j->first))
os << j->first;
else
os << "\\0xhex" << (int) j->first;
os << "\"\n\t]" << "\n";
}
}
if ((*i)->otherwise != nonmatching) {
os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise
os << "\t\"" << **i << "\" -> \"" << *(*i)->otherwise
<< "\" [" << "\n";
if (!excluded.empty()) {
os << "\t\tlabel=\"[^";
for (Chars::iterator i = excluded.begin();
i != excluded.end(); i++) {
os << *i;
if (isprint(*i))
os << *i;
else
os << "\\0x" << hex << (int) *i;
}
os << "]\"" << "\n";
}

View File

@@ -50,8 +50,8 @@ public:
{
deny |= rhs.deny;
if (!is_merged_x_consistent(allow & AA_USER_EXEC_TYPE,
rhs.allow & AA_USER_EXEC_TYPE)) {
if (!is_merged_x_consistent(allow & ALL_USER_EXEC,
rhs.allow & ALL_USER_EXEC)) {
if ((exact & AA_USER_EXEC_TYPE) &&
!(rhs.exact & AA_USER_EXEC_TYPE)) {
/* do nothing */
@@ -64,8 +64,8 @@ public:
} else
allow |= rhs.allow & AA_USER_EXEC_TYPE;
if (!is_merged_x_consistent(allow & AA_OTHER_EXEC_TYPE,
rhs.allow & AA_OTHER_EXEC_TYPE)) {
if (!is_merged_x_consistent(allow & ALL_OTHER_EXEC,
rhs.allow & ALL_OTHER_EXEC)) {
if ((exact & AA_OTHER_EXEC_TYPE) &&
!(rhs.exact & AA_OTHER_EXEC_TYPE)) {
/* do nothing */
@@ -79,10 +79,10 @@ public:
allow |= rhs.allow & AA_OTHER_EXEC_TYPE;
allow = (allow | (rhs.allow & ~ALL_AA_EXEC_TYPE)) & ~deny;
allow = (allow | (rhs.allow & ~ALL_AA_EXEC_TYPE));
audit |= rhs.audit;
quiet = (quiet | rhs.quiet) & deny;
quiet = (quiet | rhs.quiet);
/*
if (exec & AA_USER_EXEC_TYPE &&
(exec & AA_USER_EXEC_TYPE) != (allow & AA_USER_EXEC_TYPE))

View File

@@ -190,8 +190,6 @@
* mount options=ro /dev/foo, #allow mounting /dev/foo as read only
* mount options=(ro,foo) /dev/foo,
* mount options=ro options=foo /dev/foo,
* mount -> /mnt/**, # allow any mount on dirs under /mnt/
* mount options=ro -> /mnt/**, # allow any read only mount under /mnt/
* mount fstype=overlayfs options=(rw,upperdir=/tmp/upper/,lowerdir=/) overlay -> /mnt/
*
*----------------------------------------------------------------------
@@ -277,7 +275,7 @@ static struct mnt_keyword_table mnt_opts_table[] = {
{"user", 0, MS_NOUSER},
{"nouser", MS_NOUSER, 0},
{ }
{NULL, 0, 0}
};
static struct mnt_keyword_table mnt_conds_table[] = {
@@ -286,7 +284,7 @@ static struct mnt_keyword_table mnt_conds_table[] = {
{"fstype", MNT_SRC_OPT | MNT_DST_OPT, MNT_COND_FSTYPE},
{"vfstype", MNT_SRC_OPT | MNT_DST_OPT, MNT_COND_FSTYPE},
{ }
{NULL, 0, 0}
};
static int find_mnt_keyword(struct mnt_keyword_table *table, const char *name)
@@ -391,7 +389,7 @@ static struct value_list *extract_options(struct cond_entry **conds)
}
struct mnt_entry *new_mnt_entry(struct cond_entry *src_conds, char *device,
struct cond_entry *dst_conds, char *mnt_point,
struct cond_entry *dst_conds __unused, char *mnt_point,
int allow)
{
/* FIXME: dst_conds are ignored atm */
@@ -399,8 +397,6 @@ struct mnt_entry *new_mnt_entry(struct cond_entry *src_conds, char *device,
struct mnt_entry *ent;
ent = (struct mnt_entry *) calloc(1, sizeof(struct mnt_entry));
if (ent) {
unsigned int rclear, aclear;
ent->mnt_point = mnt_point;
ent->device = device;
ent->dev_type = extract_fstype(&src_conds);
@@ -420,8 +416,8 @@ struct mnt_entry *new_mnt_entry(struct cond_entry *src_conds, char *device,
ent->inv_flags = 0;
} else if (!(ent->flags | ent->inv_flags)) {
/* no flag options, and not remount, allow everything */
ent->flags = 0xffffffff;
ent->inv_flags = 0xffffffff;
ent->flags = MS_ALL_FLAGS;
ent->inv_flags = MS_ALL_FLAGS;
}
ent->allow = allow;

View File

@@ -103,8 +103,10 @@
#define AA_MAY_PIVOTROOT 1
#define AA_MAY_MOUNT 2
#define AA_MAY_UMOUNT 4
#define AA_DUMMY_REMOUNT 32 /* dummy perm for remount rule - is remapped
* to a mount option*/
#define AA_MATCH_CONT 0x40
#define AA_AUDIT_MNT_DATA AA_MATCH_CONT
#define AA_DUMMY_REMOUNT 0x40000000 /* dummy perm for remount rule - is
* remapped to a mount option*/
struct mnt_entry {

View File

@@ -768,7 +768,7 @@ static char *handle_features_dir(const char *filename, char **buffer, int size,
}
pos = snprintf_buffer(*buffer, pos, size, " }\n");
pos = snprintf_buffer(*buffer, pos, size, "}\n");
}
if (dirent_path)
free(dirent_path);
@@ -844,6 +844,7 @@ out:
static void get_flags_string(char **flags, char *flags_file) {
char *pos;
FILE *f = NULL;
size_t size;
/* abort if missing or already set */
if (!flags || *flags)
@@ -857,8 +858,10 @@ static void get_flags_string(char **flags, char *flags_file) {
if (!*flags)
goto fail;
if (!fgets(*flags, FLAGS_STRING_SIZE, f))
size = fread(*flags, 1, FLAGS_STRING_SIZE - 1, f);
if (!size || ferror(f))
goto fail;
(*flags)[size] = 0;
fclose(f);
pos = strstr(*flags, "change_hat=");

View File

@@ -83,7 +83,7 @@ static struct keyword_table keyword_table[] = {
{"remount", TOK_REMOUNT},
{"umount", TOK_UMOUNT},
{"unmount", TOK_UMOUNT},
{"pivotroot", TOK_PIVOTROOT},
{"pivot_root", TOK_PIVOTROOT},
/* terminate */
{NULL, 0}
};

View File

@@ -692,7 +692,7 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
char *p = buffer;
int i, len = 0;
if (flags == 0xffffffff) {
if (flags == MS_ALL_FLAGS) {
/* all flags are optional */
len = snprintf(p, size, "[^\\000]*");
if (len < 0 || len >= size)
@@ -704,7 +704,8 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
len = snprintf(p, size, "(\\x%02x|)", i + 1);
else if (flags & (1 << i))
len = snprintf(p, size, "\\x%02x", i + 1);
/* else no entry = not set */
else /* no entry = not set */
continue;
if (len < 0 || len >= size)
return FALSE;
@@ -712,6 +713,7 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
size -= len;
}
/* this needs to go once the backend is updated. */
if (buffer == p) {
/* match nothing - use impossible 254 as regex parser doesn't
* like the empty string
@@ -719,7 +721,7 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
if (size < 9)
return FALSE;
strcpy(p, "(\\0xfe|)");
strcpy(p, "(\\xfe|)");
}
return TRUE;
@@ -774,6 +776,7 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
char optsbuf[PATH_MAX + 3];
char *p, *vec[5];
int count = 0;
unsigned int flags, inv_flags;
/* a single mount rule may result in multiple matching rules being
* created in the backend to cover all the possible choices
@@ -781,6 +784,7 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_REMOUNT)
&& !entry->device && !entry->dev_type) {
int allow;
/* remount can't be conditional on device and type */
p = mntbuf;
/* rule class single byte header */
@@ -801,18 +805,43 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
vec[1] = devbuf;
/* skip type */
vec[2] = devbuf;
if (!build_mnt_flags(flagsbuf, PATH_MAX,
entry->flags & MS_REMOUNT_FLAGS,
entry->inv_flags & MS_REMOUNT_FLAGS))
flags = entry->flags;
inv_flags = entry->inv_flags;
if (flags != MS_ALL_FLAGS)
flags &= MS_REMOUNT_FLAGS;
if (inv_flags != MS_ALL_FLAGS)
flags &= MS_REMOUNT_FLAGS;
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
goto fail;
vec[3] = flagsbuf;
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
goto fail;
vec[4] = optsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
entry->audit, 5, vec, dfaflags))
if (entry->opts)
allow = AA_MATCH_CONT;
else
allow = entry->allow;
/* rule for match without required data || data MATCH_CONT */
if (!aare_add_rule_vec(dfarules, entry->deny, allow,
entry->audit | AA_AUDIT_MNT_DATA, 4,
vec, dfaflags))
goto fail;
count++;
if (entry->opts) {
/* rule with data match required */
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
goto fail;
vec[4] = optsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny,
entry->allow,
entry->audit | AA_AUDIT_MNT_DATA,
5, vec, dfaflags))
goto fail;
count++;
}
}
if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_BIND)
&& !entry->dev_type && !entry->opts) {
@@ -829,9 +858,14 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
if (!convert_entry(typebuf, PATH_MAX +3, NULL))
goto fail;
vec[2] = typebuf;
if (!build_mnt_flags(flagsbuf, PATH_MAX,
entry->flags & MS_BIND_FLAGS,
entry->inv_flags & MS_BIND_FLAGS))
flags = entry->flags;
inv_flags = entry->inv_flags;
if (flags != MS_ALL_FLAGS)
flags &= MS_BIND_FLAGS;
if (inv_flags != MS_ALL_FLAGS)
flags &= MS_BIND_FLAGS;
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
goto fail;
vec[3] = flagsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
@@ -856,9 +890,14 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
goto fail;
vec[1] = devbuf;
vec[2] = devbuf;
if (!build_mnt_flags(flagsbuf, PATH_MAX,
entry->flags & MS_MAKE_FLAGS,
entry->inv_flags & MS_MAKE_FLAGS))
flags = entry->flags;
inv_flags = entry->inv_flags;
if (flags != MS_ALL_FLAGS)
flags &= MS_MAKE_FLAGS;
if (inv_flags != MS_ALL_FLAGS)
flags &= MS_MAKE_FLAGS;
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
goto fail;
vec[3] = flagsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
@@ -884,9 +923,14 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
if (!convert_entry(typebuf, PATH_MAX +3, NULL))
goto fail;
vec[2] = typebuf;
if (!build_mnt_flags(flagsbuf, PATH_MAX,
entry->flags & MS_MOVE_FLAGS,
entry->inv_flags & MS_MOVE_FLAGS))
flags = entry->flags;
inv_flags = entry->inv_flags;
if (flags != MS_ALL_FLAGS)
flags &= MS_MOVE_FLAGS;
if (inv_flags != MS_ALL_FLAGS)
flags &= MS_MOVE_FLAGS;
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
goto fail;
vec[3] = flagsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
@@ -896,6 +940,7 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
}
if ((entry->allow & AA_MAY_MOUNT) &&
(entry->flags | entry->inv_flags) & ~MS_CMDS) {
int allow;
/* generic mount if flags are set that are not covered by
* above commands
*/
@@ -911,18 +956,41 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
if (!build_list_val_expr(typebuf, PATH_MAX+2, entry->dev_type))
goto fail;
vec[2] = typebuf;
if (!build_mnt_flags(flagsbuf, PATH_MAX,
entry->flags & ~MS_CMDS,
entry->inv_flags & ~MS_CMDS))
flags = entry->flags;
inv_flags = entry->inv_flags;
if (flags != MS_ALL_FLAGS)
flags &= ~MS_CMDS;
if (inv_flags != MS_ALL_FLAGS)
flags &= ~MS_CMDS;
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
goto fail;
vec[3] = flagsbuf;
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
goto fail;
vec[4] = optsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
entry->audit, 5, vec, dfaflags))
if (entry->opts)
allow = AA_MATCH_CONT;
else
allow = entry->allow;
/* rule for match without required data || data MATCH_CONT */
if (!aare_add_rule_vec(dfarules, entry->deny, allow,
entry->audit | AA_AUDIT_MNT_DATA, 4,
vec, dfaflags))
goto fail;
count++;
if (entry->opts) {
/* rule with data match required */
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
goto fail;
vec[4] = optsbuf;
if (!aare_add_rule_vec(dfarules, entry->deny,
entry->allow,
entry->audit | AA_AUDIT_MNT_DATA,
5, vec, dfaflags))
goto fail;
count++;
}
}
if (entry->allow & AA_MAY_UMOUNT) {
p = mntbuf;

View File

@@ -435,10 +435,6 @@ flagvals: flagvals flagval
(PATH_CHROOT_REL | PATH_NS_REL))
yyerror(_("Profile flag chroot_relative conflicts with namespace_relative"));
if (!($1.path & PATH_NS_REL))
/* default to chroot relative profiles */
$1.path |= PATH_CHROOT_REL;
if (($1.path & (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED)) ==
(PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED))
yyerror(_("Profile flag mediate_deleted conflicts with delegate_deleted"));
@@ -963,12 +959,14 @@ frule: file_mode opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE
file_rule: TOK_FILE TOK_END_OF_RULE
{
char *path = strdup("/**");
char *path = strdup("/{**,}");
int perms = ((AA_BASE_PERMS & ~AA_EXEC_TYPE) |
(AA_EXEC_INHERIT | AA_MAY_EXEC));
/* duplicate to other permission set */
perms |= perms << AA_OTHER_SHIFT;
if (!path)
yyerror(_("Memory allocation error."));
$$ = do_file_rule(NULL, path, ((AA_BASE_PERMS & ~AA_EXEC_TYPE) |
(AA_EXEC_INHERIT | AA_MAY_EXEC)),
NULL, NULL);
$$ = do_file_rule(NULL, path, perms, NULL, NULL);
}
| opt_file file_rule_tail { $$ = $2; }
@@ -1114,14 +1112,23 @@ mnt_rule: TOK_UMOUNT opt_conds opt_id TOK_END_OF_RULE
$$ = do_mnt_rule($2, NULL, NULL, $3, AA_MAY_UMOUNT);
}
mnt_rule: TOK_PIVOTROOT opt_conds opt_id TOK_END_OF_RULE
mnt_rule: TOK_PIVOTROOT opt_conds opt_id opt_named_transition TOK_END_OF_RULE
{
$$ = do_pivot_rule($2, $3, NULL);
}
char *name = NULL;
if ($4.present && $4.namespace) {
name = malloc(strlen($4.namespace) +
strlen($4.name) + 3);
if (!name) {
PERROR("Memory allocation error\n");
exit(1);
}
sprintf(name, ":%s:%s", $4.namespace, $4.name);
free($4.namespace);
free($4.name);
} else if ($4.present)
name = $4.name;
mnt_rule: TOK_PIVOTROOT opt_conds opt_id TOK_ARROW TOK_ID TOK_END_OF_RULE
{
$$ = do_pivot_rule($2, $3, $5);
$$ = do_pivot_rule($2, $3, name);
}
hat_start: TOK_CARET {}
@@ -1313,18 +1320,20 @@ struct mnt_entry *do_pivot_rule(struct cond_entry *old, char *root,
char *transition)
{
struct mnt_entry *ent = NULL;
char *device = NULL;
if (old) {
if (strcmp(old->name, "oldroot") != 0)
yyerror(_("invalid pivotroot conditional '%s'"), old->name);
if (old->vals) {
device = old->vals->value;
old->vals->value = NULL;
}
free_cond_entry(old);
}
ent = new_mnt_entry(NULL, old->vals->value, NULL, root,
ent = new_mnt_entry(NULL, device, NULL, root,
AA_MAY_PIVOTROOT);
ent->trans = transition;
old->vals->value = NULL;
free_cond_entry(old);
return ent;
}

View File

@@ -12,8 +12,8 @@ endif
all: tests
.PHONY: tests error_output gen_xtrans parser_sanity caching
tests: error_output gen_xtrans parser_sanity caching
.PHONY: tests error_output gen_xtrans parser_sanity caching minimize
tests: error_output gen_xtrans parser_sanity caching minimize
GEN_TRANS_DIRS=simple_tests/generated_x/ simple_tests/generated_perms_leading/ simple_tests/generated_perms_safe/
@@ -41,6 +41,9 @@ parser_sanity: $(PARSER)
caching: $(PARSER)
LANG=C ./caching.sh
minimize: $(PARSER)
LANG=C ./minimize.sh
$(PARSER):
make -C $(PARSER_DIR) $(PARSER_BIN)

View File

@@ -49,11 +49,34 @@ echo -n "Profiles are cached when requested: "
[ ! -f $basedir/cache/$profile ] && echo "FAIL ($basedir/cache/$profile does not exist)" && exit 1
echo "ok"
read_features_dir()
{
directory="$1"
if [ ! -d "$directory" ] ; then
return
fi
for f in `ls -AU "$directory"` ; do
if [ -f "$directory/$f" ] ; then
read -r -d "" KF < "$directory/$f" || true
echo -e "$f {$KF\n}"
elif [ -d "$directory/$f" ] ; then
echo -n "$f {"
KF=`read_features_dir "$directory/$f" "$KF"` || true
echo "$KF"
echo -e "}"
fi
done
}
echo -n "Kernel features are written to cache: "
[ ! -f $basedir/cache/.features ] && echo "FAIL ($basedir/cache/.features missing)" && exit 1
read CF < $basedir/cache/.features || true
read KF < /sys/kernel/security/apparmor/features || true
[ "$CF" != "$KF" ] && echo "FAIL (feature text mismatch: cache '$CF' vs kernel '$KF')" && exit 1
read -r -d "" CF < $basedir/cache/.features || true
if [ -d /sys/kernel/security/apparmor/features ] ; then
KF=`read_features_dir /sys/kernel/security/apparmor/features`
else
read -r -d "" KF < /sys/kernel/security/apparmor/features || true
fi
[ "$CF" != "$KF" ] && echo -e "FAIL (feature text mismatch:\n cache '$CF'\nvs\n kernel '$KF')" && exit 1
echo "ok"
echo -n "Cache is loaded when it exists and features match: "

199
parser/tst/minimize.sh Executable file
View File

@@ -0,0 +1,199 @@
#!/bin/bash
# Format of -D dfa-states
# dfa-states output is split into 2 parts:
# the accept state infomation
# {state} (allow deny audit XXX) ignore XXX for now
# followed by the transition table information
# {Y} -> {Z}: 0xXX Char #0xXX is the hex dump of Char
# where the start state is always shown as
# {1} <==
#
# Eg. echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ./apparmor_parser -QT -O minimize -D dfa-states --quiet
#
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 0/2800a/0/2800a)
# {4} (0x 10004/2800a/0/2800a)
# {7} (0x 40010/2800a/0/2800a)
# {8} (0x 80020/2800a/0/2800a)
# {9} (0x 100040/2800a/0/2800a)
# {c} (0x 40030/0/0/0)
#
# {1} -> {2}: 0x2f /
# {2} -> {4}: 0x61 a
# {2} -> {3}: 0x62 b
# {2} -> {3}: 0x63 c
# {2} -> {7}: 0x64 d
# {2} -> {8}: 0x65 e
# {2} -> {9}: 0x66 f
# {2} -> {3}: [^\0x0/]
# {3} -> {3}: [^\0x0]
# {4} -> {3}: [^\0x0]
# {7} -> {a}: 0x0
# {7} -> {3}: []
# {8} -> {3}: [^\0x0]
# {9} -> {3}: [^\0x0]
# {a} -> {b}: 0x2f /
# {b} -> {c}: [^/]
# {c} -> {c}: []
#
# These tests currently only look at the accept state permissions
#
# To view any of these DFAs as graphs replace --D dfa-states with -D dfa-graph
# strip of the test stuff around the parser command and use the the dot
# command to convert
# Eg.
# echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ./apparmor_parser -QT -O minimize -D dfa-graph --quiet 2>min.graph
# dot -T png -o min.png min.graph
# and then view min.png in your favorite viewer
#
#------------------------------------------------------------------------
# test to see if minimization is eliminating non-redundant accept state
# Test xtrans and regular perms separately. The are the same basic failure
# but can xtrans has an extra code path.
#
# The permission test is setup to have all the none xtrans permissions show
# up once on unique paths and have a global write permission that adds to
# it.
# This should result in a un-minimized dump looking like. Notice it has 6
# states with accept information, 1 for each rule except for the 'w'
# permission which is combined into a single state for /b and /**
#
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 2800a/0/0/0)
# {4} (0x 3800e/0/0/0)
# {5} (0x 6801a/0/0/0)
# {6} (0x a802a/0/0/0)
# {7} (0x 12804a/0/0/0)
# {a} (0x 40030/0/0/0)
# A dump of minimization that is not respecting the uniqueness of the
# permissions on the states looks like below. Notice it has only 3 states
# with accept information
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 1b806e/0/0/0)
# {5} (0x 6801a/0/0/0)
# {a} (0x 40030/0/0/0)
echo -n "Minimize profiles basic perms "
if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, /** w, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# same test as above except with audit perms added
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 2800a/0/2800a/0)
# {4} (0x 3800e/0/2800a/0)
# {7} (0x 6801a/0/2800a/0)
# {8} (0x a802a/0/2800a/0)
# {9} (0x 12804a/0/2800a/0)
# {c} (0x 40030/0/0/0)
echo -n "Minimize profiles audit perms "
if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit /** w, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# same test as above except with deny 'w' perm added to /**, this does not
# elimnates the states with 'w' and 'a' because the quiet information is
# being carried
#
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 0/2800a/0/2800a)
# {4} (0x 10004/2800a/0/2800a)
# {7} (0x 40010/2800a/0/2800a)
# {8} (0x 80020/2800a/0/2800a)
# {9} (0x 100040/2800a/0/2800a)
# {c} (0x 40030/0/0/0)
echo -n "Minimize profiles deny perms "
if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, deny /** w, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# same test as above except with audit deny 'w' perm added to /**, with the
# parameter this elimnates the states with 'w' and 'a' because
# the quiet information is NOT being carried
#
# {1} <== (allow/deny/audit/quiet)
# {4} (0x 10004/0/0/0)
# {7} (0x 40010/0/0/0)
# {8} (0x 80020/0/0/0)
# {9} (0x 100040/0/0/0)
# {c} (0x 40030/0/0/0)
echo -n "Minimize profiles audit deny perms "
if [ `echo "/t { /a r, /b w, /c a, /d l, /e k, /f m, audit deny /** w, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 6 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# The x transition test profile is setup so that there are 3 conflicting x
# permissions, two are on paths that won't collide during dfa creation. The
# 3rd is a generic permission that should be overriden during dfa creation.
#
# This should result in a dfa that specifies transitions on 'a' and 'b' to
# unique states that store the alternate accept information. However
# minimization can remove the unique accept permission states if x permissions
# are treated as a single accept state.
#
# The minimized dump should retain the 'a' and 'b' transitions accept states.
# notice the below dump has 3 states with accept information {3}, {4}, {5}
#
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 2914a45/0/0/0)
# {4} (0x 4115045/0/0/0)
# {5} (0x 2514945/0/0/0)
#
# A dump of minimization that is not respecting the uniqueness of the
# permissions on the states transitioned to by 'a' and 'b' looks like
# below. Notice that only state {3} has accept information
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 2514945/0/0/0)
#
echo -n "Minimize profiles xtrans "
if [ `echo "/t { /b px, /* Pixr, /a Cx -> foo, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# same test as above + audit
echo -n "Minimize profiles audit xtrans "
if [ `echo "/t { /b px, audit /* Pixr, /a Cx -> foo, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 3 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# now try denying x and make sure perms are cleared
# notice that only deny and quiet information is being carried
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 0/fe17f85/0/14005)
echo -n "Minimize profiles deny xtrans "
if [ `echo "/t { /b px, deny /* xr, /a Cx -> foo, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 1 ] ; then
echo "failed"
exit 1;
fi
echo "ok"
# now try audit + denying x and make sure perms are cleared
# notice that the deny info is being carried, by an artifical trap state
# {1} <== (allow/deny/audit/quiet)
# {3} (0x 0/fe17f85/0/0)
echo -n "Minimize profiles audit deny xtrans "
if [ `echo "/t { /b px, audit deny /* xr, /a Cx -> foo, }" | ../apparmor_parser -QT -O minimize -D dfa-states 2>&1 | grep -v '<==' | grep '^{.*} (.*)$' | wc -l` -ne 1 ] ; then
echo "failed"
exit 1;
fi
echo "ok"

View File

@@ -1,11 +1,13 @@
#
#=DESCRIPTION test for conflict resolution in minimization phase of dfa gen
#=EXRESULT FAIL
#=EXRESULT PASS
#=TODO
#
/usr/bin/foo {
# need to build minimal test for this yet
/b px,
/* Pixr,
/a Cx -> foo,
}

View File

@@ -0,0 +1,11 @@
#
#=DESCRIPTION test for conflict resolution in minimization phase of dfa gen
#=EXRESULT FAIL
#=TODO
#
/usr/bin/foo {
/b* px,
/* Pixr,
/a* Cx -> foo,
}

View File

@@ -36,6 +36,8 @@
/usr/lib{,32,64}/dri/** mr,
/usr/lib/@{multiarch}/dri/** mr,
/dev/dri/** rw,
/etc/drirc r,
owner @{HOME}/.drirc r,
# mouse themes
/etc/X11/cursors/ r,

View File

@@ -30,7 +30,7 @@
/usr/share/a2ps/fonts/** r,
/usr/share/xfce/fonts/** r,
/usr/share/ghostscript/fonts/** r,
/usr/share/texmf/*/fonts/** r,
/usr/share/texmf/{,*/}fonts/** r,
/var/lib/ghostscript/** r,
@{HOME}/.fonts.conf r,

View File

@@ -4,8 +4,9 @@
owner @{HOME}/.java/deployment/deployment.properties k,
/etc/java-*/ r,
/etc/java-*/** r,
/usr/lib/jvm/java-6-openjdk/jre/lib/*/IcedTeaPlugin.so mr,
/usr/lib/jvm/java-6-openjdk*/jre/lib/*/IcedTeaPlugin.so mr,
/usr/lib/jvm/java-6-openjdk/jre/bin/java cx -> browser_openjdk,
/usr/lib/jvm/java-6-openjdk-{amd64,armel,armhf,i386,powerpc}/jre/bin/java cx -> browser_openjdk,
/usr/lib/jvm/java-*-sun-1.*/jre/bin/java{,_vm} cx -> browser_java,
/usr/lib/jvm/java-*-sun-1.*/jre/lib/*/libnp*.so cx -> browser_java,
/usr/lib/j2*-ibm/jre/bin/java cx -> browser_java,
@@ -43,8 +44,8 @@
/var/lib/dbus/machine-id r,
/usr/bin/env ix,
/usr/lib/jvm/java-6-openjdk/jre/bin/java ix,
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client/classes.jsa m,
/usr/lib/jvm/java-6-openjdk*/jre/bin/java ix,
/usr/lib/jvm/java-6-openjdk*/jre/lib/i386/client/classes.jsa m,
# Why would java need this?
deny /usr/bin/gconftool-2 x,

View File

@@ -164,9 +164,10 @@ sub gen_file($) {
my $rule = shift;
my @rules = split (/:/, $rule);
# default: file rules
if (@rules != 2) {
(!$nowarn) && print STDERR "Warning: invalid file access '$rule', ignored\n";
} else {
if (@rules == 1) {
# support raw rules
push (@{$output_rules{$hat}}, " $rules[0],\n");
} elsif (@rules == 2) {
if ($escape) {
$rules[0]=~ s/(["[\]{}\\\:\#])/\\$1/g;
$rules[0]=~ s/(\#)/\\043/g;
@@ -176,6 +177,8 @@ sub gen_file($) {
} else {
push (@{$output_rules{$hat}}, " $rules[0] $rules[1],\n");
}
} else {
(!$nowarn) && print STDERR "Warning: invalid file access '$rule', ignored\n";
}
}

View File

@@ -54,3 +54,15 @@ runchecktest "OPEN R+dac_override" fail $file
rm -f ${file}
genprofile $file:$badperm2
runchecktest "OPEN W (create)" fail $file
# This is a test where using just a raw 'file,' rule allowing all file
# access
genprofile file
runchecktest "OPEN 'file' RW" pass $file
# this test is to make sure the raw 'file' rule allows access to things
# that are not covered by the owner rule
chown nobody $file
chmod 666 $file
genprofile file
runchecktest "OPEN 'file' RW" pass $file