Hello community,
here is the log from the commit of package apparmor-parser
checked in at Sun Apr 20 21:07:31 CEST 2008.
--------
--- apparmor-parser/apparmor-parser.changes 2008-04-07 23:43:16.000000000 +0200
+++ apparmor-parser/apparmor-parser.changes 2008-04-16 11:52:31.039515000 +0200
@@ -1,0 +2,5 @@
+Wed Apr 16 11:51:49 CEST 2008 - jjohansen@suse.de
+
+- Code drop of AppArmor 2.3 parser - feature implementation complete
+
+-------------------------------------------------------------------
Old:
----
apparmor-parser-2.3-1176.tar.gz
New:
----
apparmor-parser-2.3-1203.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ apparmor-docs.spec ++++++
--- /var/tmp/diff_new_pack.A25395/_old 2008-04-20 21:03:46.000000000 +0200
+++ /var/tmp/diff_new_pack.A25395/_new 2008-04-20 21:03:46.000000000 +0200
@@ -25,9 +25,9 @@
%endif
Summary: AppArmor Documentation package
Version: 2.3
-Release: 1
+Release: 4
Group: Documentation/Other
-Source0: apparmor-parser-%{version}-1176.tar.gz
+Source0: apparmor-parser-%{version}-1203.tar.gz
License: Other uncritical OpenSource License
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
++++++ apparmor-parser.spec ++++++
--- /var/tmp/diff_new_pack.A25395/_old 2008-04-20 21:03:46.000000000 +0200
+++ /var/tmp/diff_new_pack.A25395/_new 2008-04-20 21:03:46.000000000 +0200
@@ -25,9 +25,9 @@
%endif
Summary: AppArmor userlevel parser utility
Version: 2.3
-Release: 1
+Release: 4
Group: Productivity/Networking/Security
-Source0: %{name}-%{version}-1176.tar.gz
+Source0: %{name}-%{version}-1203.tar.gz
License: GPL v2 or later
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
@@ -166,6 +166,8 @@
%endif
%changelog
+* Wed Apr 16 2008 jjohansen@suse.de
+- Code drop of AppArmor 2.3 parser - feature implementation complete
* Tue Apr 08 2008 jjohansen@suse.de
- Bump version to 2.3 in preparation for AppArmor 2.3 code drop
* Sun Mar 16 2008 crrodriguez@suse.de
++++++ apparmor-parser-2.3-1176.tar.gz -> apparmor-parser-2.3-1203.tar.gz ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/apparmor-parser.spec new/apparmor-parser-2.3/apparmor-parser.spec
--- old/apparmor-parser-2.3/apparmor-parser.spec 2008-04-07 21:46:38.000000000 +0200
+++ new/apparmor-parser-2.3/apparmor-parser.spec 2008-04-18 03:44:26.000000000 +0200
@@ -34,9 +34,9 @@
Summary: AppArmor userlevel parser utility.
Name: apparmor-parser
Version: 2.3
-Release: 1176
+Release: 1203
Group: Applications/System
-Source0: %{name}-%{version}-1176.tar.gz
+Source0: %{name}-%{version}-1203.tar.gz
License: GPL
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/immunix.h new/apparmor-parser-2.3/immunix.h
--- old/apparmor-parser-2.3/immunix.h 2008-04-06 21:54:52.000000000 +0200
+++ new/apparmor-parser-2.3/immunix.h 2008-04-16 07:44:21.000000000 +0200
@@ -34,20 +34,19 @@
#define AA_EXEC_MMAP (1 << 6)
#define AA_MAY_MOUNT (1 << 7)
#define AA_EXEC_UNSAFE (1 << 8)
-#define AA_EXEC_MOD_0 (1 << 9)
-#define AA_EXEC_MOD_1 (1 << 10)
-#define AA_EXEC_MOD_2 (1 << 11)
-#define AA_EXEC_MOD_3 (1 << 12)
-#define AA_EXEC_MOD_4 (1 << 13)
+#define AA_EXEC_INHERIT (1 << 9)
+#define AA_EXEC_MOD_0 (1 << 10)
+#define AA_EXEC_MOD_1 (1 << 11)
+#define AA_EXEC_MOD_2 (1 << 12)
+#define AA_EXEC_MOD_3 (1 << 13)
#define AA_BASE_PERMS (AA_MAY_EXEC | AA_MAY_WRITE | \
AA_MAY_READ | AA_MAY_APPEND | \
AA_MAY_LINK | AA_MAY_LOCK | \
AA_MAY_MOUNT | AA_EXEC_MMAP | \
- AA_EXEC_UNSAFE | \
+ AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \
AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
- AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \
- AA_EXEC_MOD_4)
+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3)
#define AA_USER_SHIFT 0
#define AA_OTHER_SHIFT 14
@@ -57,33 +56,32 @@
#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS )
-#define AA_AUDIT_FIELD (1 << 28)
-#define AA_CHANGE_HAT (1 << 29)
-#define AA_CHANGE_PROFILE (1 << 30)
-#define AA_ERROR_BIT (1 << 31)
-#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE | \
- AA_AUDIT_FIELD | AA_ERROR_BIT)
-
+#define AA_USER_PTRACE (1 << 28)
+#define AA_OTHER_PTRACE (1 << 29)
+#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE)
+
+#define AA_CHANGE_HAT (1 << 30)
+#define AA_CHANGE_PROFILE (1 << 31)
+#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE)
#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
- AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \
- AA_EXEC_MOD_4)
-#define AA_EXEC_COUNT 32
+ AA_EXEC_MOD_2 | AA_EXEC_MOD_3)
+#define AA_EXEC_COUNT 16
#define AA_USER_EXEC_MODIFIERS (AA_EXEC_MODIFIERS << AA_USER_SHIFT)
#define AA_OTHER_EXEC_MODIFIERS (AA_EXEC_MODIFIERS << AA_OTHER_SHIFT)
#define AA_ALL_EXEC_MODIFIERS (AA_USER_EXEC_MODIFIERS | \
AA_OTHER_EXEC_MODIFIERS)
-#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_MODIFIERS)
+#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \
+ AA_EXEC_MODIFIERS)
#define AA_EXEC_UNCONFINED (AA_EXEC_MOD_0)
-#define AA_EXEC_INHERIT (AA_EXEC_MOD_1)
-#define AA_EXEC_PROFILE (AA_EXEC_MOD_0 | AA_EXEC_MOD_1)
-#define AA_EXEC_PROFILE_OR_INHERIT (AA_EXEC_MOD_2)
-#define AA_EXEC_LOCAL (AA_EXEC_MOD_2 | AA_EXEC_MOD_0)
+#define AA_EXEC_PROFILE (AA_EXEC_MOD_1)
+#define AA_EXEC_LOCAL (AA_EXEC_MOD_0 | AA_EXEC_MOD_1)
-#define AA_VALID_PERMS (AA_FILE_PERMS | AA_CHANGE_PROFILE)
+#define AA_VALID_PERMS (AA_FILE_PERMS | AA_PTRACE_PERMS | \
+ AA_OTHER_PERMS)
#define AA_USER_EXEC (AA_MAY_EXEC << AA_USER_SHIFT)
#define AA_OTHER_EXEC (AA_MAY_EXEC << AA_OTHER_SHIFT)
@@ -143,26 +141,23 @@
#define HAS_MAY_LINK(mode) ((mode) & AA_MAY_LINK)
#define HAS_MAY_LOCK(mode) ((mode) & AA_MAY_LOCK)
#define HAS_EXEC_MMAP(mode) ((mode) & AA_EXEC_MMAP)
-#define HAS_EXEC_INHERIT(mode) (((mode) & AA_EXEC_MODIFIERS) == \
- AA_EXEC_INHERIT)
-#define HAS_EXEC_PROFILE(mode) (((mode) & AA_EXEC_MODIFIERS) == \
- AA_EXEC_PROFILE)
-#define HAS_EXEC_UNCONFINED(mode) (((mode) & AA_EXEC_MODIFIERS) == \
- AA_EXEC_UNCONFINED)
-#define HAS_EXEC_PROFILE_OR_INHERIT(mode) (((mode) & AA_EXEC_MODIFIERS) == \
- AA_EXEC_PROFILE_OR_INHERIT)
+
#define HAS_EXEC_UNSAFE(mode) ((mode) & AA_EXEC_UNSAFE)
#define HAS_CHANGE_PROFILE(mode) ((mode) & AA_CHANGE_PROFILE)
+#include
static inline int is_merged_x_consistent(int a, int b)
{
if ((a & AA_USER_EXEC_TYPE) && (b & AA_USER_EXEC_TYPE) &&
((a & AA_USER_EXEC_TYPE) != (b & AA_USER_EXEC_TYPE)))
+{ fprintf(stderr, "failed user merge 0x%x 0x%x\n", a, b);
return 0;
+}
if ((a & AA_OTHER_EXEC_TYPE) && (b & AA_OTHER_EXEC_TYPE) &&
((a & AA_OTHER_EXEC_TYPE) != (b & AA_OTHER_EXEC_TYPE)))
+{ fprintf(stderr, "failed other merge 0x%x 0x%x\n", a, b);
return 0;
-
+}
return 1;
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/libapparmor_re/regexp.y new/apparmor-parser-2.3/libapparmor_re/regexp.y
--- old/apparmor-parser-2.3/libapparmor_re/regexp.y 2008-04-06 21:52:47.000000000 +0200
+++ new/apparmor-parser-2.3/libapparmor_re/regexp.y 2008-04-16 07:44:21.000000000 +0200
@@ -865,7 +865,7 @@
DenyMatchFlag(uint32_t flag, uint32_t quiet) : MatchFlag(flag, quiet) {}
};
-uint32_t accept_perms(State *state, uint32_t *audit_ctl);
+uint32_t accept_perms(State *state, uint32_t *audit_ctl, int *error);
/**
* verify that there are no conflicting X permissions on the dfa
@@ -874,10 +874,11 @@
*/
State *DFA::verify_perms(void)
{
+ int error = 0;
for (States::iterator i = states.begin(); i != states.end(); i++) {
- uint32_t accept = accept_perms(*i, NULL);
+ uint32_t accept = accept_perms(*i, NULL, &error);
if (*i == start || accept) {
- if (accept & AA_ERROR_BIT)
+ if (error)
return *i;
}
}
@@ -889,9 +890,10 @@
*/
void DFA::dump(ostream& os)
{
+ int error = 0;
for (States::iterator i = states.begin(); i != states.end(); i++) {
uint32_t accept, audit;
- accept = accept_perms(*i, &audit);
+ accept = accept_perms(*i, &audit, &error);
if (*i == start || accept) {
os << **i;
if (*i == start)
@@ -930,7 +932,8 @@
if (*i == start) {
os << "\t\tstyle=bold" << endl;
}
- uint32_t perms = accept_perms(*i, NULL);
+ int error = 0;
+ uint32_t perms = accept_perms(*i, NULL, &error);
if (perms) {
os << "\t\tlabel=\"" << **i << "\\n("
<< perms << ")\"" << endl;
@@ -1152,11 +1155,12 @@
accept.resize(dfa.states.size());
accept2.resize(dfa.states.size());
for (States::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
+ int error = 0;
uint32_t audit_ctl;
- accept[num[*i]] = accept_perms(*i, &audit_ctl);
+ accept[num[*i]] = accept_perms(*i, &audit_ctl, &error);
+ accept2[num[*i]] = audit_ctl;
//if (accept[num[*i]] & AA_CHANGE_HAT)
// fprintf(stderr, "change_hat state %d - 0x%x\n", num[*i], accept[num[*i]]);
-// accept2[num[*i]] = audit_ctl;
}
}
@@ -1510,8 +1514,8 @@
static inline int diff_qualifiers(uint32_t perm1, uint32_t perm2)
{
- return ((perm1 & AA_EXEC_MODIFIERS) && (perm2 & AA_EXEC_MODIFIERS) &&
- (perm1 & AA_EXEC_MODIFIERS) != (perm2 & AA_EXEC_MODIFIERS));
+ return ((perm1 & AA_EXEC_TYPE) && (perm2 & AA_EXEC_TYPE) &&
+ (perm1 & AA_EXEC_TYPE) != (perm2 & AA_EXEC_TYPE));
}
/**
@@ -1519,11 +1523,12 @@
* have any exact matches, then they override the execute and safe
* execute flags.
*/
-uint32_t accept_perms(State *state, uint32_t *audit_ctl)
+uint32_t accept_perms(State *state, uint32_t *audit_ctl, int *error)
{
uint32_t perms = 0, exact_match_perms = 0, audit = 0, exact_audit = 0,
quiet = 0, deny = 0;
+ *error = 0;
for (State::iterator i = state->begin(); i != state->end(); i++) {
MatchFlag *match;
if (!(match= dynamic_cast(*i)))
@@ -1532,7 +1537,7 @@
/* exact match only ever happens with x */
if (!is_merged_x_consistent(exact_match_perms,
match->flag))
- exact_match_perms |= AA_ERROR_BIT;
+ *error = 1;;
exact_match_perms |= match->flag;
exact_audit |= match->audit;
} else if (dynamic_cast(match)) {
@@ -1540,7 +1545,7 @@
quiet |= match->audit;
} else {
if (!is_merged_x_consistent(perms, match->flag))
- perms |= AA_ERROR_BIT;
+ *error = 1;
perms |= match->flag;
audit |= match->audit;
}
@@ -1605,8 +1610,8 @@
{
static MatchFlag *match_flags[2][sizeof(perms) * 8 - 1];
static DenyMatchFlag *deny_flags[2][sizeof(perms) * 8 - 1];
- static MatchFlag *exec_match_flags[2][(AA_EXEC_COUNT << 1) * 2]; /* mods + unsafe *u::o*/
- static ExactMatchFlag *exact_match_flags[2][(AA_EXEC_COUNT << 1) * 2];/* mods + unsafe *u::o*/
+ static MatchFlag *exec_match_flags[2][(AA_EXEC_COUNT << 2) * 2]; /* mods + unsafe + ix *u::o*/
+ static ExactMatchFlag *exact_match_flags[2][(AA_EXEC_COUNT << 2) * 2];/* mods + unsafe +ix *u::o*/
Node *tree = NULL, *accept;
int exact_match;
@@ -1644,7 +1649,7 @@
flip_tree(tree);
-/* 0x3f == 5 bits x mods + 1 bit unsafe mask, after shift */
+/* 0x3f == 4 bits x mods + 1 bit unsafe mask + 1 bit ix, after shift */
#define EXTRACT_X_INDEX(perm, shift) (((perm) >> (shift + 8)) & 0x3f)
//if (perms & ALL_AA_EXEC_TYPE && (!perms & AA_EXEC_BITS))
@@ -1662,7 +1667,7 @@
/* the permissions set is assumed to be non-empty if any audit
* bits are specified */
accept = NULL;
- for (unsigned int n = 0; perms && n < (sizeof(perms) * 8) - 1; n++) {
+ for (unsigned int n = 0; perms && n < (sizeof(perms) * 8) ; n++) {
uint32_t mask = 1 << n;
if (perms & mask) {
@@ -1689,7 +1694,7 @@
index = EXTRACT_X_INDEX(eperm, AA_USER_SHIFT);
} else {
eperm = mask | (perms & AA_OTHER_EXEC_TYPE);
- index = EXTRACT_X_INDEX(eperm, AA_OTHER_SHIFT) + (AA_EXEC_COUNT << 1);
+ index = EXTRACT_X_INDEX(eperm, AA_OTHER_SHIFT) + (AA_EXEC_COUNT << 2);
}
//fprintf(stderr, "index %d eperm 0x%x\n", index, eperm);
if (exact_match) {
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/Makefile new/apparmor-parser-2.3/Makefile
--- old/apparmor-parser-2.3/Makefile 2007-11-16 10:32:38.000000000 +0100
+++ new/apparmor-parser-2.3/Makefile 2008-04-16 19:27:23.000000000 +0200
@@ -1,4 +1,4 @@
-# $Id: Makefile 1029 2007-11-16 09:32:38Z jrjohansen $
+# $Id: Makefile 1201 2008-04-16 17:27:23Z steve-beattie $
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
# NOVELL (All rights reserved)
@@ -71,13 +71,13 @@
SRCS = parser_include.c parser_interface.c parser_lex.c parser_main.c \
parser_misc.c parser_merge.c parser_symtab.c parser_yacc.c \
- parser_regex.c parser_variable.c parser_policy.c
+ parser_regex.c parser_variable.c parser_policy.c parser_alias.c
HDRS = parser.h parser_include.h immunix.h
TOOLS = apparmor_parser
OBJECTS = parser_lex.o parser_yacc.o parser_main.o parser_interface.o \
parser_include.o parser_merge.o parser_symtab.o parser_misc.o \
- parser_regex.o parser_variable.o parser_policy.o
+ parser_regex.o parser_variable.o parser_policy.o parser_alias.o
AAREDIR= libapparmor_re
AAREOBJECTS = ${AAREDIR}/libapparmor_re.a
@@ -96,6 +96,9 @@
$(filter-out parser_yacc.o, \
$(filter-out parser_main.o, ${OBJECTS} ${PCREOBJECTS})))
+ifdef V
+ VERBOSE = 1
+endif
ifndef VERBOSE
VERBOSE = 0
endif
@@ -171,6 +174,9 @@
parser_policy.o: parser_policy.c parser.h parser_yacc.h
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
+parser_alias.o: parser_alias.c parser.h
+ $(CC) $(EXTRA_CFLAGS) -c -o $@ $<
+
parser_version.h: Makefile
@echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
@mv -f .ver $@
@@ -188,7 +194,7 @@
tst_variable: parser_variable.c parser.h $(filter-out parser_variable.o, ${TEST_OBJECTS})
$(Q)$(CC) -DUNIT_TEST $(EXTRA_CFLAGS) $(TEST_FLAGS) -o $@ $< $(filter-out parser_variable.o, ${TEST_OBJECTS}) $(BUILD_OUTPUT)
-tst_misc: parser_misc.c parser.h parser_yacc.h
+tst_misc: parser_misc.c parser.h parser_yacc.h af_names.h cap_names.h
$(Q)$(CC) -DUNIT_TEST $(EXTRA_CFLAGS) $(TEST_FLAGS) -o $@ $< $(BUILD_OUTPUT)
tst_regex: parser_regex.c parser.h parser_yacc.h $(PCREOBJECTS)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_alias.c new/apparmor-parser-2.3/parser_alias.c
--- old/apparmor-parser-2.3/parser_alias.c 1970-01-01 01:00:00.000000000 +0100
+++ new/apparmor-parser-2.3/parser_alias.c 2008-04-11 20:43:22.000000000 +0200
@@ -0,0 +1,168 @@
+/* $Id: parser_symtab.c 565 2007-04-11 09:12:51Z jrjohansen $ */
+
+/*
+ * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ * NOVELL (All rights reserved)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Novell, Inc.
+ */
+
+#define _GNU_SOURCE /* for tdestroy(3) */
+#include
+#include
+#include
+#include
+#include
+#include
+#define _(s) gettext(s)
+
+#include "immunix.h"
+#include "parser.h"
+
+struct alias_rule {
+ char *from;
+ char *to;
+};
+
+static void *alias_table;
+
+static int compare_alias(const void *a, const void *b)
+{
+ char *a_name = ((struct alias_rule *) a)->from;
+ char *b_name = ((struct alias_rule *) b)->from;
+ return strcmp(a_name, b_name);
+}
+
+static struct alias_rule *lookup_alias(const char *alias)
+{
+ struct alias_rule tmp = { alias, NULL} , **lookup;
+
+ lookup = (struct alias_rule **) tfind(&tmp, alias_table, (comparison_fn_t) &compare_alias);
+ if (!lookup)
+ return NULL;
+
+ return *lookup;
+}
+
+int new_alias(const char *from, const char *to)
+{
+ struct alias_rule *alias, **result;
+
+ alias = malloc(sizeof(struct alias_rule));
+ if (!alias) {
+ PERROR("Failed to allocate memory: %s\n", strerror(errno));
+ goto fail;
+ }
+ memset(alias, 0, sizeof(*alias));
+ alias->from = strdup(from);
+ if (!alias->from) {
+ PERROR("Failed to allocate memory: %s\n", strerror(errno));
+ goto fail;
+ }
+ alias->to = strdup(to);
+ if (!alias->to) {
+ PERROR("Failed to allocate memory: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ result = (struct alias_rule **) tsearch(alias, &alias_table, (comparison_fn_t) &compare_alias);
+ if (!result) {
+ PERROR("Failed to allocate memory: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ if (*result != alias) {
+ /* already existing alias */
+ PERROR("'%s' is already defined\n", from);
+ goto fail;
+ }
+
+ return 1;
+
+fail:
+ if (alias) {
+ if (alias->from)
+ free(alias->from);
+ if (alias->to)
+ free(alias->to);
+ free(alias);
+ }
+ return 0;
+}
+
+static char *do_alias(struct alias_rule *alias, const char *target)
+{
+ int len = strlen(target) - strlen(alias->from) + strlen(alias->to);
+ char *new = malloc(len + 1);
+ if (!new) {
+ PERROR("Failed to allocate memory: %s\n", strerror(errno));
+ return NULL;
+ }
+ sprintf(new, "%s%s", alias->to, target + strlen(alias->from));
+//fprintf(stderr, "replaced alias: from: %s, to: %s, name: %s\n %s\n", alias->from, alias->to, target, new);
+ return new;
+}
+
+static struct cod_entry *target_list;
+
+static void process_entries(const void *nodep, VISIT value, int __unused level)
+{
+ struct alias_rule **t = (struct alias_rule **) nodep;
+ struct cod_entry *entry;
+ int len;
+
+ if (value == preorder || value == endorder)
+ return;
+
+ len = strlen((*t)->from);
+
+ list_for_each(target_list, entry) {
+ if (entry->mode & (AA_SHARED_PERMS & AA_PTRACE_PERMS))
+ continue;
+ if (entry->name && strncmp((*t)->from, entry->name, len) == 0) {
+ char *new = do_alias(*t, entry->name);
+ if (!new)
+ return;
+ free(entry->name);
+ entry->name = new;
+ }
+ if (entry->link_name &&
+ strncmp((*t)->from, entry->link_name, len) == 0) {
+ char *new = do_alias(*t, entry->link_name);
+ if (!new)
+ return;
+ free(entry->link_name);
+ entry->link_name = new;
+ }
+ }
+}
+
+void replace_aliases(void *list)
+{
+ target_list = list;
+ twalk(alias_table, process_entries);
+}
+
+static void free_alias(void *nodep)
+{
+ struct alias_rule *t = (struct alias_rule *)nodep;
+ free(t->from);
+ free(t->to);
+ free(t);
+}
+
+void free_aliases(void)
+{
+ if (alias_table)
+ tdestroy(alias_table, &free_alias);
+}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser.h new/apparmor-parser-2.3/parser.h
--- old/apparmor-parser-2.3/parser.h 2008-04-06 21:55:46.000000000 +0200
+++ new/apparmor-parser-2.3/parser.h 2008-04-16 07:45:02.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser.h 1174 2008-04-06 19:55:46Z jrjohansen $ */
+/* $Id: parser.h 1197 2008-04-16 05:45:02Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
@@ -31,6 +31,12 @@
int audit;
};
+struct named_transition {
+ int present;
+ char *namespace;
+ char *name;
+};
+
struct cod_pattern {
char *regex; // posix regex
pcre *compiled; // compiled regex, size is compiled->size
@@ -40,6 +46,7 @@
char *namespace;
char *name;
char *link_name;
+ char *nt_name;
struct codomain *codomain; /* Special codomain defined
* just for this executable */
int mode; /* mode is 'or' of AA_* bits */
@@ -73,6 +80,9 @@
char *name; /* codomain name */
char *sub_name; /* subdomain name or NULL */
int default_deny; /* TRUE or FALSE */
+ int local;
+ int local_mode; /* true if local, not hat */
+ int local_audit;
struct codomain *parent;
@@ -92,6 +102,7 @@
struct aa_rlimits rlimits;
+ char *exec_table[AA_EXEC_COUNT];
struct cod_entry *entries;
void *hat_table;
//struct codomain *next;
@@ -143,6 +154,8 @@
#define COD_UNSAFE_UNCONFINED_CHAR 'u'
#define COD_PROFILE_CHAR 'P'
#define COD_UNSAFE_PROFILE_CHAR 'p'
+#define COD_LOCAL_CHAR 'C'
+#define COD_UNSAFE_LOCAL_CHAR 'c'
#define OPTION_ADD 1
#define OPTION_REMOVE 2
@@ -240,6 +253,11 @@
extern void dump_symtab(void);
extern void dump_expanded_symtab(void);
+/* parser_alias.c */
+extern int new_alias(const char *from, const char *to);
+extern void replace_aliases(void *list);
+extern void free_aliases(void);
+
/* parser_merge.c */
extern int codomain_merge_rules(struct codomain *cod);
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_interface.c new/apparmor-parser-2.3/parser_interface.c
--- old/apparmor-parser-2.3/parser_interface.c 2008-04-06 21:55:46.000000000 +0200
+++ new/apparmor-parser-2.3/parser_interface.c 2008-04-16 09:54:51.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_interface.c 1174 2008-04-06 19:55:46Z jrjohansen $ */
+/* $Id: parser_interface.c 1198 2008-04-16 07:54:51Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -61,7 +61,7 @@
#define SD_STR_LEN (sizeof(u16))
#define SUBDOMAIN_INTERFACE_VERSION 2
-#define SUBDOMAIN_INTERFACE_DFA_VERSION 4
+#define SUBDOMAIN_INTERFACE_DFA_VERSION 5
int sd_serialize_codomain(int option, struct codomain *cod);
@@ -377,13 +377,11 @@
return 1;
}
-inline int sd_write_string(sd_serialize *p, char *b, char *name)
+static int sd_write_strn(sd_serialize *p, char *b, int size, char *name)
{
u16 tmp;
- int size;
if (!sd_write_name(p, name))
return 0;
- size = strlen(b) + 1;
if (!sd_prepare_write(p, SD_STRING, SD_STR_LEN + size))
return 0;
tmp = cpu_to_le16(size);
@@ -394,6 +392,11 @@
return 1;
}
+inline int sd_write_string(sd_serialize *p, char *b, char *name)
+{
+ return sd_write_strn(p, b, strlen(b) + 1, name);
+}
+
inline int sd_write_struct(sd_serialize *p, char *name)
{
if (!sd_write_name(p, name))
@@ -527,6 +530,44 @@
return 1;
}
+int sd_serialize_xtable(sd_serialize *p, char **table)
+{
+ int count, i;
+ if (!table[4])
+ return 1;
+ if (!sd_write_struct(p, "xtable"))
+ return 0;
+ count = 0;
+ for (i = 4; i < AA_EXEC_COUNT; i++) {
+ if (table[i])
+ count++;
+ }
+
+ if (!sd_write_array(p, NULL, count))
+ return 0;
+
+ for (i = 4; i < count + 4; i++) {
+ int len = strlen(table[i]) + 1;
+
+ /* if its a namespace make sure the second : is overwritten
+ * with 0, so that the namespace and name are \0 seperated
+ */
+ if (*table[i] == ':') {
+ char *tmp = table[i] + 1;
+ strsep(&tmp, ":");
+ }
+ if (!sd_write_strn(p, table[i], len, NULL))
+ return 0;
+
+ }
+ if (!sd_write_arrayend(p))
+ return 0;
+
+ if (!sd_write_structend(p))
+ return 0;
+ return 1;
+}
+
int count_file_ents(struct cod_entry *list)
{
struct cod_entry *entry;
@@ -634,6 +675,9 @@
if (regex_type == AARE_DFA) {
if (!sd_serialize_dfa(p, profile->dfa, profile->dfa_size))
return 0;
+
+ if (!sd_serialize_xtable(p, profile->exec_table))
+ return 0;
} else {
/* pcre globbing entries */
if (count_pcre_ents(profile->entries)) {
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_lex.l new/apparmor-parser-2.3/parser_lex.l
--- old/apparmor-parser-2.3/parser_lex.l 2008-04-06 21:55:46.000000000 +0200
+++ new/apparmor-parser-2.3/parser_lex.l 2008-04-16 07:44:21.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_lex.l 1174 2008-04-06 19:55:46Z jrjohansen $ */
+/* $Id: parser_lex.l 1196 2008-04-16 05:44:21Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -53,7 +53,7 @@
END_OF_RULE [,]
SEPERATOR {UP}
RANGE -
-MODE_CHARS ([RrWwaLlMmkXx])|([Pp][Xx])|([Uu][Xx])|([Ii][Xx])|([Pp][Ii][Xx])
+MODE_CHARS ([RrWwaLlMmkXx])|(([Uu]|[Pp]|[Cc])[Xx])|(([Pp]|[Cc])?[Ii][Xx])
MODES {MODE_CHARS}+
WS [[:blank:]]
NUMBER [[:digit:]]+
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_merge.c new/apparmor-parser-2.3/parser_merge.c
--- old/apparmor-parser-2.3/parser_merge.c 2008-03-13 19:39:03.000000000 +0100
+++ new/apparmor-parser-2.3/parser_merge.c 2008-04-10 02:56:31.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_merge.c 1128 2008-03-13 18:39:03Z jrjohansen $ */
+/* $Id: parser_merge.c 1188 2008-04-10 00:56:31Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -67,6 +67,12 @@
if ((*e1)->deny != (*e2)->deny)
return (*e1)->deny < (*e2)->deny ? -1 : 1;
+ /* rules with ptrace and change_profile can only merge with
+ * rules with exact same perm */
+ if (((*e1)->mode & (AA_CHANGE_PROFILE | AA_PTRACE_PERMS)) !=
+ ((*e2)->mode & (AA_CHANGE_PROFILE | AA_PTRACE_PERMS)))
+ return 1;
+
return strcmp((*e1)->name, (*e2)->name);
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_misc.c new/apparmor-parser-2.3/parser_misc.c
--- old/apparmor-parser-2.3/parser_misc.c 2008-04-06 21:55:46.000000000 +0200
+++ new/apparmor-parser-2.3/parser_misc.c 2008-04-16 07:44:21.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_misc.c 1174 2008-04-06 19:55:46Z jrjohansen $ */
+/* $Id: parser_misc.c 1196 2008-04-16 05:44:21Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -70,6 +70,8 @@
{"profile", TOK_PROFILE},
{"set", TOK_SET},
{"rlimit", TOK_RLIMIT},
+ {"alias", TOK_ALIAS},
+ {"ptrace", TOK_PTRACE},
/* terminate */
{NULL, 0}
};
@@ -441,7 +443,7 @@
static int parse_sub_mode(const char *str_mode, const char *mode_desc)
{
-#define IS_DIFF_QUAL(mode, q) (((mode) & AA_MAY_EXEC) && (((mode) & (AA_EXEC_MODIFIERS | AA_EXEC_UNSAFE)) != (q)))
+#define IS_DIFF_QUAL(mode, q) (((mode) & AA_MAY_EXEC) && (((mode) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE)))
int mode = 0;
const char *p;
@@ -491,7 +493,7 @@
case COD_INHERIT_CHAR:
PDEBUG("Parsing mode: found INHERIT\n");
- if (IS_DIFF_QUAL(mode, AA_EXEC_INHERIT)) {
+ if (mode & AA_EXEC_MODIFIERS) {
yyerror(_("Exec qualifier 'i' invalid, conflicting qualifier already specified"));
} else {
if (next != tolower(next))
@@ -508,40 +510,48 @@
COD_UNSAFE_UNCONFINED_CHAR, COD_EXEC_CHAR);
/* fall through */
case COD_UNCONFINED_CHAR:
+ tmode |= AA_EXEC_UNCONFINED | AA_MAY_EXEC;
PDEBUG("Parsing mode: found UNCONFINED\n");
- if (IS_DIFF_QUAL(mode, tmode | AA_EXEC_UNCONFINED)) {
+ if (IS_DIFF_QUAL(mode, tmode)) {
yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"),
this);
} else {
if (next != tolower(next))
warn_uppercase();
- mode |= tmode | AA_EXEC_UNCONFINED |
- AA_MAY_EXEC;
+ mode |= tmode;
p++; /* skip 'x' */
}
tmode = 0;
break;
case COD_UNSAFE_PROFILE_CHAR:
+ case COD_UNSAFE_LOCAL_CHAR:
tmode = AA_EXEC_UNSAFE;
/* fall through */
case COD_PROFILE_CHAR:
+ case COD_LOCAL_CHAR:
+ if (tolower(this) == COD_UNSAFE_PROFILE_CHAR)
+ tmode |= AA_EXEC_PROFILE | AA_MAY_EXEC;
+ else
+ {
+ tmode |= AA_EXEC_LOCAL | AA_MAY_EXEC;
+ }
PDEBUG("Parsing mode: found PROFILE\n");
if (tolower(next) == COD_INHERIT_CHAR) {
- if (IS_DIFF_QUAL(mode, tmode | AA_EXEC_PROFILE_OR_INHERIT)) {
+ tmode |= AA_EXEC_INHERIT;
+ if (IS_DIFF_QUAL(mode, tmode)) {
yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), this, next);
} else {
- mode |= tmode | AA_MAY_EXEC |
- AA_EXEC_PROFILE_OR_INHERIT;
+ mode |= tmode;
p += 2; /* skip x */
}
- } else if (IS_DIFF_QUAL(mode, tmode | AA_EXEC_PROFILE)) {
- yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"),
- this);
+ } else if (IS_DIFF_QUAL(mode, tmode)) {
+ yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"), this);
+
} else {
if (next != tolower(next))
warn_uppercase();
- mode |= tmode | AA_EXEC_PROFILE | AA_MAY_EXEC;
+ mode |= tmode;
p++; /* skip 'x' */
}
tmode = 0;
@@ -684,20 +694,6 @@
printf("%c", COD_LINK_CHAR);
if (HAS_MAY_LOCK(mask))
printf("%c", COD_LOCK_CHAR);
- if (HAS_EXEC_INHERIT(mask))
- printf("%c", COD_INHERIT_CHAR);
- if (HAS_EXEC_UNCONFINED(mask)) {
- if (HAS_EXEC_UNSAFE(mask))
- printf("%c", COD_UNSAFE_UNCONFINED_CHAR);
- else
- printf("%c", COD_UNCONFINED_CHAR);
- }
- if (HAS_EXEC_PROFILE(mask)) {
- if (HAS_EXEC_UNSAFE(mask))
- printf("%c", COD_UNSAFE_PROFILE_CHAR);
- else
- printf("%c", COD_PROFILE_CHAR);
- }
if (HAS_EXEC_MMAP(mask))
printf("%c", COD_MMAP_CHAR);
if (HAS_MAY_EXEC(mask))
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_policy.c new/apparmor-parser-2.3/parser_policy.c
--- old/apparmor-parser-2.3/parser_policy.c 2008-04-06 21:55:27.000000000 +0200
+++ new/apparmor-parser-2.3/parser_policy.c 2008-04-16 11:48:06.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_policy.c 1173 2008-04-06 19:55:27Z jrjohansen $ */
+/* $Id: parser_policy.c 1199 2008-04-16 09:48:06Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -93,8 +93,91 @@
}
}
+static int add_named_transition(struct codomain *cod, struct cod_entry *entry)
+{
+ char *name = NULL;
+ int i;
+
+ /* check to see if it is a local transition */
+ if (!entry->namespace) {
+ char *sub = strstr(entry->nt_name, "//");
+ /* does the subprofile name match the rule */
+#if 0
+/* disable cix checking as cod->name is not available. Need to rework */
+ if (sub && strncmp(cod->name, sub, sub - entry->nt_name) &&
+ strcmp(sub + 2, entry->name) == 0) {
+ free(entry->nt_name);
+ entry->nt_name = NULL;
+ return AA_EXEC_LOCAL >> 10;
+ } else if (((entry->mode & AA_USER_EXEC_MODIFIERS) ==
+ SHIFT_MODE(AA_EXEC_LOCAL, AA_USER_SHIFT)) ||
+ ((entry->mode & AA_OTHER_EXEC_MODIFIERS) ==
+ SHIFT_MODE(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) {
+ if (strcmp(entry->nt_name, entry->name) == 0) {
+ free(entry->nt_name);
+ entry->nt_name = NULL;
+ return AA_EXEC_LOCAL >> 10;
+ }
+ /* specified as cix so profile name is implicit */
+ name = malloc(strlen(cod->name) + strlen(entry->nt_name)
+ + 3);
+ if (!name) {
+ PERROR("Memory allocation error\n");
+ exit(1);
+ }
+ sprintf(name, "%s//%s", cod->name, entry->nt_name);
+ free(entry->nt_name);
+ entry->nt_name = name;
+ }
+#endif
+ }
+ if (entry->namespace) {
+ name = malloc(strlen(entry->namespace) + strlen(entry->nt_name) + 3);
+ if (!name) {
+ PERROR("Memory allocation error\n");
+ exit(1);
+ }
+ sprintf(name, ":%s:%s", entry->namespace, entry->nt_name);
+ free(entry->namespace);
+ free(entry->nt_name);
+ entry->namespace = NULL;
+ entry->nt_name = NULL;
+ } else {
+ name = entry->nt_name;
+ }
+
+ for (i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++) {
+ if (!cod->exec_table[i]) {
+ cod->exec_table[i] = name;
+ return i;
+ } else if (strcmp(cod->exec_table[i], name) == 0) {
+ /* name already in table */
+ free(name);
+ return i;
+ }
+ }
+ free(name);
+ return 0;
+}
+
void add_entry_to_policy(struct codomain *cod, struct cod_entry *entry)
{
+ if (entry->nt_name) {
+ int mode = 0;
+ int n = add_named_transition(cod, entry);
+ if (!n) {
+ PERROR("Profile %s has to many specified profile transitions.\n", cod->name);
+ exit(1);
+ }
+ if (entry->mode & AA_USER_EXEC)
+ mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT);
+ if (entry->mode & AA_OTHER_EXEC)
+ mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT);
+ entry->mode = ((entry->mode & ~AA_ALL_EXEC_MODIFIERS) |
+ (mode & AA_ALL_EXEC_MODIFIERS));
+ entry->namespace = NULL;
+ entry->nt_name = NULL;
+ }
entry->next = cod->entries;
cod->entries = entry;
}
@@ -230,6 +313,28 @@
return 0;
}
+
+static void __process_alias(const void *nodep, const VISIT value,
+ const int __unused depth)
+{
+ struct codomain **t = (struct codomain **) nodep;
+
+ if (value == preorder || value == endorder)
+ return;
+
+ if ((*t)->entries)
+ replace_aliases((*t)->entries);
+
+ if ((*t)->hat_table)
+ twalk((*t)->hat_table, __process_alias);
+}
+
+int post_process_alias(void)
+{
+ twalk(policy_list, __process_alias);
+ return 0;
+}
+
#define CHANGEHAT_PATH "/proc/[0-9]*/attr/current"
/* add file rules to access /proc files to call change_hat()
@@ -250,6 +355,10 @@
if (!(*t)->hat_table && !(*t)->parent)
return;
+ /* don't add hat rules for local_profiles */
+ if ((*t)->local)
+ return;
+
/* add rule to grant permission to change_hat - AA 2.3 requirement,
* rules are added to the parent of the hat
*/
@@ -297,6 +406,10 @@
if (!(*t)->hat_table && !(*t)->parent)
return;
+ /* don't add hat rules for local_profiles */
+ if ((*t)->local)
+ return;
+
/* hat */
if ((*t)->parent) {
struct cod_entry *entry, *new_ent;
@@ -555,6 +668,13 @@
return retval;
}
+ retval = post_process_alias();
+ if (retval != 0) {
+ PERROR(_("%s: Errors found during postprocess. Aborting.\n"),
+ progname);
+ return retval;
+ }
+
retval = post_merge_rules();
if (retval != 0) {
PERROR(_("%s: Errors found in combining rules postprocessing. Aborting.\n"),
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_regex.c new/apparmor-parser-2.3/parser_regex.c
--- old/apparmor-parser-2.3/parser_regex.c 2008-03-13 19:39:03.000000000 +0100
+++ new/apparmor-parser-2.3/parser_regex.c 2008-04-16 07:44:21.000000000 +0200
@@ -1,4 +1,4 @@
-/* $Id: parser_regex.c 1128 2008-03-13 18:39:03Z jrjohansen $ */
+/* $Id: parser_regex.c 1196 2008-04-16 05:44:21Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -496,13 +496,13 @@
/* ix implies m but the apparmor module does not add m bit to
* dfa states like it does for pcre
*/
- if (((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_MODIFIERS) ==
- AA_EXEC_INHERIT)
+ if ((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT)
entry->mode |= AA_EXEC_MMAP << AA_OTHER_SHIFT;
- if (((entry->mode >> AA_USER_SHIFT) & AA_EXEC_MODIFIERS) ==
- AA_EXEC_INHERIT)
+ if ((entry->mode >> AA_USER_SHIFT) & AA_EXEC_INHERIT)
entry->mode |= AA_EXEC_MMAP << AA_USER_SHIFT;
+ /* relying on ptrace and change_profile not getting merged earlier */
+
/* the link bit on the first pair entry should not get masked
* out by a deny rule, as both pieces of the link pair must
* match. audit info for the link is carried on the second
@@ -518,6 +518,7 @@
entry->audit))
return FALSE;
}
+
if (entry->mode & (AA_LINK_BITS)) {
/* add the pair rule */
char lbuf[PATH_MAX + 8];
@@ -550,6 +551,19 @@
return FALSE;
}
}
+ if (entry->mode & (AA_USER_PTRACE | AA_OTHER_PTRACE)) {
+ int mode = entry->mode & (AA_USER_PTRACE | AA_OTHER_PTRACE);
+ if (entry->namespace) {
+ char *vec[2];
+ vec[0] = entry->namespace;
+ vec[1] = entry->name;
+ if (!aare_add_rule_vec(dfarules, 0, mode, 0, 2, vec))
+ return FALSE;
+ } else {
+ if (!aare_add_rule(dfarules, entry->name, 0, mode, 0))
+ return FALSE;
+ }
+ }
return TRUE;
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/parser_yacc.y new/apparmor-parser-2.3/parser_yacc.y
--- old/apparmor-parser-2.3/parser_yacc.y 2008-04-07 07:26:02.000000000 +0200
+++ new/apparmor-parser-2.3/parser_yacc.y 2008-04-18 03:40:40.000000000 +0200
@@ -1,5 +1,5 @@
%{
-/* $Id: parser_yacc.y 1176 2008-04-07 05:26:02Z jrjohansen $ */
+/* $Id: parser_yacc.y 1203 2008-04-18 01:40:40Z jrjohansen $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
@@ -68,7 +68,11 @@
void free_value_list(struct value_list *list);
struct cod_entry *do_file_rule(char *namespace, char *id, int mode,
- char *link_id);
+ char *link_id, char *nt);
+
+void add_local_entry(struct codomain *cod);
+
+struct codomain *do_local_profile(struct codomain *cod, char *name, int mode, int audit);
%}
@@ -102,6 +106,8 @@
%token TOK_DENY
%token TOK_PROFILE
%token TOK_SET
+%token TOK_ALIAS
+%token TOK_PTRACE
/* rlimits */
%token TOK_RLIMIT
@@ -151,6 +157,7 @@
char *var_val;
struct value_list *val_list;
int boolean;
+ struct named_transition transition;
}
%type <id> TOK_ID
@@ -159,6 +166,7 @@
%type <cod> profile
%type <cod> rules
%type <cod> hat
+%type <cod> local_profile
%type <cod> cond_rule
%type network_rule
%type rule
@@ -181,10 +189,12 @@
%type <boolean> opt_audit_flag
%type <boolean> opt_owner_flag
%type <boolean> opt_profile_flag
+%type <transition> opt_named_transition
+
%%
-list: varlist profilelist
+list: aliaslist varlist profilelist
{ /* nothing */ };
profilelist: { /* nothing */ };
@@ -244,6 +254,17 @@
$$ = cod;
};
+aliaslist: { /* nothing */ }
+ | aliaslist alias { /* nothing */ };
+
+alias: TOK_ALIAS TOK_ID TOK_ARROW TOK_ID TOK_END_OF_RULE
+ {
+ if (!new_alias($2, $4))
+ yyerror(_("Failed to create alias %s -> %s\n"), $2, $4);
+ free($2);
+ free($4);
+ };
+
varlist: { /* nothing */ }
varlist: varlist varassign
@@ -389,6 +410,7 @@
opt_subset_flag: { /* nothing */ $$ = 0; }
| TOK_SUBSET { $$ = 1; }
+ | TOK_LE { $$ = 1; }
opt_audit_flag: { /* nothing */ $$ = 0; }
| TOK_AUDIT { $$ = 1; };
@@ -421,9 +443,9 @@
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
if ($4 == 1)
- $5->mode &= (AA_USER_PERMS | AA_SHARED_PERMS);
+ $5->mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
else if ($4 == 2)
- $5->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
+ $5->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
/* only set audit ctl quieting if the rule is not audited */
if (!$2)
$5->audit = $5->mode & ~ALL_AA_EXEC_TYPE;
@@ -438,13 +460,15 @@
PDEBUG("rules rule: (%s)\n", $4->name);
if (!$4)
yyerror(_("Assert: `rule' returned NULL."));
- if (($4->mode & AA_EXEC_BITS) && !($4->mode & ALL_AA_EXEC_TYPE))
- yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
+ if (($4->mode & AA_EXEC_BITS) &&
+ !($4->mode & ALL_AA_EXEC_TYPE) &&
+ !($4->nt_name))
+ yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'"));
if ($3 == 1)
- $4->mode &= (AA_USER_PERMS | AA_SHARED_PERMS);
+ $4->mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
else if ($3 == 2)
- $4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
+ $4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
if ($2)
$4->audit = $4->mode & ~ALL_AA_EXEC_TYPE;
@@ -467,9 +491,9 @@
yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
}
if ($3 == 1)
- entry->mode &= (AA_USER_PERMS | AA_SHARED_PERMS);
+ entry->mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
else if ($3 == 2)
- entry->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
+ entry->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
if ($2 && !entry->deny)
entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE;
@@ -609,6 +633,16 @@
$$ = $1;
};
+rules: rules local_profile
+ {
+ PDEBUG("Matched: hat rule\n");
+ if (!$2)
+ yyerror(_("Assert: 'local_profile rule' returned NULL."));
+ add_hat_to_policy($1, $2);
+ add_local_entry($2);
+ $$ = $1;
+ };
+
rules: rules cond_rule
{
PDEBUG("Matched: conditional rules\n");
@@ -766,23 +800,61 @@
id_or_var: TOK_ID { $$ = $1; }
id_or_var: TOK_SET_VAR { $$ = $1; };
-rule: id_or_var file_mode TOK_END_OF_RULE
+opt_named_transition:
+ { /* nothing */
+ $$.present = 0;
+ $$.namespace = NULL;
+ $$.name = NULL;
+ }
+ | TOK_ARROW id_or_var
+ {
+ $$.present = 1;
+ $$.namespace = NULL;
+ $$.name = $2;
+ }
+ | TOK_ARROW TOK_COLON id_or_var TOK_COLON id_or_var
+ {
+ $$.present = 1;
+ $$.namespace = $3;
+ $$.name = $5;
+ };
+
+rule: id_or_var file_mode opt_named_transition TOK_END_OF_RULE
{
- $$ = do_file_rule(NULL, $1, $2, NULL);
+ $$ = do_file_rule($3.namespace, $1, $2, NULL, $3.name);
};
-rule: file_mode id_or_var TOK_END_OF_RULE
+rule: file_mode opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE
{
- $$ = do_file_rule(NULL, $2, $1 & ~ALL_AA_EXEC_UNSAFE, NULL);
+ if ($2 && ($1 & ~AA_LINK_BITS))
+ yyerror(_("subset can only be used with link rules."));
+ if ($4.present && ($1 & AA_LINK_BITS) && ($1 & AA_EXEC_BITS))
+ yyerror(_("link and exec perms conflict on a file rule using ->"));
+ if ($4.present && $4.namespace && ($1 & AA_LINK_BITS))
+ yyerror(_("link perms are not allowed on a named profile transition.\n"));
+ if (($1 & AA_LINK_BITS)) {
+ $$ = do_file_rule(NULL, $3, $1 & ~ALL_AA_EXEC_UNSAFE,
+ $4.name, NULL);
+ $$->subset = $2;
+
+ } else {
+ $$ = do_file_rule($4.namespace, $3, $1 & ~ALL_AA_EXEC_UNSAFE, NULL, $4.name);
+ }
};
-rule: TOK_UNSAFE file_mode id_or_var TOK_END_OF_RULE
+rule: TOK_UNSAFE file_mode id_or_var opt_named_transition TOK_END_OF_RULE
{
int mode = (($2 & AA_EXEC_BITS) << 8) & ALL_AA_EXEC_UNSAFE;
+
if (!($2 & AA_EXEC_BITS))
yyerror(_("unsafe rule missing exec permissions"));
- $$ = do_file_rule(NULL, $3, ($2 & ~ALL_AA_EXEC_UNSAFE) | mode,
- NULL);
+
+ if ($4.present && ($2 & AA_LINK_BITS))
+ yyerror(_("link perms are not allowed on a named profile transtion.\n"));
+
+ $$ = do_file_rule($4.namespace, $3,
+ ($2 & ~ALL_AA_EXEC_UNSAFE) | mode,
+ NULL, $4.name);
};
rule: id_or_var file_mode id_or_var
@@ -799,25 +871,26 @@
struct cod_entry *entry;
PDEBUG("Matched: link tok_id (%s) -> (%s)\n", $3, $5);
entry = new_entry(NULL, $3, AA_LINK_BITS, $5);
- if (!entry)
- yyerror(_("Memory allocation error."));
entry->subset = $2;
PDEBUG("rule.entry: link (%s)\n", entry->name);
$$ = entry;
};
-rule: file_mode opt_subset_flag TOK_ID TOK_ARROW TOK_ID TOK_END_OF_RULE
+rule: TOK_PTRACE TOK_ID TOK_END_OF_RULE
{
struct cod_entry *entry;
- PDEBUG("Matched: link tok_id (%s) -> (%s)\n", $3, $5);
- if ($1 & ~AA_LINK_BITS)
- yyerror(_("only link perms can be specified in a link rule."));
- entry = new_entry(NULL, $3, AA_LINK_BITS, $5);
+ entry = new_entry(NULL, $2, AA_USER_PTRACE | AA_OTHER_PTRACE, NULL);
if (!entry)
yyerror(_("Memory allocation error."));
- entry->subset = $2;
+ $$ = entry;
+ };
- PDEBUG("rule.entry: link (%s)\n", entry->name);
+rule: TOK_PTRACE TOK_COLON TOK_ID TOK_COLON TOK_ID TOK_END_OF_RULE
+ {
+ struct cod_entry *entry;
+ entry = new_entry($3, $5, AA_USER_PTRACE | AA_OTHER_PTRACE, NULL);
+ if (!entry)
+ yyerror(_("Memory allocation error."));
$$ = entry;
};
@@ -851,6 +924,56 @@
$$ = cod;
};
+/*
+local_profile: opt_audit_flag opt_owner_flag TOK_ID file_mode TOK_ARROW TOK_OPEN rules TOK_CLOSE
+ {
+ int audit = 0, mode = $4;
+ if ($2 == 1)
+ mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
+ else if ($2 == 2)
+ mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
+ if ($1)
+ audit = mode & ~ALL_AA_EXEC_TYPE;
+
+ $$ = do_local_profile($7, $3, mode, audit);
+ };
+
+local_profile: opt_audit_flag opt_owner_flag file_mode TOK_ID TOK_ARROW TOK_OPEN rules TOK_CLOSE
+ {
+ int audit = 0, mode = $3;
+ mode &= ~ALL_AA_EXEC_UNSAFE;
+ if ($2 == 1)
+ mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
+ else if ($2 == 2)
+ mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
+ if ($1)
+ audit = mode & ~ALL_AA_EXEC_TYPE;
+
+ $$ = do_local_profile($7, $4, mode, audit);
+ };
+
+local_profile: opt_audit_flag opt_owner_flag TOK_UNSAFE file_mode TOK_ID TOK_ARROW TOK_OPEN rules TOK_CLOSE
+ {
+ int unsafe = (($4 & AA_EXEC_BITS) << 8) & ALL_AA_EXEC_UNSAFE;
+ int audit = 0, mode = ($4 & ~ALL_AA_EXEC_UNSAFE) | unsafe;
+ if ($2 == 1)
+ mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
+ else if ($2 == 2)
+ mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
+ if ($1)
+ audit = mode & ~ALL_AA_EXEC_TYPE;
+
+ $$ = do_local_profile($8, $5, mode, audit);
+ };
+*/
+
+local_profile: TOK_PROFILE TOK_ID flags TOK_OPEN rules TOK_CLOSE
+ {
+ struct codomain *cod = do_local_profile($5, $2, 0, 0);
+ cod->flags = $3;
+ $$ = cod;
+ };
+
network_rule: TOK_NETWORK TOK_END_OF_RULE
{
int family;
@@ -901,22 +1024,22 @@
free($1);
}
-change_profile: TOK_CHANGE_PROFILE TOK_ID TOK_END_OF_RULE
+change_profile: TOK_CHANGE_PROFILE TOK_ARROW TOK_ID TOK_END_OF_RULE
{
struct cod_entry *entry;
- PDEBUG("Matched change_profile: tok_id (%s)\n", $2);
- entry = new_entry(NULL, $2, AA_CHANGE_PROFILE, NULL);
+ PDEBUG("Matched change_profile: tok_id (%s)\n", $3);
+ entry = new_entry(NULL, $3, AA_CHANGE_PROFILE, NULL);
if (!entry)
yyerror(_("Memory allocation error."));
PDEBUG("change_profile.entry: (%s)\n", entry->name);
$$ = entry;
};
-change_profile: TOK_CHANGE_PROFILE TOK_COLON TOK_ID TOK_COLON TOK_ID TOK_END_OF_RULE
+change_profile: TOK_CHANGE_PROFILE TOK_ARROW TOK_COLON TOK_ID TOK_COLON TOK_ID TOK_END_OF_RULE
{
struct cod_entry *entry;
- PDEBUG("Matched change_profile: tok_id (%s:%s)\n", $3, $5);
- entry = new_entry($3, $5, AA_CHANGE_PROFILE, NULL);
+ PDEBUG("Matched change_profile: tok_id (%s:%s)\n", $4, $6);
+ entry = new_entry($4, $6, AA_CHANGE_PROFILE, NULL);
if (!entry)
yyerror(_("Memory allocation error."));
PDEBUG("change_profile.entry: (%s)\n", entry->name);
@@ -987,13 +1110,58 @@
}
struct cod_entry *do_file_rule(char *namespace, char *id, int mode,
- char *link_id)
+ char *link_id, char *nt)
{
struct cod_entry *entry;
PDEBUG("Matched: tok_id (%s) tok_mode (0x%x)\n", id, mode);
entry = new_entry(namespace, id, mode, link_id);
if (!entry)
yyerror(_("Memory allocation error."));
+ entry->nt_name = nt;
PDEBUG("rule.entry: (%s)\n", entry->name);
return entry;
}
+
+void add_local_entry(struct codomain *cod)
+{
+ /* ugh this has to be called after the hat is attached to its parent */
+ if (cod->local_mode) {
+ struct cod_entry *entry;
+ char *trans = malloc(strlen(cod->parent->name) +
+ strlen(cod->name) + 3);
+ char *name = strdup(cod->name);
+ if (!trans)
+ yyerror(_("Memory allocation error."));
+ sprintf(name, "%s//%s", cod->parent->name, cod->name);
+
+ entry = new_entry(NULL, name, cod->local_mode, NULL);
+ entry->audit = cod->local_audit;
+ entry->nt_name = trans;
+ if (!entry)
+ yyerror(_("Memory allocation error."));
+
+ add_entry_to_policy(cod, entry);
+ }
+}
+
+struct codomain *do_local_profile(struct codomain *cod, char *name, int mode,
+ int audit)
+{
+ PDEBUG("Matched: local profile trans (%s) open rules close\n", $1);
+ if (!cod) {
+ yyerror(_("Memory allocation error."));
+ }
+ cod->name = name;
+ if (force_complain)
+ cod->flags = force_complain_flags;
+ PDEBUG("profile %s: flags='%s%s'\n",
+ name,
+ cod->flags.complain ? "complain, " : "",
+ cod->flags.audit ? "audit" : "");
+
+ cod->local = 1;
+ cod->local_mode = mode;
+ cod->local_audit = audit;
+
+ return cod;
+}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_1.sd new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_1.sd
--- old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_1.sd 2007-10-01 09:34:27.000000000 +0200
+++ new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_1.sd 2008-04-16 07:45:02.000000000 +0200
@@ -3,5 +3,5 @@
#=EXRESULT PASS
#
/usr/bin/foo {
- change_profile /bin/foo,
+ change_profile -> /bin/foo,
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_2.sd new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_2.sd
--- old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_2.sd 2007-10-01 09:34:27.000000000 +0200
+++ new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_2.sd 2008-04-16 07:45:02.000000000 +0200
@@ -3,5 +3,5 @@
#=EXRESULT PASS
#
/usr/bin/foo {
- change_profile /bin/foo//bar,
+ change_profile -> /bin/foo//bar,
}
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_3.sd new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_3.sd
--- old/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_3.sd 2008-04-06 21:53:59.000000000 +0200
+++ new/apparmor-parser-2.3/tst/simple_tests/simple_ok_change_profile_3.sd 2008-04-16 07:45:02.000000000 +0200
@@ -3,5 +3,5 @@
#=EXRESULT PASS
#
/usr/bin/foo {
- change_profile :foo:/bin/foo,
+ change_profile -> :foo:/bin/foo,
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org