[apparmor] [Bug 789409] Re: /proc/[PID]/attr/current overwrite Null pointer dereference

2012-02-22 Thread Launchpad Bug Tracker
** Branch linked: lp:ubuntu/maverick-proposed/linux-ti-omap4

** Branch linked: lp:ubuntu/natty-proposed/linux-ti-omap4

-- 
You received this bug notification because you are a member of AppArmor
Developers, which is subscribed to the bug report.
https://bugs.launchpad.net/bugs/789409

Title:
  /proc/[PID]/attr/current overwrite Null pointer dereference

Status in AppArmor Linux application security framework:
  Fix Released
Status in “linux” package in Ubuntu:
  Fix Released
Status in “linux-ec2” package in Ubuntu:
  Invalid
Status in “linux-fsl-imx51” package in Ubuntu:
  Invalid
Status in “linux-lts-backport-maverick” package in Ubuntu:
  Invalid
Status in “linux-lts-backport-natty” package in Ubuntu:
  Invalid
Status in “linux-lts-backport-oneiric” package in Ubuntu:
  Invalid
Status in “linux-mvl-dove” package in Ubuntu:
  Invalid
Status in “linux-ti-omap4” package in Ubuntu:
  Invalid
Status in “linux” source package in Lucid:
  Invalid
Status in “linux-ec2” source package in Lucid:
  Invalid
Status in “linux-fsl-imx51” source package in Lucid:
  Invalid
Status in “linux-lts-backport-maverick” source package in Lucid:
  Fix Committed
Status in “linux-lts-backport-natty” source package in Lucid:
  Fix Committed
Status in “linux-lts-backport-oneiric” source package in Lucid:
  Fix Committed
Status in “linux-mvl-dove” source package in Lucid:
  Invalid
Status in “linux-ti-omap4” source package in Lucid:
  Invalid
Status in “linux” source package in Natty:
  Fix Released
Status in “linux-ec2” source package in Natty:
  Invalid
Status in “linux-fsl-imx51” source package in Natty:
  Invalid
Status in “linux-lts-backport-maverick” source package in Natty:
  Invalid
Status in “linux-lts-backport-natty” source package in Natty:
  Invalid
Status in “linux-lts-backport-oneiric” source package in Natty:
  Invalid
Status in “linux-mvl-dove” source package in Natty:
  Invalid
Status in “linux-ti-omap4” source package in Natty:
  Fix Committed
Status in “linux” source package in Oneiric:
  Fix Committed
Status in “linux-ec2” source package in Oneiric:
  Invalid
Status in “linux-fsl-imx51” source package in Oneiric:
  Invalid
Status in “linux-lts-backport-maverick” source package in Oneiric:
  Invalid
Status in “linux-lts-backport-natty” source package in Oneiric:
  Invalid
Status in “linux-lts-backport-oneiric” source package in Oneiric:
  Invalid
Status in “linux-mvl-dove” source package in Oneiric:
  Invalid
Status in “linux-ti-omap4” source package in Oneiric:
  Fix Committed
Status in “linux” source package in Precise:
  Fix Released
Status in “linux-ec2” source package in Precise:
  Invalid
Status in “linux-fsl-imx51” source package in Precise:
  Invalid
Status in “linux-lts-backport-maverick” source package in Precise:
  Invalid
Status in “linux-lts-backport-natty” source package in Precise:
  Invalid
Status in “linux-lts-backport-oneiric” source package in Precise:
  Invalid
Status in “linux-mvl-dove” source package in Precise:
  Invalid
Status in “linux-ti-omap4” source package in Precise:
  Invalid
Status in “linux” source package in Hardy:
  Invalid
Status in “linux-ec2” source package in Hardy:
  Invalid
Status in “linux-fsl-imx51” source package in Hardy:
  Invalid
Status in “linux-lts-backport-maverick” source package in Hardy:
  Invalid
Status in “linux-lts-backport-natty” source package in Hardy:
  Invalid
Status in “linux-lts-backport-oneiric” source package in Hardy:
  Invalid
Status in “linux-mvl-dove” source package in Hardy:
  Invalid
Status in “linux-ti-omap4” source package in Hardy:
  Invalid

Bug description:
  kernel/AppArmor local denial of service

  Break-Fix: - a5b2c5b2ad5853591a6cac6134cd0f599a720865

To manage notifications about this bug go to:
https://bugs.launchpad.net/apparmor/+bug/789409/+subscriptions

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 3/3] Add mount rules

2012-02-22 Thread James Troup
John Johansen  writes:

a) What is it with you and Kees and not trimming replies? :-P

b) Most of my comments are not substantive and limited to trivial issues
   as I'm only reading the patch for educational purposes and not really
   qualified to review the code.  If it's not of interest, I'm happy to
   do any read further in silence, just let me know.

> +++ b/parser/mount.c

[...]

> + *   Copyright (c) 2010
> + *   Canonical, Ltd. (All rights reserved)

As Kees said, 2012 - but also s/Canonical, Ltd./Canonical Ltd./

Same for all files. 

> + * -F fork for similtaneous mount

s/similtaneous/simultaneous/

> + * The linux kernel has 32 fs - independent mount flags, that mount command

s/linux/Linux/

> + * is responsible for stripping out and mapping to a 32 bit flags field.
> + * The mount commands mapping is documented below.
> + *
> + * Unfortunately we can not directly use this mapping as we need to be able
> + * represent, whether none, 1 or both options of a flag can be present for
> + *

for ... what?

> + * eg.

s/eg./e.g./

> + *ro, and rw information is stored in a single bit.  But we need 2 bits
> + *of information.
> + *ro - the mount can only be readonly
> + *rw - the mount can only be rw
> + *ro/rw - the mount can be either ro/rw
> + *the forth state of neither ro/rw does not exist, but still we need

s/forth/fourth/ (presumably?)

> + * Note: leading owner option applies owner condition to both sours and dest

s/sours/source/

> + * If a condition is not specified then it is assumed to match all possible
> + * entries for it.  ie. a missing fstype means all fstypes are matced.

s/ie./i.e./, s/matced/matched/

> + * However if a condition is specified then the rule only grants permission
> + * for mounts matching the specified pattern.
> + *
> + * Egs.

Perhaps: 'Examples:' or just straight up 'e.g.'

> + *   to catch mount options, that can't be covered.

s/, that/that/

> + PDEBUG("  extracting fstype ");

Missing \n ?

> + ent = (struct mnt_entry *) calloc(1, sizeof(struct mnt_entry));
> + if (ent) {

Maybe this is simply project style and/or a personal preference, but
wouldn't it be cleaner to do:

  ent = (struct mnt_entry *) calloc(1, sizeof(struct mnt_entry));
if (!ent)
  return ent

Which would allow the rest of the function to be deindented?

> + ent->dev_type = extract_fstype(&sconds);

It may just be me, but my brain automatically expands that to 'seconds'.
It might be nice to use src_conds and dst_conds like you did elsewhere
here too.

> + fprintf(stderr, "error: unknonw mount perm");

s/unknonw/unknown/

> +++ b/parser/mount.h


> +#define AA_MAY_REMOUNT 8 /* dump perm for remount rule */

What does this comment mean?

> +++ b/parser/parser_policy.c

> + PERROR("Profile %s has to many specified 
> profile transitions.\n", cod->name);

s/to/too/

> +++ b/parser/parser_regex.c

> + if (ent->next && size - (p -buffer) > 1) {

s/-buffer/- buffer/

> + /* remount is can't be conditional on device and type */

s/is //

> + pwarn("profile %s mount rules not enforce\n", cod->name);

not enforced?  not enforceable?

> +++ b/parser/parser_variable.c

> + if (!dup_and_chain(entry)) {
>   PERROR("Memory allocaton error while handling 
> set variable %s\n",

It's pre-existing, but: s/allocaton/allocation/

>  static int process_variables_in_entries(struct cod_entry *entry_list)
>  {
>   int ret = TRUE, rc;
>   struct cod_entry *entry;
>  
>   list_for_each(entry_list, entry) {
> - rc = expand_entry_variables(entry);
> + rc = expand_entry_variables(&entry->name, entry,
> + clone_and_chain_cod);
>   if (!rc)
> - ret = FALSE;
> + return FALSE;
> + }
> +
> + return ret;
> +}
>

Couldn't you just 'return TRUE;' here and drop the 'ret' variable altogether?

> +static int process_variables_in_mnt_entries(struct mnt_entry *entry_list)

[...]

>   return ret;

Same here.

> +++ b/parser/parser_yacc.y

> + //  val->next = $1;

?

-- 
James

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 1/3] Generate the features list from the features directory

2012-02-22 Thread Steve Beattie
On Wed, Feb 22, 2012 at 03:04:56PM -0800, John Johansen wrote:
> Newer versions of AppArmor use a features directory instead of a file
> update the parser to use this to determine features and match string
> 
> This is just a first pass at this to get things up quickly.  A much
> more comprehensive rework that can parse and use the full information
> set is needed.
> 
> Signed-off-by: John Johansen 
> ---
>  parser/parser.h|1 +
>  parser/parser_common.c |1 +
>  parser/parser_main.c   |  121 
> +++-
>  3 files changed, 122 insertions(+), 1 deletions(-)
> 
> diff --git a/parser/parser.h b/parser/parser.h
> index 8d3ef6c..7be0f83 100644
> --- a/parser/parser.h
> +++ b/parser/parser.h
> @@ -247,6 +247,7 @@ extern int perms_create;
>  extern int net_af_max_override;
>  extern int kernel_load;
>  extern int kernel_supports_network;
> +extern int kernel_supports_mount;
>  extern int flag_changehat_version;
>  extern int conf_verbose;
>  extern int conf_quiet;
> diff --git a/parser/parser_common.c b/parser/parser_common.c
> index df78a10..572eaad 100644
> --- a/parser/parser_common.c
> +++ b/parser/parser_common.c
> @@ -27,6 +27,7 @@ int perms_create = 0;   /* perms contain 
> create flag */
>  int net_af_max_override = -1;   /* use kernel to determine af_max */
>  int kernel_load = 1;
>  int kernel_supports_network = 1;/* kernel supports network rules */
> +int kernel_supports_mount = 0;   /* kernel supports mount rules 
> */

(minor nit) tabs vs whitespace?

>  int flag_changehat_version = FLAG_CHANGEHAT_1_5;
>  int conf_verbose = 0;
>  int conf_quiet = 0;
> diff --git a/parser/parser_main.c b/parser/parser_main.c
> index 721582d..94ad2b9 100644
> --- a/parser/parser_main.c
> +++ b/parser/parser_main.c
> @@ -30,6 +30,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #define _(s) gettext(s)
>  
>  /* enable the following line to get voluminous debug info */
> @@ -667,17 +668,134 @@ int have_enough_privilege(void)
>   return 0;
>  }
>  
> +static char *handle_features_dir(const char *filename, char **buffer, int 
> size,
> +  char *pos)
> +{
> + DIR *dir = NULL;
> + char *dirent_path = NULL;
> + struct dirent *dirent;
> + struct stat my_stat;
> + int len;
> +
> + PDEBUG("Opened features directory \"%s\"\n", filename);
> + if (!(dir = opendir(filename))) {
> + PDEBUG("opendir failed '%s'", filename);
> + exit(1);
> + }
> +
> + while ((dirent = readdir(dir)) != NULL) {
> + int name_len, remaining;
> + /* skip dotfiles silently. */
> + if (dirent->d_name[0] == '.')
> + continue;
> +
> + if (dirent_path)
> + free(dirent_path);
> + if (asprintf(&dirent_path, "%s/%s", filename, dirent->d_name) < 
> 0)
> + {
> + PERROR(_("Memory allocation error."));
> + exit(1);
> + }
> +
> + name_len = strlen(dirent->d_name);
> + if (!name_len)
> + continue;
> +
> + if (stat(dirent_path, &my_stat)) {
> + PERROR(_("stat failed for '%s'"), dirent_path);
> + exit(1);
> + }
> +
> + remaining = size - (pos - *buffer);
> + len = snprintf(pos, remaining, "%s { ", dirent->d_name);
> + if (len > remaining) {

I think there's an off by one error here, in that if len == remaining,
then the output has been truncated, as the value returned by snprintf()
is the number of characters that would have been written not including
the trailing \0 character. When len == remaining, then it has been
truncated by 1 character.

> + PERROR(_("Feature buffer full."));
> + exit(1);
> + }
> + pos += len;
> +
> + if (S_ISREG(my_stat.st_mode)) {
> + int file;
> + int remaining = size - (pos - *buffer);
> + if (!(file = open(dirent_path, O_RDONLY))) {
> + PDEBUG("Could not open '%s' in '%s'", 
> dirent_path, filename);
> + exit(1);
> + break;
> + }
> + PDEBUG("Opened features \"%s\" in \"%s\"\n", 
> dirent_path, filename);
> + if (my_stat.st_size > remaining) {
> + PERROR(_("Feature buffer full."));
> + exit(1);
> + }
> +
> + do {
> + len = read(file, pos, remaining);
> + if (pos > 0) {

Is this test correct? Given that pos is a pointer to a character
string, it's, uh, likely to not be 0. Did you mean (len > 0)?

> +

Re: [apparmor] [PATCH 1/3] Generate the features list from the features directory

2012-02-22 Thread John Johansen
On 02/22/2012 03:18 PM, Kees Cook wrote:
> On Wed, Feb 22, 2012 at 03:04:56PM -0800, John Johansen wrote:
>> +static char *handle_features_dir(const char *filename, char **buffer, int 
>> size,
>> + char *pos)
>> [...]
>> +flags_string = malloc(1024);
>> +handle_features_dir(FLAGS_FILE, &flags_string, 2048, 
>> flags_string);
> 
> Shouldn't that 1024 be 2048, or vice versa?
> 
yep thanks

>> +if (strstr(flags_string, "network"))
>> +kernel_supports_network = 1;
>> +if (strstr(flags_string, "mount"))
>> +kernel_supports_mount = 1;
> 
> Looks like you were going for a more complex flags_string in the function,
> but then just did a quick check for things here instead?
> 
actually I was just leveraging the already existing flags_string that is used
to generate the flags set for the cache, and this is totally going for the
quick hack approach, as think we need to actually parser these things and
thats a bit much for this iteration.

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 2/3] Extend the information dumped by -D rule-exprs to include permissions

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 03:04:57PM -0800, John Johansen wrote:
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 1/3] Generate the features list from the features directory

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 03:04:56PM -0800, John Johansen wrote:
> +static char *handle_features_dir(const char *filename, char **buffer, int 
> size,
> +  char *pos)
> [...]
> + flags_string = malloc(1024);
> + handle_features_dir(FLAGS_FILE, &flags_string, 2048, 
> flags_string);

Shouldn't that 1024 be 2048, or vice versa?

> + if (strstr(flags_string, "network"))
> + kernel_supports_network = 1;
> + if (strstr(flags_string, "mount"))
> + kernel_supports_mount = 1;

Looks like you were going for a more complex flags_string in the function,
but then just did a quick check for things here instead?

-Kees

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 2/3] Extend the information dumped by -D rule-exprs to include permissions

2012-02-22 Thread John Johansen
Signed-off-by: John Johansen 
---
 parser/libapparmor_re/aare_rules.cc |7 ++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/parser/libapparmor_re/aare_rules.cc 
b/parser/libapparmor_re/aare_rules.cc
index e78967a..d216a48 100644
--- a/parser/libapparmor_re/aare_rules.cc
+++ b/parser/libapparmor_re/aare_rules.cc
@@ -98,6 +98,7 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int 
deny,
 {
Node *tree = NULL, *accept;
int exact_match;
+   uint32_t allow = perms;
 
assert(perms != 0);
 
@@ -220,7 +221,11 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, 
int deny,
}
cerr << "  ->  ";
tree->dump(cerr);
-   cerr << "\n\n";
+   if (deny)
+   cerr << " deny";
+   cerr << " (" << hex << allow <<"/" << audit << dec << ")";
+   accept->dump(cerr);
+   cerr << "\n\n";
}
 
if (rules->root)
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [Patch 0/3] Remaining userspace patches needed for mount rules

2012-02-22 Thread John Johansen
These are the remaining patches in the queue for adding mount rules.
The feature direcory support is real rudimentary but sufficient for this
iteration.


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 1/3] Generate the features list from the features directory

2012-02-22 Thread John Johansen
Newer versions of AppArmor use a features directory instead of a file
update the parser to use this to determine features and match string

This is just a first pass at this to get things up quickly.  A much
more comprehensive rework that can parse and use the full information
set is needed.

Signed-off-by: John Johansen 
---
 parser/parser.h|1 +
 parser/parser_common.c |1 +
 parser/parser_main.c   |  121 +++-
 3 files changed, 122 insertions(+), 1 deletions(-)

diff --git a/parser/parser.h b/parser/parser.h
index 8d3ef6c..7be0f83 100644
--- a/parser/parser.h
+++ b/parser/parser.h
@@ -247,6 +247,7 @@ extern int perms_create;
 extern int net_af_max_override;
 extern int kernel_load;
 extern int kernel_supports_network;
+extern int kernel_supports_mount;
 extern int flag_changehat_version;
 extern int conf_verbose;
 extern int conf_quiet;
diff --git a/parser/parser_common.c b/parser/parser_common.c
index df78a10..572eaad 100644
--- a/parser/parser_common.c
+++ b/parser/parser_common.c
@@ -27,6 +27,7 @@ int perms_create = 0;   /* perms contain 
create flag */
 int net_af_max_override = -1;   /* use kernel to determine af_max */
 int kernel_load = 1;
 int kernel_supports_network = 1;/* kernel supports network rules */
+int kernel_supports_mount = 0; /* kernel supports mount rules */
 int flag_changehat_version = FLAG_CHANGEHAT_1_5;
 int conf_verbose = 0;
 int conf_quiet = 0;
diff --git a/parser/parser_main.c b/parser/parser_main.c
index 721582d..94ad2b9 100644
--- a/parser/parser_main.c
+++ b/parser/parser_main.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #define _(s) gettext(s)
 
 /* enable the following line to get voluminous debug info */
@@ -667,17 +668,134 @@ int have_enough_privilege(void)
return 0;
 }
 
+static char *handle_features_dir(const char *filename, char **buffer, int size,
+char *pos)
+{
+   DIR *dir = NULL;
+   char *dirent_path = NULL;
+   struct dirent *dirent;
+   struct stat my_stat;
+   int len;
+
+   PDEBUG("Opened features directory \"%s\"\n", filename);
+   if (!(dir = opendir(filename))) {
+   PDEBUG("opendir failed '%s'", filename);
+   exit(1);
+   }
+
+   while ((dirent = readdir(dir)) != NULL) {
+   int name_len, remaining;
+   /* skip dotfiles silently. */
+   if (dirent->d_name[0] == '.')
+   continue;
+
+   if (dirent_path)
+   free(dirent_path);
+   if (asprintf(&dirent_path, "%s/%s", filename, dirent->d_name) < 
0)
+   {
+   PERROR(_("Memory allocation error."));
+   exit(1);
+   }
+
+   name_len = strlen(dirent->d_name);
+   if (!name_len)
+   continue;
+
+   if (stat(dirent_path, &my_stat)) {
+   PERROR(_("stat failed for '%s'"), dirent_path);
+   exit(1);
+   }
+
+   remaining = size - (pos - *buffer);
+   len = snprintf(pos, remaining, "%s { ", dirent->d_name);
+   if (len > remaining) {
+   PERROR(_("Feature buffer full."));
+   exit(1);
+   }
+   pos += len;
+
+   if (S_ISREG(my_stat.st_mode)) {
+   int file;
+   int remaining = size - (pos - *buffer);
+   if (!(file = open(dirent_path, O_RDONLY))) {
+   PDEBUG("Could not open '%s' in '%s'", 
dirent_path, filename);
+   exit(1);
+   break;
+   }
+   PDEBUG("Opened features \"%s\" in \"%s\"\n", 
dirent_path, filename);
+   if (my_stat.st_size > remaining) {
+   PERROR(_("Feature buffer full."));
+   exit(1);
+   }
+
+   do {
+   len = read(file, pos, remaining);
+   if (pos > 0) {
+   remaining -= len;
+   pos += len;
+   *pos = 0;
+   }
+   } while (len > 0);
+   if (len < 0) {
+   PDEBUG("Error reading feature file '%s'\n",
+  dirent_path);
+   exit(1);
+   }
+   close(file);
+
+   } else if (S_ISDIR(my_stat.st_mode)) {
+   pos = handle_features_dir(dirent_path, buffer, size,
+ pos);
+   

Re: [apparmor] [PATCH 02/20] AppArmor: add initial "features" directory to securityfs

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 01:14:09PM -0800, John Johansen wrote:
> On 02/22/2012 01:10 PM, Kees Cook wrote:
> > Hi John,
> > 
> > On Wed, Feb 22, 2012 at 09:22:45AM -0800, John Johansen wrote:
> >> +static struct aa_fs_entry aa_fs_entry_features[] = {
> >> +  AA_FS_DIR("domain", aa_fs_entry_domain),
> >> +  AA_FS_FILE_BOOLEAN("namespaces",1),
> > 
> > If "namespaces" is going to change into a directory, perhaps just leave
> > it out for now?
> > 
> Hrmm yes we could do that, it would be a little cleaner.
> 
> Originally I wasn't going to make it a directory but it felt cleaner to
> group all the things that affect namespaces in one way or another together.
> 
> So the clone flags patch (not posted yet), pivot_root, chroot, apparmor
> namespaces, etc.

Well, since the patch that changes namespaces into a directory will be
sent up at the same time, it's probably fine to just leave it as-is.

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 02/20] AppArmor: add initial "features" directory to securityfs

2012-02-22 Thread John Johansen
On 02/22/2012 01:10 PM, Kees Cook wrote:
> Hi John,
> 
> On Wed, Feb 22, 2012 at 09:22:45AM -0800, John Johansen wrote:
>> +static struct aa_fs_entry aa_fs_entry_features[] = {
>> +AA_FS_DIR("domain", aa_fs_entry_domain),
>> +AA_FS_FILE_BOOLEAN("namespaces",1),
> 
> If "namespaces" is going to change into a directory, perhaps just leave
> it out for now?
> 
Hrmm yes we could do that, it would be a little cleaner.

Originally I wasn't going to make it a directory but it felt cleaner to
group all the things that affect namespaces in one way or another together.

So the clone flags patch (not posted yet), pivot_root, chroot, apparmor
namespaces, etc.


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 02/20] AppArmor: add initial "features" directory to securityfs

2012-02-22 Thread Kees Cook
Hi John,

On Wed, Feb 22, 2012 at 09:22:45AM -0800, John Johansen wrote:
> +static struct aa_fs_entry aa_fs_entry_features[] = {
> + AA_FS_DIR("domain", aa_fs_entry_domain),
> + AA_FS_FILE_BOOLEAN("namespaces",1),

If "namespaces" is going to change into a directory, perhaps just leave
it out for now?

-Kees

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 13/16] AppArmor: Add profile introspection file to interface

2012-02-22 Thread John Johansen
On 02/22/2012 01:01 PM, Kees Cook wrote:
> On Wed, Feb 22, 2012 at 09:10:38AM -0800, John Johansen wrote:
>> Add the dynamic profiles file to the interace, to allow load policy
>> introspection.
>>
>> Signed-off-by: John Johansen 
> 
> I thought we were going to hold off on this until we had the "real"
> profile introspection tree, but I'm not very opposed to it, since it
> would be extremely nice to have this in upstream.
> 
Right sorry covered in the 0/16 email that got dropped off the first
submission, hence the resend.

We are holding off on this, but it is still needed for precise, and any
other distro that wants to carry the out of tree patch.  So its been
refreshed to work with your fs patches, with anything you covered being
dropped.

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 03/16] AppArmor: Fix underflow in xindex calculation

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 12:44:54PM -0800, John Johansen wrote:
> On 02/22/2012 12:27 PM, Kees Cook wrote:
> > On Wed, Feb 22, 2012 at 09:10:28AM -0800, John Johansen wrote:
> >> If the xindex value stored in the accept tables is 0, the extraction of
> >> that value will result in an underflow (0 - 4).
> >>
> >> In properly compiled policy this should not happen for file rules but
> >> it may be possible for other rule types in the future.
> >>
> >> To exploit this underflow a user would have to be able to load a corrupt
> >> policy, which requires CAP_MAC_ADMIN, overwrite system policy in kernel
> >> memory or know of a compiler error resulting in the flaw being present
> >> for loaded policy (no such flaw is known at this time).
> >>
> >> Signed-off-by: John Johansen 
> >> ---
> >>  security/apparmor/include/file.h |2 +-
> >>  1 files changed, 1 insertions(+), 1 deletions(-)
> >>
> >> diff --git a/security/apparmor/include/file.h 
> >> b/security/apparmor/include/file.h
> >> index ab8c6d8..f98fd47 100644
> >> --- a/security/apparmor/include/file.h
> >> +++ b/security/apparmor/include/file.h
> >> @@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
> >>index |= AA_X_NAME;
> >>} else if (old_index == 3) {
> >>index |= AA_X_NAME | AA_X_CHILD;
> >> -  } else {
> >> +  } else if (old_index) {
> >>index |= AA_X_TABLE;
> >>index |= old_index - 4;
> >>}
> > 
> > What about the cases where old_index < 4, but != 0?
> > 
> look above cases 1, 2, and 3 are covered by the if blocks
> eg.
> 
> } else if (old_index == 3) {
>   index |= AA_X_NAME | AA_X_CHILD;

Ah, right. Okay. Missed that bit. Thanks!

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 16/16] AppArmor: Add mediation of chroot

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:41AM -0800, John Johansen wrote:
> Add support for chroot rules, which allow a profile to specify where a
> chroot can be made.
> 
>   chroot /tmp/example,
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 15/16] AppArmor: Add mount information to apparmorfs

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:40AM -0800, John Johansen wrote:
> Update the apparmorfs introspection interface to reflect that mount rules
> are available.  As part of this change the namespace entry from a binary
> file to a directory so it can store interface information for operations
> that affect the namespace like pivot_root.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 12/16] AppArmor: basic networking rules

2012-02-22 Thread John Johansen
On 02/22/2012 12:59 PM, Kees Cook wrote:
> On Wed, Feb 22, 2012 at 09:10:37AM -0800, John Johansen wrote:
>> Base support for network mediation.
>>
>> Signed-off-by: John Johansen 
>> [...]
>> diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
>> index 86103ce..96cf725 100644
>> --- a/security/apparmor/Makefile
>> +++ b/security/apparmor/Makefile
>> [...]
>> @@ -62,3 +64,5 @@ $(obj)/capability_names.h : 
>> $(srctree)/include/linux/capability.h \
>>  $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
>>$(src)/Makefile
>>  $(call cmd,make-rlim)
>> +$(obj)/af_names.h : $(srctree)/include/linux/socket.h
>> +$(call cmd,make-af)
> 
> Please have this depend on $(src)/Makefile (like the others) so that when
> the Makefile rules change, a rebuild of the .h file is triggered. Also,
> please include comments at the generation to show what the sed mess
> produces (like the others have).
>
heh yeah, /me just did a quick merge on this patch and resolved conflicts.  I 
should
have spent a little time updating it.

>> diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
>> index 38d6262..4267401 100644
>> --- a/security/apparmor/apparmorfs.c
>> +++ b/security/apparmor/apparmorfs.c
>> @@ -198,9 +198,15 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
>>  { }
>>  };
>>  
>> +static struct aa_fs_entry aa_fs_entry_network[] = {
>> +AA_FS_FILE_BOOLEAN("af_masking",1),
> 
> You just want this to be a boolean, not a list?
> 
Hrmm we could do that, I really didn't put a lot of thought into it as this is
the older patch set being moved forward, instead of the newer one.

But since we are going to need compatibility it is probably best to make this
a directory.

>> diff --git a/security/apparmor/include/net.h 
>> b/security/apparmor/include/net.h
>> new file mode 100644
>> index 000..3c7d599
>> --- /dev/null
>> +++ b/security/apparmor/include/net.h
>> @@ -0,0 +1,40 @@
>> +/*
>> + * AppArmor security module
>> + *
>> + * This file contains AppArmor network mediation definitions.
>> + *
>> + * Copyright (C) 1998-2008 Novell/SUSE
>> + * Copyright 2009-2010 Canonical Ltd.
> 
> Should update this to 2012.
> 
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation, version 2 of the
>> + * License.
>> + */
>> +
>> +#ifndef __AA_NET_H
>> +#define __AA_NET_H
>> +
>> +#include 
>> +
>> +/* struct aa_net - network confinement data
>> + * @allowed: basic network families permissions
>> + * @audit_network: which network permissions to force audit
>> + * @quiet_network: which network permissions to quiet rejects
>> + */
>> +struct aa_net {
>> +u16 allow[AF_MAX];
>> +u16 audit[AF_MAX];
>> +u16 quiet[AF_MAX];
>> +};
>> +
>> +extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
>> +   int type, int protocol, struct sock *sk);
>> +extern int aa_revalidate_sk(int op, struct sock *sk);
>> +
>> +static inline void aa_free_net_rules(struct aa_net *new)
>> +{
>> +/* NOP */
>> +}
>> +
>> +#endif /* __AA_NET_H */
>> diff --git a/security/apparmor/include/policy.h 
>> b/security/apparmor/include/policy.h
>> index 9e18e96..3f582a7 100644
>> --- a/security/apparmor/include/policy.h
>> +++ b/security/apparmor/include/policy.h
>> @@ -27,6 +27,7 @@
>>  #include "capability.h"
>>  #include "domain.h"
>>  #include "file.h"
>> +#include "net.h"
>>  #include "resource.h"
>>  
>>  extern const char *profile_mode_names[];
>> @@ -157,6 +158,7 @@ struct aa_policydb {
>>   * @policy: general match rules governing policy
>>   * @file: The set of rules governing basic file access and domain 
>> transitions
>>   * @caps: capabilities for the profile
>> + * @net: network controls for the profile
>>   * @rlimits: rlimits for the profile
>>   *
>>   * The AppArmor profile contains the basic confinement data.  Each profile
>> @@ -194,6 +196,7 @@ struct aa_profile {
>>  struct aa_policydb policy;
>>  struct aa_file_rules file;
>>  struct aa_caps caps;
>> +struct aa_net net;
>>  struct aa_rlimit rlimits;
>>  };
>>  
>> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
>> index 3783202..7459547 100644
>> --- a/security/apparmor/lsm.c
>> +++ b/security/apparmor/lsm.c
>> @@ -32,6 +32,7 @@
>>  #include "include/context.h"
>>  #include "include/file.h"
>>  #include "include/ipc.h"
>> +#include "include/net.h"
>>  #include "include/path.h"
>>  #include "include/policy.h"
>>  #include "include/procattr.h"
>> @@ -621,6 +622,104 @@ static int apparmor_task_setrlimit(struct task_struct 
>> *task,
>>  return error;
>>  }
>>  
>> +static int apparmor_socket_create(int family, int type, int protocol, int 
>> kern)
>> +{
>> +struct aa_profile *profile;
>> +int error = 0;
>> +
>> +if (kern)
>> +return 0;
>> +
>> +profile = __aa_current

Re: [apparmor] [PATCH 14/16] AppArmor: Add the ability to mediate mount

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:39AM -0800, John Johansen wrote:
> Add the ability for apparmor to do mediation of mount operations.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 13/16] AppArmor: Add profile introspection file to interface

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:38AM -0800, John Johansen wrote:
> Add the dynamic profiles file to the interace, to allow load policy
> introspection.
> 
> Signed-off-by: John Johansen 

I thought we were going to hold off on this until we had the "real"
profile introspection tree, but I'm not very opposed to it, since it
would be extremely nice to have this in upstream.

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 12/16] AppArmor: basic networking rules

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:37AM -0800, John Johansen wrote:
> Base support for network mediation.
> 
> Signed-off-by: John Johansen 
> [...]
> diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
> index 86103ce..96cf725 100644
> --- a/security/apparmor/Makefile
> +++ b/security/apparmor/Makefile
> [...]
> @@ -62,3 +64,5 @@ $(obj)/capability_names.h : 
> $(srctree)/include/linux/capability.h \
>  $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
> $(src)/Makefile
>   $(call cmd,make-rlim)
> +$(obj)/af_names.h : $(srctree)/include/linux/socket.h
> + $(call cmd,make-af)

Please have this depend on $(src)/Makefile (like the others) so that when
the Makefile rules change, a rebuild of the .h file is triggered. Also,
please include comments at the generation to show what the sed mess
produces (like the others have).

> diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
> index 38d6262..4267401 100644
> --- a/security/apparmor/apparmorfs.c
> +++ b/security/apparmor/apparmorfs.c
> @@ -198,9 +198,15 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
>   { }
>  };
>  
> +static struct aa_fs_entry aa_fs_entry_network[] = {
> + AA_FS_FILE_BOOLEAN("af_masking",1),

You just want this to be a boolean, not a list?

> diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
> new file mode 100644
> index 000..3c7d599
> --- /dev/null
> +++ b/security/apparmor/include/net.h
> @@ -0,0 +1,40 @@
> +/*
> + * AppArmor security module
> + *
> + * This file contains AppArmor network mediation definitions.
> + *
> + * Copyright (C) 1998-2008 Novell/SUSE
> + * Copyright 2009-2010 Canonical Ltd.

Should update this to 2012.

> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2 of the
> + * License.
> + */
> +
> +#ifndef __AA_NET_H
> +#define __AA_NET_H
> +
> +#include 
> +
> +/* struct aa_net - network confinement data
> + * @allowed: basic network families permissions
> + * @audit_network: which network permissions to force audit
> + * @quiet_network: which network permissions to quiet rejects
> + */
> +struct aa_net {
> + u16 allow[AF_MAX];
> + u16 audit[AF_MAX];
> + u16 quiet[AF_MAX];
> +};
> +
> +extern int aa_net_perm(int op, struct aa_profile *profile, u16 family,
> +int type, int protocol, struct sock *sk);
> +extern int aa_revalidate_sk(int op, struct sock *sk);
> +
> +static inline void aa_free_net_rules(struct aa_net *new)
> +{
> + /* NOP */
> +}
> +
> +#endif /* __AA_NET_H */
> diff --git a/security/apparmor/include/policy.h 
> b/security/apparmor/include/policy.h
> index 9e18e96..3f582a7 100644
> --- a/security/apparmor/include/policy.h
> +++ b/security/apparmor/include/policy.h
> @@ -27,6 +27,7 @@
>  #include "capability.h"
>  #include "domain.h"
>  #include "file.h"
> +#include "net.h"
>  #include "resource.h"
>  
>  extern const char *profile_mode_names[];
> @@ -157,6 +158,7 @@ struct aa_policydb {
>   * @policy: general match rules governing policy
>   * @file: The set of rules governing basic file access and domain transitions
>   * @caps: capabilities for the profile
> + * @net: network controls for the profile
>   * @rlimits: rlimits for the profile
>   *
>   * The AppArmor profile contains the basic confinement data.  Each profile
> @@ -194,6 +196,7 @@ struct aa_profile {
>   struct aa_policydb policy;
>   struct aa_file_rules file;
>   struct aa_caps caps;
> + struct aa_net net;
>   struct aa_rlimit rlimits;
>  };
>  
> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
> index 3783202..7459547 100644
> --- a/security/apparmor/lsm.c
> +++ b/security/apparmor/lsm.c
> @@ -32,6 +32,7 @@
>  #include "include/context.h"
>  #include "include/file.h"
>  #include "include/ipc.h"
> +#include "include/net.h"
>  #include "include/path.h"
>  #include "include/policy.h"
>  #include "include/procattr.h"
> @@ -621,6 +622,104 @@ static int apparmor_task_setrlimit(struct task_struct 
> *task,
>   return error;
>  }
>  
> +static int apparmor_socket_create(int family, int type, int protocol, int 
> kern)
> +{
> + struct aa_profile *profile;
> + int error = 0;
> +
> + if (kern)
> + return 0;
> +
> + profile = __aa_current_profile();
> + if (!unconfined(profile))
> + error = aa_net_perm(OP_CREATE, profile, family, type, protocol,
> + NULL);
> + return error;
> +}
> +
> +static int apparmor_socket_bind(struct socket *sock,
> + struct sockaddr *address, int addrlen)
> +{
> + struct sock *sk = sock->sk;
> +
> + return aa_revalidate_sk(OP_BIND, sk);
> +}
> +
> +static int apparmor_socket_connect(struct socket *sock,
> +struct sockaddr *addres

Re: [apparmor] [PATCH 03/16] AppArmor: Fix underflow in xindex calculation

2012-02-22 Thread John Johansen
On 02/22/2012 12:27 PM, Kees Cook wrote:
> On Wed, Feb 22, 2012 at 09:10:28AM -0800, John Johansen wrote:
>> If the xindex value stored in the accept tables is 0, the extraction of
>> that value will result in an underflow (0 - 4).
>>
>> In properly compiled policy this should not happen for file rules but
>> it may be possible for other rule types in the future.
>>
>> To exploit this underflow a user would have to be able to load a corrupt
>> policy, which requires CAP_MAC_ADMIN, overwrite system policy in kernel
>> memory or know of a compiler error resulting in the flaw being present
>> for loaded policy (no such flaw is known at this time).
>>
>> Signed-off-by: John Johansen 
>> ---
>>  security/apparmor/include/file.h |2 +-
>>  1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/security/apparmor/include/file.h 
>> b/security/apparmor/include/file.h
>> index ab8c6d8..f98fd47 100644
>> --- a/security/apparmor/include/file.h
>> +++ b/security/apparmor/include/file.h
>> @@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
>>  index |= AA_X_NAME;
>>  } else if (old_index == 3) {
>>  index |= AA_X_NAME | AA_X_CHILD;
>> -} else {
>> +} else if (old_index) {
>>  index |= AA_X_TABLE;
>>  index |= old_index - 4;
>>  }
> 
> What about the cases where old_index < 4, but != 0?
> 
look above cases 1, 2, and 3 are covered by the if blocks
eg.

} else if (old_index == 3) {
index |= AA_X_NAME | AA_X_CHILD;

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 11/16] AppArmor: Add ability to load extended policy

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:36AM -0800, John Johansen wrote:
> Add the base support for the new policy extensions. This does not bring
> any additional functionality, or change current semantics.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 10/16] AppArmor: Make chroot relative the default path lookup type

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:35AM -0800, John Johansen wrote:
> Profiles that want name lookup past the chroot to the namespace root
> must be marked as such, all other profiles should be chroot relative.
> 
> Currently the autogenerated null (learning), and unconfined  profiles are
> not marked as such. Make sure they are properly flagged. This should not
> affect behavior except for auto-generated profiles when a chroot is entered.
> Profiles loaded from userspace will not be affected as they provide their
> own value for the flag.
> 
> This change does not affect mediation as it only changes the path reported by
> the unconfined (none mediating), an null learning profiles.
> 
> Also ensure that if a profile is ever loaded with out path flags set, that
> it defaults to being chroot relative.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 09/16] AppArmor: Move path failure information into aa_get_name and rename

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:34AM -0800, John Johansen wrote:
> Move the path name lookup failure messages into the main path name lookup
> routine, as the information is useful in more than just aa_path_perm.
> 
> Also rename aa_get_name to aa_path_name as it is not getting a reference
> counted object with a corresponding put fn.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 08/16] AppArmor: Update dfa matching routines.

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:33AM -0800, John Johansen wrote:
> Update aa_dfa_match so that it doesn't result in an input string being
> walked twice (once to get its length and another time to match)
> 
> Add a single step functions
>   aa_dfa_next
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 07/16] AppArmor: Minor cleanup of d_namespace_path to consolidate error handling

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:32AM -0800, John Johansen wrote:
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 06/16] AppArmor: Retrieve the dentry_path for error reporting when path lookup fails

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:31AM -0800, John Johansen wrote:
> When __d_path and d_absolute_path fail due to the name being outside of
> the current namespace no name is reported.  Use dentry_path to provide
> some hint as to which file was being accessed.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 05/16] AppArmor: Fix the error case for chroot relative path name lookup

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:30AM -0800, John Johansen wrote:
> When a chroot relative pathname lookup fails it is falling through to
> do a d_absolute_path lookup.  This is incorrect as d_absolute_path should
> only be used to lookup names for namespace absolute paths.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 04/16] AppArmor: fix mapping of META_READ to audit and quiet flags

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:29AM -0800, John Johansen wrote:
> The mapping of AA_MAY_META_READ for the allow mask was also being mapped
> to the audit and quiet masks. This would result in some operations being
> audited when the should not.
> 
> This flaw was hidden by the previous audit bug which would drop some
> messages that where supposed to be audited.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 03/16] AppArmor: Fix underflow in xindex calculation

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:28AM -0800, John Johansen wrote:
> If the xindex value stored in the accept tables is 0, the extraction of
> that value will result in an underflow (0 - 4).
> 
> In properly compiled policy this should not happen for file rules but
> it may be possible for other rule types in the future.
> 
> To exploit this underflow a user would have to be able to load a corrupt
> policy, which requires CAP_MAC_ADMIN, overwrite system policy in kernel
> memory or know of a compiler error resulting in the flaw being present
> for loaded policy (no such flaw is known at this time).
> 
> Signed-off-by: John Johansen 
> ---
>  security/apparmor/include/file.h |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/security/apparmor/include/file.h 
> b/security/apparmor/include/file.h
> index ab8c6d8..f98fd47 100644
> --- a/security/apparmor/include/file.h
> +++ b/security/apparmor/include/file.h
> @@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
>   index |= AA_X_NAME;
>   } else if (old_index == 3) {
>   index |= AA_X_NAME | AA_X_CHILD;
> - } else {
> + } else if (old_index) {
>   index |= AA_X_TABLE;
>   index |= old_index - 4;
>   }

What about the cases where old_index < 4, but != 0?

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 02/16] AppArmor: Fix dropping of allowed operations that are force audited

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:27AM -0800, John Johansen wrote:
> The audit permission flag, that specifies an audit message should be
> provided when an operation is allowed, was being ignored in some cases.
> 
> This is because the auto audit mode (which determines the audit mode from
> system flags) was incorrectly assigned the same value as audit mode. The
> shared value would result in messages that should be audited going through
> a second evaluation as to whether they should be audited based on the
> auto audit, resulting in some messages being dropped.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


Re: [apparmor] [PATCH 01/16] AppArmor: Add mising end of structure test to caps unpacking

2012-02-22 Thread Kees Cook
On Wed, Feb 22, 2012 at 09:10:26AM -0800, John Johansen wrote:
> The unpacking of struct capsx is missing a check for the end of the
> caps structure.  This can lead to unpack failures depending on what else
> is packed into the policy file being unpacked.
> 
> Signed-off-by: John Johansen 

Signed-off-by: Kees Cook 

-- 
Kees Cook

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 09/20] AppArmor: Fix the error case for chroot relative path name lookup

2012-02-22 Thread John Johansen
When a chroot relative pathname lookup fails it is falling through to
do a d_absolute_path lookup.  This is incorrect as d_absolute_path should
only be used to lookup names for namespace absolute paths.

Signed-off-by: John Johansen 
---
 security/apparmor/path.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index b566eba..70b09bb 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -92,9 +92,8 @@ static int d_namespace_path(struct path *path, char *buf, int 
buflen,
}
path_put(&root);
connected = 0;
-   }
-
-   res = d_absolute_path(path, buf, buflen);
+   } else
+   res = d_absolute_path(path, buf, buflen);
 
*name = res;
/* handle error conditions - and still allow a partial path to
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 19/20] AppArmor: Add mount information to apparmorfs

2012-02-22 Thread John Johansen
Update the apparmorfs introspection interface to reflect that mount rules
are available.  As part of this change the namespace entry from a binary
file to a directory so it can store interface information for operations
that affect the namespace like pivot_root.

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |   13 -
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0cbbfab..d30aa11 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -429,11 +429,22 @@ static struct aa_fs_entry aa_fs_entry_network[] = {
{ }
 };
 
+static struct aa_fs_entry aa_fs_entry_mount[] = {
+   AA_FS_FILE_STRING("mask", "mount umount"),
+   { }
+};
+
+static struct aa_fs_entry aa_fs_entry_namespaces[] = {
+   AA_FS_FILE_BOOLEAN("profile",   1),
+   AA_FS_FILE_BOOLEAN("pivot_root",1),
+};
+
 static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file",   aa_fs_entry_file),
+   AA_FS_DIR("mount",  aa_fs_entry_mount),
AA_FS_DIR("network",aa_fs_entry_network),
-   AA_FS_FILE_BOOLEAN("namespaces",1),
+   AA_FS_DIR("namespaces", aa_fs_entry_namespaces),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
{ }
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 20/20] AppArmor: Add mediation of chroot

2012-02-22 Thread John Johansen
Add support for chroot rules, which allow a profile to specify where a
chroot can be made.

  chroot /tmp/example,

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c   |1 +
 security/apparmor/audit.c|1 +
 security/apparmor/include/apparmor.h |3 +-
 security/apparmor/include/audit.h|1 +
 security/apparmor/include/mount.h|4 +++
 security/apparmor/lsm.c  |   13 ++
 security/apparmor/mount.c|   42 ++
 7 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index d30aa11..32c1394 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -437,6 +437,7 @@ static struct aa_fs_entry aa_fs_entry_mount[] = {
 static struct aa_fs_entry aa_fs_entry_namespaces[] = {
AA_FS_FILE_BOOLEAN("profile",   1),
AA_FS_FILE_BOOLEAN("pivot_root",1),
+   AA_FS_FILE_BOOLEAN("chroot",1),
 };
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 64e9442..4c80d4f 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -47,6 +47,7 @@ const char *op_table[] = {
"pivotroot",
"mount",
"umount",
+   "chroot",
 
"create",
"post_create",
diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index d615726..5f4b32e 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -30,8 +30,9 @@
 #define AA_CLASS_RLIMITS   5
 #define AA_CLASS_DOMAIN6
 #define AA_CLASS_MOUNT 7
+#define AA_CLASS_CHROOT8
 
-#define AA_CLASS_LAST  AA_CLASS_MOUNT
+#define AA_CLASS_LAST  AA_CLASS_CHROOT
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 0e8689d..693f37f 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -76,6 +76,7 @@ enum aa_ops {
OP_PIVOTROOT,
OP_MOUNT,
OP_UMOUNT,
+   OP_CHROOT,
 
OP_CREATE,
OP_POST_CREATE,
diff --git a/security/apparmor/include/mount.h 
b/security/apparmor/include/mount.h
index 6f936bc..a1c5026 100644
--- a/security/apparmor/include/mount.h
+++ b/security/apparmor/include/mount.h
@@ -27,6 +27,8 @@
 
 #define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
 
+/* chroot permissions */
+#define AA_MAY_CHROOT  0x01
 
 int aa_remount(struct aa_profile *profile, struct path *path,
   unsigned long flags, void *data);
@@ -50,4 +52,6 @@ int aa_umount(struct aa_profile *profile, struct vfsmount 
*mnt, int flags);
 int aa_pivotroot(struct aa_profile *profile, struct path *old_path,
  struct path *new_path);
 
+int aa_chroot(struct aa_profile *profile, struct path *path);
+
 #endif /* __AA_MOUNT_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3aec025..507ba44 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -544,6 +544,18 @@ static int apparmor_sb_mount(char *dev_name, struct path 
*path, char *type,
return error;
 }
 
+static int apparmor_path_chroot(struct path *path)
+{
+   struct aa_profile *profile;
+   int error = 0;
+
+   profile = __aa_current_profile();
+   if (!unconfined(profile))
+   error = aa_chroot(profile, path);
+
+   return error;
+}
+
 static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
 {
struct aa_profile *profile;
@@ -786,6 +798,7 @@ static struct security_operations apparmor_ops = {
.sb_mount = apparmor_sb_mount,
.sb_umount =apparmor_sb_umount,
.sb_pivotroot = apparmor_sb_pivotroot,
+   .path_chroot =  apparmor_path_chroot,
 
.path_link =apparmor_path_link,
.path_unlink =  apparmor_path_unlink,
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 1572bf6..86f6102 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -587,3 +587,45 @@ audit:
 
return error;
 }
+
+int aa_chroot(struct aa_profile *profile, struct path *path)
+{
+   struct file_perms perms = { };
+   struct aa_profile *target = NULL;
+   char *buffer = NULL;
+   const char *name, *info = NULL;
+   int error;
+
+   error = aa_path_name(path, profile->path_flags, &buffer, &name, &info);
+   if (error)
+   goto audit;
+
+   if (profile->policy.dfa) {
+   unsigned int state;
+   state = aa_dfa_match(profile->policy.dfa,
+profile->policy.start[AA_CLASS_CHROOT],
+   

[apparmor] [PATCH 18/20] AppArmor: Add the ability to mediate mount

2012-02-22 Thread John Johansen
Add the ability for apparmor to do mediation of mount operations.

Signed-off-by: John Johansen 
---
 include/linux/lsm_audit.h|7 +
 security/apparmor/Makefile   |2 +-
 security/apparmor/audit.c|4 +
 security/apparmor/domain.c   |2 +-
 security/apparmor/include/apparmor.h |3 +-
 security/apparmor/include/audit.h|4 +
 security/apparmor/include/domain.h   |2 +
 security/apparmor/include/mount.h|   53 +++
 security/apparmor/lsm.c  |   59 
 security/apparmor/mount.c|  589 ++
 10 files changed, 722 insertions(+), 3 deletions(-)
 create mode 100644 security/apparmor/include/mount.h
 create mode 100644 security/apparmor/mount.c

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index c63979a..39a00cc 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -119,6 +119,13 @@ struct common_audit_data {
unsigned long max;
} rlim;
struct {
+   const char *src_name;
+   const char *type;
+   const char *trans;
+   const char *data;
+   unsigned long flags;
+   } mnt;
+   struct {
const char *target;
u32 request;
u32 denied;
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 96cf725..0352e1a 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
   path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-  resource.o sid.o file.o net.o
+  resource.o sid.o file.o net.o mount.o
 
 clean-files := capability_names.h rlim_names.h af_names.h
 
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index f419e12..64e9442 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -44,6 +44,10 @@ const char *op_table[] = {
"file_mmap",
"file_mprotect",
 
+   "pivotroot",
+   "mount",
+   "umount",
+
"create",
"post_create",
"bind",
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 7c69599..6fc18d1 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -242,7 +242,7 @@ static const char *next_name(int xtype, const char *name)
  *
  * Returns: refcounted profile, or NULL on failure (MAYBE NULL)
  */
-static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 
xindex)
+struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
 {
struct aa_profile *new_profile = NULL;
struct aa_namespace *ns = profile->ns;
diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 9cef358..d615726 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -29,8 +29,9 @@
 #define AA_CLASS_NET   4
 #define AA_CLASS_RLIMITS   5
 #define AA_CLASS_DOMAIN6
+#define AA_CLASS_MOUNT 7
 
-#define AA_CLASS_LAST  AA_CLASS_DOMAIN
+#define AA_CLASS_LAST  AA_CLASS_MOUNT
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 9317cd8..0e8689d 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -73,6 +73,10 @@ enum aa_ops {
OP_FMMAP,
OP_FMPROT,
 
+   OP_PIVOTROOT,
+   OP_MOUNT,
+   OP_UMOUNT,
+
OP_CREATE,
OP_POST_CREATE,
OP_BIND,
diff --git a/security/apparmor/include/domain.h 
b/security/apparmor/include/domain.h
index de04464..a3f70c5 100644
--- a/security/apparmor/include/domain.h
+++ b/security/apparmor/include/domain.h
@@ -23,6 +23,8 @@ struct aa_domain {
char **table;
 };
 
+struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex);
+
 int apparmor_bprm_set_creds(struct linux_binprm *bprm);
 int apparmor_bprm_secureexec(struct linux_binprm *bprm);
 void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
diff --git a/security/apparmor/include/mount.h 
b/security/apparmor/include/mount.h
new file mode 100644
index 000..6f936bc
--- /dev/null
+++ b/security/apparmor/include/mount.h
@@ -0,0 +1,53 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor file mediation function definitions.
+ *
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software;

[apparmor] [PATCH 11/20] AppArmor: Minor cleanup of d_namespace_path to consolidate error handling

2012-02-22 Thread John Johansen
Signed-off-by: John Johansen 
---
 security/apparmor/path.c |   19 +++
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 96fb310..2bda438 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -84,33 +84,28 @@ static int d_namespace_path(struct path *path, char *buf, 
int buflen,
struct path root;
get_fs_root(current->fs, &root);
res = __d_path(path, &root, buf, buflen);
-   if (res && !IS_ERR(res)) {
-   /* everything's fine */
-   *name = res;
-   path_put(&root);
-   goto ok;
-   }
path_put(&root);
-   connected = 0;
-   } else
+   } else {
res = d_absolute_path(path, buf, buflen);
+   if (!our_mnt(path->mnt))
+   connected = 0;
+   }
 
/* handle error conditions - and still allow a partial path to
 * be returned.
 */
-   if (IS_ERR(res)) {
+   if (!res || IS_ERR(res)) {
+   connected = 0;
res = dentry_path_raw(path->dentry, buf, buflen);
if (IS_ERR(res)) {
error = PTR_ERR(res);
*name = buf;
goto out;
};
-} else if (!our_mnt(path->mnt))
-   connected = 0;
+}
 
*name = res;
 
-ok:
/* Handle two cases:
 * 1. A deleted dentry && profile is not allowing mediation of deleted
 * 2. On some filesystems, newly allocated dentries appear to the
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 12/20] AppArmor: Update dfa matching routines.

2012-02-22 Thread John Johansen
Update aa_dfa_match so that it doesn't result in an input string being
walked twice (once to get its length and another time to match)

Add a single step functions
  aa_dfa_next

Signed-off-by: John Johansen 
---
 security/apparmor/include/apparmor.h |2 +-
 security/apparmor/include/match.h|3 +
 security/apparmor/match.c|   80 -
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 38ccaea..43cf834 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -81,7 +81,7 @@ static inline unsigned int aa_dfa_null_transition(struct 
aa_dfa *dfa,
  unsigned int start)
 {
/* the null transition only needs the string's null terminator byte */
-   return aa_dfa_match_len(dfa, start, "", 1);
+   return aa_dfa_next(dfa, start, 0);
 }
 
 static inline bool mediated_filesystem(struct inode *inode)
diff --git a/security/apparmor/include/match.h 
b/security/apparmor/include/match.h
index a4a8639..775843e 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -116,6 +116,9 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned 
int start,
  const char *str, int len);
 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
  const char *str);
+unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
+const char c);
+
 void aa_dfa_free_kref(struct kref *kref);
 
 /**
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 94de6b4..90971a8 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -335,12 +335,12 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, 
unsigned int start,
 }
 
 /**
- * aa_dfa_next_state - traverse @dfa to find state @str stops at
+ * aa_dfa_match - traverse @dfa to find state @str stops at
  * @dfa: the dfa to match @str against  (NOT NULL)
  * @start: the state of the dfa to start matching in
  * @str: the null terminated string of bytes to match against the dfa (NOT 
NULL)
  *
- * aa_dfa_next_state will match @str against the dfa and return the state it
+ * aa_dfa_match will match @str against the dfa and return the state it
  * finished matching in. The final state can be used to look up the accepting
  * label, or as the start state of a continuing match.
  *
@@ -349,5 +349,79 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned 
int start,
 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
  const char *str)
 {
-   return aa_dfa_match_len(dfa, start, str, strlen(str));
+   u16 *def = DEFAULT_TABLE(dfa);
+   u32 *base = BASE_TABLE(dfa);
+   u16 *next = NEXT_TABLE(dfa);
+   u16 *check = CHECK_TABLE(dfa);
+   unsigned int state = start, pos;
+
+   if (state == 0)
+   return 0;
+
+   /* current state is , matching character *str */
+   if (dfa->tables[YYTD_ID_EC]) {
+   /* Equivalence class table defined */
+   u8 *equiv = EQUIV_TABLE(dfa);
+   /* default is direct to next state */
+   while (*str) {
+   pos = base[state] + equiv[(u8) *str++];
+   if (check[pos] == state)
+   state = next[pos];
+   else
+   state = def[state];
+   }
+   } else {
+   /* default is direct to next state */
+   while (*str) {
+   pos = base[state] + (u8) *str++;
+   if (check[pos] == state)
+   state = next[pos];
+   else
+   state = def[state];
+   }
+   }
+
+   return state;
+}
+
+/**
+ * aa_dfa_next - step one character to the next state in the dfa
+ * @dfa: the dfa to tranverse (NOT NULL)
+ * @state: the state to start in
+ * @c: the input character to transition on
+ *
+ * aa_dfa_match will step through the dfa by one input character @c
+ *
+ * Returns: state reach after input @c
+ */
+unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
+ const char c)
+{
+   u16 *def = DEFAULT_TABLE(dfa);
+   u32 *base = BASE_TABLE(dfa);
+   u16 *next = NEXT_TABLE(dfa);
+   u16 *check = CHECK_TABLE(dfa);
+   unsigned int pos;
+
+   /* current state is , matching character *str */
+   if (dfa->tables[YYTD_ID_EC]) {
+   /* Equivalence class table defined */
+   u8 *equiv = EQUIV_TABLE(dfa);
+   /* default is direct to next state */
+
+   pos = base[state] + equiv[(u8) c];
+   if (check[pos] == state)
+   state = next[pos];
+   else

[apparmor] [PATCH 17/20] AppArmor: Add profile introspection file to interface

2012-02-22 Thread John Johansen
Add the dynamic profiles file to the interace, to allow load policy
introspection.

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |  227 
 1 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 4267401..0cbbfab 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -182,6 +182,232 @@ const struct file_operations aa_fs_seq_file_ops = {
.release= single_release,
 };
 
+/**
+ * __next_namespace - find the next namespace to list
+ * @root: root namespace to stop search at (NOT NULL)
+ * @ns: current ns position (NOT NULL)
+ *
+ * Find the next namespace from @ns under @root and handle all locking needed
+ * while switching current namespace.
+ *
+ * Returns: next namespace or NULL if at last namespace under @root
+ * NOTE: will not unlock root->lock
+ */
+static struct aa_namespace *__next_namespace(struct aa_namespace *root,
+struct aa_namespace *ns)
+{
+   struct aa_namespace *parent;
+
+   /* is next namespace a child */
+   if (!list_empty(&ns->sub_ns)) {
+   struct aa_namespace *next;
+   next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
+   read_lock(&next->lock);
+   return next;
+   }
+
+   /* check if the next ns is a sibling, parent, gp, .. */
+   parent = ns->parent;
+   while (parent) {
+   read_unlock(&ns->lock);
+   list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
+   read_lock(&ns->lock);
+   return ns;
+   }
+   if (parent == root)
+   return NULL;
+   ns = parent;
+   parent = parent->parent;
+   }
+
+   return NULL;
+}
+
+/**
+ * __first_profile - find the first profile in a namespace
+ * @root: namespace that is root of profiles being displayed (NOT NULL)
+ * @ns: namespace to start in   (NOT NULL)
+ *
+ * Returns: unrefcounted profile or NULL if no profile
+ */
+static struct aa_profile *__first_profile(struct aa_namespace *root,
+ struct aa_namespace *ns)
+{
+   for ( ; ns; ns = __next_namespace(root, ns)) {
+   if (!list_empty(&ns->base.profiles))
+   return list_first_entry(&ns->base.profiles,
+   struct aa_profile, base.list);
+   }
+   return NULL;
+}
+
+/**
+ * __next_profile - step to the next profile in a profile tree
+ * @profile: current profile in tree (NOT NULL)
+ *
+ * Perform a depth first taversal on the profile tree in a namespace
+ *
+ * Returns: next profile or NULL if done
+ * Requires: profile->ns.lock to be held
+ */
+static struct aa_profile *__next_profile(struct aa_profile *p)
+{
+   struct aa_profile *parent;
+   struct aa_namespace *ns = p->ns;
+
+   /* is next profile a child */
+   if (!list_empty(&p->base.profiles))
+   return list_first_entry(&p->base.profiles, typeof(*p),
+   base.list);
+
+   /* is next profile a sibling, parent sibling, gp, subling, .. */
+   parent = p->parent;
+   while (parent) {
+   list_for_each_entry_continue(p, &parent->base.profiles,
+base.list)
+   return p;
+   p = parent;
+   parent = parent->parent;
+   }
+
+   /* is next another profile in the namespace */
+   list_for_each_entry_continue(p, &ns->base.profiles, base.list)
+   return p;
+
+   return NULL;
+}
+
+/**
+ * next_profile - step to the next profile in where ever it may be
+ * @root: root namespace  (NOT NULL)
+ * @profile: current profile  (NOT NULL)
+ *
+ * Returns: next profile or NULL if there isn't one
+ */
+static struct aa_profile *next_profile(struct aa_namespace *root,
+  struct aa_profile *profile)
+{
+   struct aa_profile *next = __next_profile(profile);
+   if (next)
+   return next;
+
+   /* finished all profiles in namespace move to next namespace */
+   return __first_profile(root, __next_namespace(root, profile->ns));
+}
+
+/**
+ * p_start - start a depth first traversal of profile tree
+ * @f: seq_file to fill
+ * @pos: current position
+ *
+ * Returns: first profile under current namespace or NULL if none found
+ *
+ * acquires first ns->lock
+ */
+static void *p_start(struct seq_file *f, loff_t *pos)
+   __acquires(root->lock)
+{
+   struct aa_profile *profile = NULL;
+   struct aa_namespace *root = aa_current_profile()->ns;
+   loff_t l = *pos;
+   f->private = aa_get_namespace(root);
+
+
+   /* find the first profile */
+   read_lock(&root->lock);
+   profile =

[apparmor] [PATCH 15/20] AppArmor: Add ability to load extended policy

2012-02-22 Thread John Johansen
Add the base support for the new policy extensions. This does not bring
any additional functionality, or change current semantics.

Signed-off-by: John Johansen 
---
 security/apparmor/include/apparmor.h |   13 +
 security/apparmor/include/policy.h   |   13 +
 security/apparmor/policy.c   |1 +
 security/apparmor/policy_unpack.c|   22 ++
 4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 43cf834..9cef358 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -19,6 +19,19 @@
 
 #include "match.h"
 
+/*
+ * Class of mediation types in the AppArmor policy db
+ */
+#define AA_CLASS_ENTRY 0
+#define AA_CLASS_UNKNOWN   1
+#define AA_CLASS_FILE  2
+#define AA_CLASS_CAP   3
+#define AA_CLASS_NET   4
+#define AA_CLASS_RLIMITS   5
+#define AA_CLASS_DOMAIN6
+
+#define AA_CLASS_LAST  AA_CLASS_DOMAIN
+
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
 extern int aa_g_audit_header;
diff --git a/security/apparmor/include/policy.h 
b/security/apparmor/include/policy.h
index aeda5cf..9e18e96 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -129,6 +129,17 @@ struct aa_namespace {
struct list_head sub_ns;
 };
 
+/* struct aa_policydb - match engine for a policy
+ * dfa: dfa pattern match
+ * start: set of start states for the different classes of data
+ */
+struct aa_policydb {
+   /* Generic policy DFA specific rule types will be subsections of it */
+   struct aa_dfa *dfa;
+   unsigned int start[AA_CLASS_LAST + 1];
+
+};
+
 /* struct aa_profile - basic confinement data
  * @base - base components of the profile (name, refcount, lists, lock ...)
  * @parent: parent of profile
@@ -143,6 +154,7 @@ struct aa_namespace {
  * @flags: flags controlling profile behavior
  * @path_flags: flags controlling path generation behavior
  * @size: the memory consumed by this profiles rules
+ * @policy: general match rules governing policy
  * @file: The set of rules governing basic file access and domain transitions
  * @caps: capabilities for the profile
  * @rlimits: rlimits for the profile
@@ -179,6 +191,7 @@ struct aa_profile {
u32 path_flags;
int size;
 
+   struct aa_policydb policy;
struct aa_file_rules file;
struct aa_caps caps;
struct aa_rlimit rlimits;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 537e5dc..8b7febb 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -752,6 +752,7 @@ static void free_profile(struct aa_profile *profile)
 
aa_free_sid(profile->sid);
aa_put_dfa(profile->xmatch);
+   aa_put_dfa(profile->policy.dfa);
 
aa_put_profile(profile->replacedby);
 
diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 6137b10..c7a6d03 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -562,6 +562,28 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
if (!unpack_rlimits(e, profile))
goto fail;
 
+   if (unpack_nameX(e, AA_STRUCT, "policydb")) {
+   /* generic policy dfa - optional and may be NULL */
+   profile->policy.dfa = unpack_dfa(e);
+   if (IS_ERR(profile->policy.dfa)) {
+   error = PTR_ERR(profile->policy.dfa);
+   profile->policy.dfa = NULL;
+   goto fail;
+   }
+   if (!unpack_u32(e, &profile->policy.start[0], "start"))
+   /* default start state */
+   profile->policy.start[0] = DFA_START;
+   /* setup class index */
+   for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) {
+   profile->policy.start[i] =
+   aa_dfa_next(profile->policy.dfa,
+   profile->policy.start[0],
+   i);
+   }
+   if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+   goto fail;
+   }
+
/* get file rules */
profile->file.dfa = unpack_dfa(e);
if (IS_ERR(profile->file.dfa)) {
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 16/20] AppArmor: basic networking rules

2012-02-22 Thread John Johansen
Base support for network mediation.

Signed-off-by: John Johansen 
---
 include/linux/lsm_audit.h  |4 +
 security/apparmor/Makefile |   10 ++-
 security/apparmor/apparmorfs.c |6 ++
 security/apparmor/include/net.h|   40 +
 security/apparmor/include/policy.h |3 +
 security/apparmor/lsm.c|  112 +++
 security/apparmor/net.c|  170 
 security/apparmor/policy.c |1 +
 security/apparmor/policy_unpack.c  |   48 ++-
 9 files changed, 390 insertions(+), 4 deletions(-)
 create mode 100644 security/apparmor/include/net.h
 create mode 100644 security/apparmor/net.c

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 88e78de..c63979a 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -124,6 +124,10 @@ struct common_audit_data {
u32 denied;
uid_t ouid;
} fs;
+   struct {
+   int type, protocol;
+   struct sock *sk;
+   } net;
};
} apparmor_audit_data;
 #endif
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 86103ce..96cf725 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,10 +4,9 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
   path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-  resource.o sid.o file.o
-
-clean-files := capability_names.h rlim_names.h
+  resource.o sid.o file.o net.o
 
+clean-files := capability_names.h rlim_names.h af_names.h
 
 # Build a lower case string table of capability names
 # Transforms lines from
@@ -20,6 +19,8 @@ cmd_make-caps = echo "static const char *capability_names[] = 
{" > $@ ;\
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
echo "};" >> $@
 
+quiet_cmd_make-af = GEN $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ; sed 
-n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ 
\\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2]  = 
\"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
 
 # Build a lower case string table of rlimit names.
 # Transforms lines from
@@ -55,6 +56,7 @@ cmd_make-rlim = echo "static const char 
*rlim_names[RLIM_NLIMITS] = {" > $@ ;\
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
 
 $(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/af_names.h
 $(obj)/resource.o : $(obj)/rlim_names.h
 $(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
$(src)/Makefile
@@ -62,3 +64,5 @@ $(obj)/capability_names.h : 
$(srctree)/include/linux/capability.h \
 $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
  $(src)/Makefile
$(call cmd,make-rlim)
+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
+   $(call cmd,make-af)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 38d6262..4267401 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -198,9 +198,15 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
{ }
 };
 
+static struct aa_fs_entry aa_fs_entry_network[] = {
+   AA_FS_FILE_BOOLEAN("af_masking",1),
+   { }
+};
+
 static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file",   aa_fs_entry_file),
+   AA_FS_DIR("network",aa_fs_entry_network),
AA_FS_FILE_BOOLEAN("namespaces",1),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
new file mode 100644
index 000..3c7d599
--- /dev/null
+++ b/security/apparmor/include/net.h
@@ -0,0 +1,40 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2010 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include 
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+   u16 all

[apparmor] [PATCH 10/20] AppArmor: Retrieve the dentry_path for error reporting when path lookup fails

2012-02-22 Thread John Johansen
When __d_path and d_absolute_path fail due to the name being outside of
the current namespace no name is reported.  Use dentry_path to provide
some hint as to which file was being accessed.

Signed-off-by: John Johansen 
---
 security/apparmor/path.c |   15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 70b09bb..96fb310 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -95,18 +95,21 @@ static int d_namespace_path(struct path *path, char *buf, 
int buflen,
} else
res = d_absolute_path(path, buf, buflen);
 
-   *name = res;
/* handle error conditions - and still allow a partial path to
 * be returned.
 */
if (IS_ERR(res)) {
-   error = PTR_ERR(res);
-   *name = buf;
-   goto out;
-   }
-   if (!our_mnt(path->mnt))
+   res = dentry_path_raw(path->dentry, buf, buflen);
+   if (IS_ERR(res)) {
+   error = PTR_ERR(res);
+   *name = buf;
+   goto out;
+   };
+} else if (!our_mnt(path->mnt))
connected = 0;
 
+   *name = res;
+
 ok:
/* Handle two cases:
 * 1. A deleted dentry && profile is not allowing mediation of deleted
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 14/20] AppArmor: Make chroot relative the default path lookup type

2012-02-22 Thread John Johansen
Profiles that want name lookup past the chroot to the namespace root
must be marked as such, all other profiles should be chroot relative.

Currently the autogenerated null (learning), and unconfined  profiles are
not marked as such. Make sure they are properly flagged. This should not
affect behavior except for auto-generated profiles when a chroot is entered.
Profiles loaded from userspace will not be affected as they provide their
own value for the flag.

This change does not affect mediation as it only changes the path reported by
the unconfined (none mediating), an null learning profiles.

Also ensure that if a profile is ever loaded with out path flags set, that
it defaults to being chroot relative.

Signed-off-by: John Johansen 
---
 security/apparmor/policy.c|3 +++
 security/apparmor/policy_unpack.c |3 ++-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 4f0eade..537e5dc 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -655,6 +655,9 @@ struct aa_profile *aa_alloc_profile(const char *hname)
return NULL;
}
 
+   /* default to chroot relative paths */
+   profile->path_flags = PATH_CHROOT_REL;
+
/* refcount released by caller */
return profile;
 }
diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 5c46acf..6137b10 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -25,6 +25,7 @@
 #include "include/audit.h"
 #include "include/context.h"
 #include "include/match.h"
+#include "include/path.h"
 #include "include/policy.h"
 #include "include/policy_unpack.h"
 #include "include/sid.h"
@@ -523,7 +524,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
else
/* set a default value if path_flags field is not present */
-   profile->path_flags = PFLAG_MEDIATE_DELETED;
+   profile->path_flags = PFLAG_MEDIATE_DELETED | PATH_CHROOT_REL;
 
if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
goto fail;
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 13/20] AppArmor: Move path failure information into aa_get_name and rename

2012-02-22 Thread John Johansen
Move the path name lookup failure messages into the main path name lookup
routine, as the information is useful in more than just aa_path_perm.

Also rename aa_get_name to aa_path_name as it is not getting a reference
counted object with a corresponding put fn.

Signed-off-by: John Johansen 
---
 security/apparmor/domain.c   |5 ++---
 security/apparmor/file.c |   18 +++---
 security/apparmor/include/path.h |3 ++-
 security/apparmor/path.c |   22 ++
 4 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c1e18ba..7c69599 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
state = profile->file.start;
 
/* buffer freed below, name is pointer into buffer */
-   error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer,
-   &name);
+   error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
+&name, &info);
if (error) {
if (profile->flags &
(PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
error = 0;
-   info = "Exec failed name resolution";
name = bprm->filename;
goto audit;
}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index bba875c..3022c0f 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -278,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, 
struct path *path,
int error;
 
flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
-   error = aa_get_name(path, flags, &buffer, &name);
+   error = aa_path_name(path, flags, &buffer, &name, &info);
if (error) {
if (error == -ENOENT && is_deleted(path->dentry)) {
/* Access to open files that are deleted are
 * give a pass (implicit delegation)
 */
error = 0;
+   info = NULL;
perms.allow = request;
-   } else if (error == -ENOENT)
-   info = "Failed name lookup - deleted entry";
-   else if (error == -ESTALE)
-   info = "Failed name lookup - disconnected path";
-   else if (error == -ENAMETOOLONG)
-   info = "Failed name lookup - name too long";
-   else
-   info = "Failed name lookup";
+   }
} else {
aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
 &perms);
@@ -364,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct 
dentry *old_dentry,
lperms = nullperms;
 
/* buffer freed below, lname is pointer in buffer */
-   error = aa_get_name(&link, profile->path_flags, &buffer, &lname);
+   error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
+&info);
if (error)
goto audit;
 
/* buffer2 freed below, tname is pointer in buffer2 */
-   error = aa_get_name(&target, profile->path_flags, &buffer2, &tname);
+   error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
+&info);
if (error)
goto audit;
 
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 27b327a..286ac75 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -26,6 +26,7 @@ enum path_flags {
PATH_MEDIATE_DELETED = 0x1, /* mediate deleted paths */
 };
 
-int aa_get_name(struct path *path, int flags, char **buffer, const char 
**name);
+int aa_path_name(struct path *path, int flags, char **buffer,
+const char **name, const char **info);
 
 #endif /* __AA_PATH_H */
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 2bda438..e0447c5 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -157,7 +157,7 @@ out:
  * Returns: %0 else error on failure
  */
 static int get_name_to_buffer(struct path *path, int flags, char *buffer,
- int size, char **name)
+ int size, char **name, const char **info)
 {
int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
int error = d_namespace_path(path, buffer, size - adjust, name, flags);
@@ -169,15 +169,27 @@ static int get_name_to_buffer(struct path *path, int 
flags, char *buffer,
 */
strcpy(&buffer[size - 2], "/");
 
+   if (info && error) {
+   if (error == -ENOENT)
+   *info = "Failed name lookup - deleted entry";
+   else if (er

[apparmor] [PATCH 04/20] AppArmor: export known rlimit names/value mappings in securityfs

2012-02-22 Thread John Johansen
From: Kees Cook 

Since the parser needs to know which rlimits are known to the kernel,
export the list via a mask file in the "rlimit" subdirectory in the
securityfs "features" directory.

Signed-off-by: Kees Cook 
Signed-off-by: John Johansen 
---
 security/apparmor/Makefile   |   24 ++--
 security/apparmor/apparmorfs.c   |2 ++
 security/apparmor/include/resource.h |4 
 security/apparmor/resource.c |5 +
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 2dafe50..86103ce 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -28,25 +28,37 @@ cmd_make-caps = echo "static const char *capability_names[] 
= {" > $@ ;\
 #[RLIMIT_STACK] = "stack",
 #
 # and build a second integer table (with the second sed cmd), that maps
-# RLIMIT defines to the order defined in asm-generic/resource.h  Thi is
+# RLIMIT defines to the order defined in asm-generic/resource.h  This is
 # required by policy load to map policy ordering of RLIMITs to internal
 # ordering for architectures that redefine an RLIMIT.
 # Transforms lines from
 ##define RLIMIT_STACK  3   /* max stack size */
 # to
 # RLIMIT_STACK, 
+#
+# and build the securityfs entries for the mapping.
+# Transforms lines from
+##define RLIMIT_FSIZE1   /* Maximum filesize */
+##define RLIMIT_STACK  3   /* max stack size */
+# to
+# #define AA_FS_RLIMIT_MASK "fsize stack"
 quiet_cmd_make-rlim = GEN $@
-cmd_make-rlim = echo "static const char *rlim_names[] = {" > $@ ;\
+cmd_make-rlim = echo "static const char *rlim_names[RLIM_NLIMITS] = {" > $@ ;\
sed $< >> $@ -r -n \
-e 's/^\# ?define[ \t]+(RLIMIT_([A-Z0-9_]+)).*/[\1] = "\L\2",/p';\
echo "};" >> $@ ;\
-   echo "static const int rlim_map[] = {" >> $@ ;\
+   echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
-   echo "};" >> $@
+   echo "};" >> $@ ; \
+   echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
+   sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
+   tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
 
 $(obj)/capability.o : $(obj)/capability_names.h
 $(obj)/resource.o : $(obj)/rlim_names.h
-$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
+$(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
+   $(src)/Makefile
$(call cmd,make-caps)
-$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h
+$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
+ $(src)/Makefile
$(call cmd,make-rlim)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 68ce771..38d6262 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -25,6 +25,7 @@
 #include "include/audit.h"
 #include "include/context.h"
 #include "include/policy.h"
+#include "include/resource.h"
 
 /**
  * aa_simple_write_to_buffer - common routine for getting policy from user
@@ -202,6 +203,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("file",   aa_fs_entry_file),
AA_FS_FILE_BOOLEAN("namespaces",1),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
+   AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
{ }
 };
 
diff --git a/security/apparmor/include/resource.h 
b/security/apparmor/include/resource.h
index 02baec7..d3f4cf0 100644
--- a/security/apparmor/include/resource.h
+++ b/security/apparmor/include/resource.h
@@ -18,6 +18,8 @@
 #include 
 #include 
 
+#include "apparmorfs.h"
+
 struct aa_profile;
 
 /* struct aa_rlimit - rlimit settings for the profile
@@ -32,6 +34,8 @@ struct aa_rlimit {
struct rlimit limits[RLIM_NLIMITS];
 };
 
+extern struct aa_fs_entry aa_fs_entry_rlimit[];
+
 int aa_map_resource(int resource);
 int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
  unsigned int resource, struct rlimit *new_rlim);
diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
index a4136c1..72c25a4 100644
--- a/security/apparmor/resource.c
+++ b/security/apparmor/resource.c
@@ -23,6 +23,11 @@
  */
 #include "rlim_names.h"
 
+struct aa_fs_entry aa_fs_entry_rlimit[] = {
+   AA_FS_FILE_STRING("mask", AA_FS_RLIMIT_MASK),
+   { }
+};
+
 /* audit callback for resource specific fields */
 static void audit_cb(struct audit_buffer *ab, void *va)
 {
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 07/20] AppArmor: Fix underflow in xindex calculation

2012-02-22 Thread John Johansen
If the xindex value stored in the accept tables is 0, the extraction of
that value will result in an underflow (0 - 4).

In properly compiled policy this should not happen for file rules but
it may be possible for other rule types in the future.

To exploit this underflow a user would have to be able to load a corrupt
policy, which requires CAP_MAC_ADMIN, overwrite system policy in kernel
memory or know of a compiler error resulting in the flaw being present
for loaded policy (no such flaw is known at this time).

Signed-off-by: John Johansen 
---
 security/apparmor/include/file.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ab8c6d8..f98fd47 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
index |= AA_X_NAME;
} else if (old_index == 3) {
index |= AA_X_NAME | AA_X_CHILD;
-   } else {
+   } else if (old_index) {
index |= AA_X_TABLE;
index |= old_index - 4;
}
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 08/20] AppArmor: fix mapping of META_READ to audit and quiet flags

2012-02-22 Thread John Johansen
The mapping of AA_MAY_META_READ for the allow mask was also being mapped
to the audit and quiet masks. This would result in some operations being
audited when the should not.

This flaw was hidden by the previous audit bug which would drop some
messages that where supposed to be audited.

Signed-off-by: John Johansen 
---
 security/apparmor/file.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 7312db7..bba875c 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -173,8 +173,6 @@ static u32 map_old_perms(u32 old)
if (old & 0x40) /* AA_EXEC_MMAP */
new |= AA_EXEC_MMAP;
 
-   new |= AA_MAY_META_READ;
-
return new;
 }
 
@@ -212,6 +210,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, 
unsigned int state,
perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
perms.xindex = dfa_other_xindex(dfa, state);
}
+   perms.allow |= AA_MAY_META_READ;
 
/* change_profile wasn't determined by ownership in old mapping */
if (ACCEPT_TABLE(dfa)[state] & 0x8000)
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 06/20] AppArmor: Fix dropping of allowed operations that are force audited

2012-02-22 Thread John Johansen
The audit permission flag, that specifies an audit message should be
provided when an operation is allowed, was being ignored in some cases.

This is because the auto audit mode (which determines the audit mode from
system flags) was incorrectly assigned the same value as audit mode. The
shared value would result in messages that should be audited going through
a second evaluation as to whether they should be audited based on the
auto audit, resulting in some messages being dropped.

Signed-off-by: John Johansen 
---
 security/apparmor/audit.c |1 +
 security/apparmor/include/audit.h |5 ++---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 96502b2..f419e12 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -89,6 +89,7 @@ static char *aa_audit_type[] = {
"STATUS",
"ERROR",
"KILLED"
+   "AUTO"
 };
 
 /*
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 1951786..9317cd8 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -28,8 +28,6 @@ struct aa_profile;
 extern const char *audit_mode_names[];
 #define AUDIT_MAX_INDEX 5
 
-#define AUDIT_APPARMOR_AUTO 0  /* auto choose audit message type */
-
 enum audit_mode {
AUDIT_NORMAL,   /* follow normal auditing of accesses */
AUDIT_QUIET_DENIED, /* quiet all denied access messages */
@@ -45,7 +43,8 @@ enum audit_type {
AUDIT_APPARMOR_HINT,
AUDIT_APPARMOR_STATUS,
AUDIT_APPARMOR_ERROR,
-   AUDIT_APPARMOR_KILL
+   AUDIT_APPARMOR_KILL,
+   AUDIT_APPARMOR_AUTO
 };
 
 extern const char *op_table[];
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 05/20] AppArmor: Add mising end of structure test to caps unpacking

2012-02-22 Thread John Johansen
The unpacking of struct capsx is missing a check for the end of the
caps structure.  This can lead to unpack failures depending on what else
is packed into the policy file being unpacked.

Signed-off-by: John Johansen 
---
 security/apparmor/policy_unpack.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 741dd13..5c46acf 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -554,6 +554,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
goto fail;
if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
goto fail;
+   if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+   goto fail;
}
 
if (!unpack_rlimits(e, profile))
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 02/20] AppArmor: add initial "features" directory to securityfs

2012-02-22 Thread John Johansen
From: Kees Cook 

This adds the "features" subdirectory to the AppArmor securityfs
to display boolean features flags and the known capability mask.

Signed-off-by: Kees Cook 
Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |   52 
 security/apparmor/include/apparmorfs.h |   14 
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 1e22bb3..36efe64 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "include/apparmor.h"
 #include "include/apparmorfs.h"
@@ -142,12 +143,63 @@ static const struct file_operations aa_fs_profile_remove 
= {
.llseek = default_llseek,
 };
 
+static int aa_fs_seq_show(struct seq_file *seq, void *v)
+{
+   struct aa_fs_entry *fs_file = seq->private;
+
+   if (!fs_file)
+   return 0;
+
+   switch (fs_file->v_type) {
+   case AA_FS_TYPE_BOOLEAN:
+   seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
+   break;
+   case AA_FS_TYPE_U64:
+   seq_printf(seq, "%#08lx\n", fs_file->v.u64);
+   break;
+   default:
+   /* Ignore unpritable entry types. */
+   break;
+   }
+
+   return 0;
+}
+
+static int aa_fs_seq_open(struct inode *inode, struct file *file)
+{
+   return single_open(file, aa_fs_seq_show, inode->i_private);
+}
+
+const struct file_operations aa_fs_seq_file_ops = {
+   .owner  = THIS_MODULE,
+   .open   = aa_fs_seq_open,
+   .read   = seq_read,
+   .llseek = seq_lseek,
+   .release= single_release,
+};
+
 /** Base file system setup **/
 
+static struct aa_fs_entry aa_fs_entry_domain[] = {
+   AA_FS_FILE_BOOLEAN("change_hat",1),
+   AA_FS_FILE_BOOLEAN("change_hatv",   1),
+   AA_FS_FILE_BOOLEAN("change_onexec", 1),
+   AA_FS_FILE_BOOLEAN("change_profile",1),
+   { }
+};
+
+static struct aa_fs_entry aa_fs_entry_features[] = {
+   AA_FS_DIR("domain", aa_fs_entry_domain),
+   AA_FS_FILE_BOOLEAN("namespaces",1),
+   AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
+   { }
+};
+
 static struct aa_fs_entry aa_fs_entry_apparmor[] = {
AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
+   AA_FS_DIR("features", aa_fs_entry_features),
{ }
 };
 
diff --git a/security/apparmor/include/apparmorfs.h 
b/security/apparmor/include/apparmorfs.h
index 4fdf02f..16e6545 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -16,6 +16,8 @@
 #define __AA_APPARMORFS_H
 
 enum aa_fs_type {
+   AA_FS_TYPE_BOOLEAN,
+   AA_FS_TYPE_U64,
AA_FS_TYPE_FOPS,
AA_FS_TYPE_DIR,
 };
@@ -28,11 +30,23 @@ struct aa_fs_entry {
umode_t mode;
enum aa_fs_type v_type;
union {
+   bool boolean;
+   unsigned long u64;
struct aa_fs_entry *files;
} v;
const struct file_operations *file_ops;
 };
 
+extern const struct file_operations aa_fs_seq_file_ops;
+
+#define AA_FS_FILE_BOOLEAN(_name, _value) \
+   { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
+#define AA_FS_FILE_U64(_name, _value) \
+   { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
 #define AA_FS_FILE_FOPS(_name, _mode, _fops) \
{ .name = (_name), .v_type = AA_FS_TYPE_FOPS, \
  .mode = (_mode), .file_ops = (_fops) }
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 03/20] AppArmor: add "file" details to securityfs

2012-02-22 Thread John Johansen
From: Kees Cook 

Create the "file" directory in the securityfs for tracking features
related to files.

Signed-off-by: Kees Cook 
Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |   10 ++
 security/apparmor/include/apparmorfs.h |6 ++
 2 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 36efe64..68ce771 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -154,6 +154,9 @@ static int aa_fs_seq_show(struct seq_file *seq, void *v)
case AA_FS_TYPE_BOOLEAN:
seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
break;
+   case AA_FS_TYPE_STRING:
+   seq_printf(seq, "%s\n", fs_file->v.string);
+   break;
case AA_FS_TYPE_U64:
seq_printf(seq, "%#08lx\n", fs_file->v.u64);
break;
@@ -180,6 +183,12 @@ const struct file_operations aa_fs_seq_file_ops = {
 
 /** Base file system setup **/
 
+static struct aa_fs_entry aa_fs_entry_file[] = {
+   AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
+ "link lock"),
+   { }
+};
+
 static struct aa_fs_entry aa_fs_entry_domain[] = {
AA_FS_FILE_BOOLEAN("change_hat",1),
AA_FS_FILE_BOOLEAN("change_hatv",   1),
@@ -190,6 +199,7 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("domain", aa_fs_entry_domain),
+   AA_FS_DIR("file",   aa_fs_entry_file),
AA_FS_FILE_BOOLEAN("namespaces",1),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
{ }
diff --git a/security/apparmor/include/apparmorfs.h 
b/security/apparmor/include/apparmorfs.h
index 16e6545..7ea4769 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -17,6 +17,7 @@
 
 enum aa_fs_type {
AA_FS_TYPE_BOOLEAN,
+   AA_FS_TYPE_STRING,
AA_FS_TYPE_U64,
AA_FS_TYPE_FOPS,
AA_FS_TYPE_DIR,
@@ -31,6 +32,7 @@ struct aa_fs_entry {
enum aa_fs_type v_type;
union {
bool boolean;
+   char *string;
unsigned long u64;
struct aa_fs_entry *files;
} v;
@@ -43,6 +45,10 @@ extern const struct file_operations aa_fs_seq_file_ops;
{ .name = (_name), .mode = 0444, \
  .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \
  .file_ops = &aa_fs_seq_file_ops }
+#define AA_FS_FILE_STRING(_name, _value) \
+   { .name = (_name), .mode = 0444, \
+ .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \
+ .file_ops = &aa_fs_seq_file_ops }
 #define AA_FS_FILE_U64(_name, _value) \
{ .name = (_name), .mode = 0444, \
  .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 01/20] AppArmor: refactor securityfs to use structures

2012-02-22 Thread John Johansen
From: Kees Cook 

Use a file tree structure to represent the AppArmor securityfs.

Signed-off-by: Kees Cook 

Conflicts:

security/apparmor/apparmorfs.c

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |  132 ++--
 security/apparmor/include/apparmorfs.h |   24 ++
 2 files changed, 114 insertions(+), 42 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 69ddb47..1e22bb3 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -144,36 +144,103 @@ static const struct file_operations aa_fs_profile_remove 
= {
 
 /** Base file system setup **/
 
-static struct dentry *aa_fs_dentry __initdata;
+static struct aa_fs_entry aa_fs_entry_apparmor[] = {
+   AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
+   AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
+   AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
+   { }
+};
 
-static void __init aafs_remove(const char *name)
-{
-   struct dentry *dentry;
+static struct aa_fs_entry aa_fs_entry =
+   AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
 
-   dentry = lookup_one_len(name, aa_fs_dentry, strlen(name));
-   if (!IS_ERR(dentry)) {
-   securityfs_remove(dentry);
-   dput(dentry);
+/**
+ * aafs_create_file - create a file entry in the apparmor securityfs
+ * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
+ * @parent: the parent dentry in the securityfs
+ *
+ * Use aafs_remove_file to remove entries created with this fn.
+ */
+static int __init aafs_create_file(struct aa_fs_entry *fs_file,
+  struct dentry *parent)
+{
+   int error = 0;
+
+   fs_file->dentry = securityfs_create_file(fs_file->name,
+S_IFREG | fs_file->mode,
+parent, fs_file,
+fs_file->file_ops);
+   if (IS_ERR(fs_file->dentry)) {
+   error = PTR_ERR(fs_file->dentry);
+   fs_file->dentry = NULL;
}
+   return error;
 }
 
 /**
- * aafs_create - create an entry in the apparmor filesystem
- * @name: name of the entry (NOT NULL)
- * @mask: file permission mask of the file
- * @fops: file operations for the file (NOT NULL)
+ * aafs_create_dir - recursively create a directory entry in the securityfs
+ * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
+ * @parent: the parent dentry in the securityfs
  *
- * Used aafs_remove to remove entries created with this fn.
+ * Use aafs_remove_dir to remove entries created with this fn.
  */
-static int __init aafs_create(const char *name, int mask,
- const struct file_operations *fops)
+static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
+ struct dentry *parent)
 {
-   struct dentry *dentry;
+   int error;
+   struct aa_fs_entry *fs_file;
 
-   dentry = securityfs_create_file(name, S_IFREG | mask, aa_fs_dentry,
-   NULL, fops);
+   fs_dir->dentry = securityfs_create_dir(fs_dir->name, parent);
+   if (IS_ERR(fs_dir->dentry)) {
+   error = PTR_ERR(fs_dir->dentry);
+   fs_dir->dentry = NULL;
+   goto failed;
+   }
 
-   return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
+   for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
+   if (fs_file->v_type == AA_FS_TYPE_DIR)
+   error = aafs_create_dir(fs_file, fs_dir->dentry);
+   else
+   error = aafs_create_file(fs_file, fs_dir->dentry);
+   if (error)
+   goto failed;
+   }
+
+   return 0;
+
+failed:
+   return error;
+}
+
+/**
+ * aafs_remove_file - drop a single file entry in the apparmor securityfs
+ * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
+ */
+static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
+{
+   if (!fs_file->dentry)
+   return;
+
+   securityfs_remove(fs_file->dentry);
+   fs_file->dentry = NULL;
+}
+
+/**
+ * aafs_remove_dir - recursively drop a directory entry from the securityfs
+ * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
+ */
+static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
+{
+   struct aa_fs_entry *fs_file;
+
+   for (fs_file = fs_dir->v.files; fs_file->name; ++fs_file) {
+   if (fs_file->v_type == AA_FS_TYPE_DIR)
+   aafs_remove_dir(fs_file);
+   else
+   aafs_remove_file(fs_file);
+   }
+
+   aafs_remove_file(fs_dir);
 }
 
 /**
@@ -183,14 +250,7 @@ static int __init aafs_create(const char *name, int mask,
  */
 void __init aa_destroy_aafs(void)
 {
-   if (aa_fs_dentry) {
-   aaf

[apparmor] [Patch 0/20] AppArmor 2.8 kernel patches

2012-02-22 Thread John Johansen
We lets try this again with a proper intro email (these are the same
patches).

These are the kernel patches meant for the AppArmor 2.8 release. The set
of patches is smaller than originally planned for but with certain features
missing, I decided to hold back the unused/unneeded patches.  The missing
patches will show up soon in an AppArmor 3.0 alpha

The first 4 patches are Kees's update to the apparmor filesystem.  They
are here for convienence not because they need to be reviewed yet again.

Of the following patch 
  Patches 1 - 9 will be sent upstream in as the first pull request, the
  rest will follow being sent first for review.

Patches
  [PATCH 16/20] AppArmor: basic networking rules
  [PATCH 17/20] AppArmor: Add profile introspection file to interface

will not be sent upstream at this time.  They are hold overs from previous
releases and their replacements just aren't ready yet so unfortunately
we will need to carry these a little longer.



-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 13/16] AppArmor: Add profile introspection file to interface

2012-02-22 Thread John Johansen
Add the dynamic profiles file to the interace, to allow load policy
introspection.

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |  227 
 1 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 4267401..0cbbfab 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -182,6 +182,232 @@ const struct file_operations aa_fs_seq_file_ops = {
.release= single_release,
 };
 
+/**
+ * __next_namespace - find the next namespace to list
+ * @root: root namespace to stop search at (NOT NULL)
+ * @ns: current ns position (NOT NULL)
+ *
+ * Find the next namespace from @ns under @root and handle all locking needed
+ * while switching current namespace.
+ *
+ * Returns: next namespace or NULL if at last namespace under @root
+ * NOTE: will not unlock root->lock
+ */
+static struct aa_namespace *__next_namespace(struct aa_namespace *root,
+struct aa_namespace *ns)
+{
+   struct aa_namespace *parent;
+
+   /* is next namespace a child */
+   if (!list_empty(&ns->sub_ns)) {
+   struct aa_namespace *next;
+   next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
+   read_lock(&next->lock);
+   return next;
+   }
+
+   /* check if the next ns is a sibling, parent, gp, .. */
+   parent = ns->parent;
+   while (parent) {
+   read_unlock(&ns->lock);
+   list_for_each_entry_continue(ns, &parent->sub_ns, base.list) {
+   read_lock(&ns->lock);
+   return ns;
+   }
+   if (parent == root)
+   return NULL;
+   ns = parent;
+   parent = parent->parent;
+   }
+
+   return NULL;
+}
+
+/**
+ * __first_profile - find the first profile in a namespace
+ * @root: namespace that is root of profiles being displayed (NOT NULL)
+ * @ns: namespace to start in   (NOT NULL)
+ *
+ * Returns: unrefcounted profile or NULL if no profile
+ */
+static struct aa_profile *__first_profile(struct aa_namespace *root,
+ struct aa_namespace *ns)
+{
+   for ( ; ns; ns = __next_namespace(root, ns)) {
+   if (!list_empty(&ns->base.profiles))
+   return list_first_entry(&ns->base.profiles,
+   struct aa_profile, base.list);
+   }
+   return NULL;
+}
+
+/**
+ * __next_profile - step to the next profile in a profile tree
+ * @profile: current profile in tree (NOT NULL)
+ *
+ * Perform a depth first taversal on the profile tree in a namespace
+ *
+ * Returns: next profile or NULL if done
+ * Requires: profile->ns.lock to be held
+ */
+static struct aa_profile *__next_profile(struct aa_profile *p)
+{
+   struct aa_profile *parent;
+   struct aa_namespace *ns = p->ns;
+
+   /* is next profile a child */
+   if (!list_empty(&p->base.profiles))
+   return list_first_entry(&p->base.profiles, typeof(*p),
+   base.list);
+
+   /* is next profile a sibling, parent sibling, gp, subling, .. */
+   parent = p->parent;
+   while (parent) {
+   list_for_each_entry_continue(p, &parent->base.profiles,
+base.list)
+   return p;
+   p = parent;
+   parent = parent->parent;
+   }
+
+   /* is next another profile in the namespace */
+   list_for_each_entry_continue(p, &ns->base.profiles, base.list)
+   return p;
+
+   return NULL;
+}
+
+/**
+ * next_profile - step to the next profile in where ever it may be
+ * @root: root namespace  (NOT NULL)
+ * @profile: current profile  (NOT NULL)
+ *
+ * Returns: next profile or NULL if there isn't one
+ */
+static struct aa_profile *next_profile(struct aa_namespace *root,
+  struct aa_profile *profile)
+{
+   struct aa_profile *next = __next_profile(profile);
+   if (next)
+   return next;
+
+   /* finished all profiles in namespace move to next namespace */
+   return __first_profile(root, __next_namespace(root, profile->ns));
+}
+
+/**
+ * p_start - start a depth first traversal of profile tree
+ * @f: seq_file to fill
+ * @pos: current position
+ *
+ * Returns: first profile under current namespace or NULL if none found
+ *
+ * acquires first ns->lock
+ */
+static void *p_start(struct seq_file *f, loff_t *pos)
+   __acquires(root->lock)
+{
+   struct aa_profile *profile = NULL;
+   struct aa_namespace *root = aa_current_profile()->ns;
+   loff_t l = *pos;
+   f->private = aa_get_namespace(root);
+
+
+   /* find the first profile */
+   read_lock(&root->lock);
+   profile =

[apparmor] [PATCH 16/16] AppArmor: Add mediation of chroot

2012-02-22 Thread John Johansen
Add support for chroot rules, which allow a profile to specify where a
chroot can be made.

  chroot /tmp/example,

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c   |1 +
 security/apparmor/audit.c|1 +
 security/apparmor/include/apparmor.h |3 +-
 security/apparmor/include/audit.h|1 +
 security/apparmor/include/mount.h|4 +++
 security/apparmor/lsm.c  |   13 ++
 security/apparmor/mount.c|   42 ++
 7 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index d30aa11..32c1394 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -437,6 +437,7 @@ static struct aa_fs_entry aa_fs_entry_mount[] = {
 static struct aa_fs_entry aa_fs_entry_namespaces[] = {
AA_FS_FILE_BOOLEAN("profile",   1),
AA_FS_FILE_BOOLEAN("pivot_root",1),
+   AA_FS_FILE_BOOLEAN("chroot",1),
 };
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 64e9442..4c80d4f 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -47,6 +47,7 @@ const char *op_table[] = {
"pivotroot",
"mount",
"umount",
+   "chroot",
 
"create",
"post_create",
diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index d615726..5f4b32e 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -30,8 +30,9 @@
 #define AA_CLASS_RLIMITS   5
 #define AA_CLASS_DOMAIN6
 #define AA_CLASS_MOUNT 7
+#define AA_CLASS_CHROOT8
 
-#define AA_CLASS_LAST  AA_CLASS_MOUNT
+#define AA_CLASS_LAST  AA_CLASS_CHROOT
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 0e8689d..693f37f 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -76,6 +76,7 @@ enum aa_ops {
OP_PIVOTROOT,
OP_MOUNT,
OP_UMOUNT,
+   OP_CHROOT,
 
OP_CREATE,
OP_POST_CREATE,
diff --git a/security/apparmor/include/mount.h 
b/security/apparmor/include/mount.h
index 6f936bc..a1c5026 100644
--- a/security/apparmor/include/mount.h
+++ b/security/apparmor/include/mount.h
@@ -27,6 +27,8 @@
 
 #define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
 
+/* chroot permissions */
+#define AA_MAY_CHROOT  0x01
 
 int aa_remount(struct aa_profile *profile, struct path *path,
   unsigned long flags, void *data);
@@ -50,4 +52,6 @@ int aa_umount(struct aa_profile *profile, struct vfsmount 
*mnt, int flags);
 int aa_pivotroot(struct aa_profile *profile, struct path *old_path,
  struct path *new_path);
 
+int aa_chroot(struct aa_profile *profile, struct path *path);
+
 #endif /* __AA_MOUNT_H */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 3aec025..507ba44 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -544,6 +544,18 @@ static int apparmor_sb_mount(char *dev_name, struct path 
*path, char *type,
return error;
 }
 
+static int apparmor_path_chroot(struct path *path)
+{
+   struct aa_profile *profile;
+   int error = 0;
+
+   profile = __aa_current_profile();
+   if (!unconfined(profile))
+   error = aa_chroot(profile, path);
+
+   return error;
+}
+
 static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
 {
struct aa_profile *profile;
@@ -786,6 +798,7 @@ static struct security_operations apparmor_ops = {
.sb_mount = apparmor_sb_mount,
.sb_umount =apparmor_sb_umount,
.sb_pivotroot = apparmor_sb_pivotroot,
+   .path_chroot =  apparmor_path_chroot,
 
.path_link =apparmor_path_link,
.path_unlink =  apparmor_path_unlink,
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 1572bf6..86f6102 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -587,3 +587,45 @@ audit:
 
return error;
 }
+
+int aa_chroot(struct aa_profile *profile, struct path *path)
+{
+   struct file_perms perms = { };
+   struct aa_profile *target = NULL;
+   char *buffer = NULL;
+   const char *name, *info = NULL;
+   int error;
+
+   error = aa_path_name(path, profile->path_flags, &buffer, &name, &info);
+   if (error)
+   goto audit;
+
+   if (profile->policy.dfa) {
+   unsigned int state;
+   state = aa_dfa_match(profile->policy.dfa,
+profile->policy.start[AA_CLASS_CHROOT],
+   

[apparmor] [PATCH 14/16] AppArmor: Add the ability to mediate mount

2012-02-22 Thread John Johansen
Add the ability for apparmor to do mediation of mount operations.

Signed-off-by: John Johansen 
---
 include/linux/lsm_audit.h|7 +
 security/apparmor/Makefile   |2 +-
 security/apparmor/audit.c|4 +
 security/apparmor/domain.c   |2 +-
 security/apparmor/include/apparmor.h |3 +-
 security/apparmor/include/audit.h|4 +
 security/apparmor/include/domain.h   |2 +
 security/apparmor/include/mount.h|   53 +++
 security/apparmor/lsm.c  |   59 
 security/apparmor/mount.c|  589 ++
 10 files changed, 722 insertions(+), 3 deletions(-)
 create mode 100644 security/apparmor/include/mount.h
 create mode 100644 security/apparmor/mount.c

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index c63979a..39a00cc 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -119,6 +119,13 @@ struct common_audit_data {
unsigned long max;
} rlim;
struct {
+   const char *src_name;
+   const char *type;
+   const char *trans;
+   const char *data;
+   unsigned long flags;
+   } mnt;
+   struct {
const char *target;
u32 request;
u32 denied;
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 96cf725..0352e1a 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
   path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-  resource.o sid.o file.o net.o
+  resource.o sid.o file.o net.o mount.o
 
 clean-files := capability_names.h rlim_names.h af_names.h
 
diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index f419e12..64e9442 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -44,6 +44,10 @@ const char *op_table[] = {
"file_mmap",
"file_mprotect",
 
+   "pivotroot",
+   "mount",
+   "umount",
+
"create",
"post_create",
"bind",
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 7c69599..6fc18d1 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -242,7 +242,7 @@ static const char *next_name(int xtype, const char *name)
  *
  * Returns: refcounted profile, or NULL on failure (MAYBE NULL)
  */
-static struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 
xindex)
+struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex)
 {
struct aa_profile *new_profile = NULL;
struct aa_namespace *ns = profile->ns;
diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 9cef358..d615726 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -29,8 +29,9 @@
 #define AA_CLASS_NET   4
 #define AA_CLASS_RLIMITS   5
 #define AA_CLASS_DOMAIN6
+#define AA_CLASS_MOUNT 7
 
-#define AA_CLASS_LAST  AA_CLASS_DOMAIN
+#define AA_CLASS_LAST  AA_CLASS_MOUNT
 
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 9317cd8..0e8689d 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -73,6 +73,10 @@ enum aa_ops {
OP_FMMAP,
OP_FMPROT,
 
+   OP_PIVOTROOT,
+   OP_MOUNT,
+   OP_UMOUNT,
+
OP_CREATE,
OP_POST_CREATE,
OP_BIND,
diff --git a/security/apparmor/include/domain.h 
b/security/apparmor/include/domain.h
index de04464..a3f70c5 100644
--- a/security/apparmor/include/domain.h
+++ b/security/apparmor/include/domain.h
@@ -23,6 +23,8 @@ struct aa_domain {
char **table;
 };
 
+struct aa_profile *x_table_lookup(struct aa_profile *profile, u32 xindex);
+
 int apparmor_bprm_set_creds(struct linux_binprm *bprm);
 int apparmor_bprm_secureexec(struct linux_binprm *bprm);
 void apparmor_bprm_committing_creds(struct linux_binprm *bprm);
diff --git a/security/apparmor/include/mount.h 
b/security/apparmor/include/mount.h
new file mode 100644
index 000..6f936bc
--- /dev/null
+++ b/security/apparmor/include/mount.h
@@ -0,0 +1,53 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor file mediation function definitions.
+ *
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software;

[apparmor] [PATCH 08/16] AppArmor: Update dfa matching routines.

2012-02-22 Thread John Johansen
Update aa_dfa_match so that it doesn't result in an input string being
walked twice (once to get its length and another time to match)

Add a single step functions
  aa_dfa_next

Signed-off-by: John Johansen 
---
 security/apparmor/include/apparmor.h |2 +-
 security/apparmor/include/match.h|3 +
 security/apparmor/match.c|   80 -
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 38ccaea..43cf834 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -81,7 +81,7 @@ static inline unsigned int aa_dfa_null_transition(struct 
aa_dfa *dfa,
  unsigned int start)
 {
/* the null transition only needs the string's null terminator byte */
-   return aa_dfa_match_len(dfa, start, "", 1);
+   return aa_dfa_next(dfa, start, 0);
 }
 
 static inline bool mediated_filesystem(struct inode *inode)
diff --git a/security/apparmor/include/match.h 
b/security/apparmor/include/match.h
index a4a8639..775843e 100644
--- a/security/apparmor/include/match.h
+++ b/security/apparmor/include/match.h
@@ -116,6 +116,9 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned 
int start,
  const char *str, int len);
 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
  const char *str);
+unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
+const char c);
+
 void aa_dfa_free_kref(struct kref *kref);
 
 /**
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index 94de6b4..90971a8 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -335,12 +335,12 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, 
unsigned int start,
 }
 
 /**
- * aa_dfa_next_state - traverse @dfa to find state @str stops at
+ * aa_dfa_match - traverse @dfa to find state @str stops at
  * @dfa: the dfa to match @str against  (NOT NULL)
  * @start: the state of the dfa to start matching in
  * @str: the null terminated string of bytes to match against the dfa (NOT 
NULL)
  *
- * aa_dfa_next_state will match @str against the dfa and return the state it
+ * aa_dfa_match will match @str against the dfa and return the state it
  * finished matching in. The final state can be used to look up the accepting
  * label, or as the start state of a continuing match.
  *
@@ -349,5 +349,79 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned 
int start,
 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
  const char *str)
 {
-   return aa_dfa_match_len(dfa, start, str, strlen(str));
+   u16 *def = DEFAULT_TABLE(dfa);
+   u32 *base = BASE_TABLE(dfa);
+   u16 *next = NEXT_TABLE(dfa);
+   u16 *check = CHECK_TABLE(dfa);
+   unsigned int state = start, pos;
+
+   if (state == 0)
+   return 0;
+
+   /* current state is , matching character *str */
+   if (dfa->tables[YYTD_ID_EC]) {
+   /* Equivalence class table defined */
+   u8 *equiv = EQUIV_TABLE(dfa);
+   /* default is direct to next state */
+   while (*str) {
+   pos = base[state] + equiv[(u8) *str++];
+   if (check[pos] == state)
+   state = next[pos];
+   else
+   state = def[state];
+   }
+   } else {
+   /* default is direct to next state */
+   while (*str) {
+   pos = base[state] + (u8) *str++;
+   if (check[pos] == state)
+   state = next[pos];
+   else
+   state = def[state];
+   }
+   }
+
+   return state;
+}
+
+/**
+ * aa_dfa_next - step one character to the next state in the dfa
+ * @dfa: the dfa to tranverse (NOT NULL)
+ * @state: the state to start in
+ * @c: the input character to transition on
+ *
+ * aa_dfa_match will step through the dfa by one input character @c
+ *
+ * Returns: state reach after input @c
+ */
+unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
+ const char c)
+{
+   u16 *def = DEFAULT_TABLE(dfa);
+   u32 *base = BASE_TABLE(dfa);
+   u16 *next = NEXT_TABLE(dfa);
+   u16 *check = CHECK_TABLE(dfa);
+   unsigned int pos;
+
+   /* current state is , matching character *str */
+   if (dfa->tables[YYTD_ID_EC]) {
+   /* Equivalence class table defined */
+   u8 *equiv = EQUIV_TABLE(dfa);
+   /* default is direct to next state */
+
+   pos = base[state] + equiv[(u8) c];
+   if (check[pos] == state)
+   state = next[pos];
+   else

[apparmor] [PATCH 07/16] AppArmor: Minor cleanup of d_namespace_path to consolidate error handling

2012-02-22 Thread John Johansen
Signed-off-by: John Johansen 
---
 security/apparmor/path.c |   19 +++
 1 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 96fb310..2bda438 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -84,33 +84,28 @@ static int d_namespace_path(struct path *path, char *buf, 
int buflen,
struct path root;
get_fs_root(current->fs, &root);
res = __d_path(path, &root, buf, buflen);
-   if (res && !IS_ERR(res)) {
-   /* everything's fine */
-   *name = res;
-   path_put(&root);
-   goto ok;
-   }
path_put(&root);
-   connected = 0;
-   } else
+   } else {
res = d_absolute_path(path, buf, buflen);
+   if (!our_mnt(path->mnt))
+   connected = 0;
+   }
 
/* handle error conditions - and still allow a partial path to
 * be returned.
 */
-   if (IS_ERR(res)) {
+   if (!res || IS_ERR(res)) {
+   connected = 0;
res = dentry_path_raw(path->dentry, buf, buflen);
if (IS_ERR(res)) {
error = PTR_ERR(res);
*name = buf;
goto out;
};
-} else if (!our_mnt(path->mnt))
-   connected = 0;
+}
 
*name = res;
 
-ok:
/* Handle two cases:
 * 1. A deleted dentry && profile is not allowing mediation of deleted
 * 2. On some filesystems, newly allocated dentries appear to the
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 05/16] AppArmor: Fix the error case for chroot relative path name lookup

2012-02-22 Thread John Johansen
When a chroot relative pathname lookup fails it is falling through to
do a d_absolute_path lookup.  This is incorrect as d_absolute_path should
only be used to lookup names for namespace absolute paths.

Signed-off-by: John Johansen 
---
 security/apparmor/path.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index b566eba..70b09bb 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -92,9 +92,8 @@ static int d_namespace_path(struct path *path, char *buf, int 
buflen,
}
path_put(&root);
connected = 0;
-   }
-
-   res = d_absolute_path(path, buf, buflen);
+   } else
+   res = d_absolute_path(path, buf, buflen);
 
*name = res;
/* handle error conditions - and still allow a partial path to
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 15/16] AppArmor: Add mount information to apparmorfs

2012-02-22 Thread John Johansen
Update the apparmorfs introspection interface to reflect that mount rules
are available.  As part of this change the namespace entry from a binary
file to a directory so it can store interface information for operations
that affect the namespace like pivot_root.

Signed-off-by: John Johansen 
---
 security/apparmor/apparmorfs.c |   13 -
 1 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0cbbfab..d30aa11 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -429,11 +429,22 @@ static struct aa_fs_entry aa_fs_entry_network[] = {
{ }
 };
 
+static struct aa_fs_entry aa_fs_entry_mount[] = {
+   AA_FS_FILE_STRING("mask", "mount umount"),
+   { }
+};
+
+static struct aa_fs_entry aa_fs_entry_namespaces[] = {
+   AA_FS_FILE_BOOLEAN("profile",   1),
+   AA_FS_FILE_BOOLEAN("pivot_root",1),
+};
+
 static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file",   aa_fs_entry_file),
+   AA_FS_DIR("mount",  aa_fs_entry_mount),
AA_FS_DIR("network",aa_fs_entry_network),
-   AA_FS_FILE_BOOLEAN("namespaces",1),
+   AA_FS_DIR("namespaces", aa_fs_entry_namespaces),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
{ }
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 06/16] AppArmor: Retrieve the dentry_path for error reporting when path lookup fails

2012-02-22 Thread John Johansen
When __d_path and d_absolute_path fail due to the name being outside of
the current namespace no name is reported.  Use dentry_path to provide
some hint as to which file was being accessed.

Signed-off-by: John Johansen 
---
 security/apparmor/path.c |   15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 70b09bb..96fb310 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -95,18 +95,21 @@ static int d_namespace_path(struct path *path, char *buf, 
int buflen,
} else
res = d_absolute_path(path, buf, buflen);
 
-   *name = res;
/* handle error conditions - and still allow a partial path to
 * be returned.
 */
if (IS_ERR(res)) {
-   error = PTR_ERR(res);
-   *name = buf;
-   goto out;
-   }
-   if (!our_mnt(path->mnt))
+   res = dentry_path_raw(path->dentry, buf, buflen);
+   if (IS_ERR(res)) {
+   error = PTR_ERR(res);
+   *name = buf;
+   goto out;
+   };
+} else if (!our_mnt(path->mnt))
connected = 0;
 
+   *name = res;
+
 ok:
/* Handle two cases:
 * 1. A deleted dentry && profile is not allowing mediation of deleted
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 12/16] AppArmor: basic networking rules

2012-02-22 Thread John Johansen
Base support for network mediation.

Signed-off-by: John Johansen 
---
 include/linux/lsm_audit.h  |4 +
 security/apparmor/Makefile |   10 ++-
 security/apparmor/apparmorfs.c |6 ++
 security/apparmor/include/net.h|   40 +
 security/apparmor/include/policy.h |3 +
 security/apparmor/lsm.c|  112 +++
 security/apparmor/net.c|  170 
 security/apparmor/policy.c |1 +
 security/apparmor/policy_unpack.c  |   48 ++-
 9 files changed, 390 insertions(+), 4 deletions(-)
 create mode 100644 security/apparmor/include/net.h
 create mode 100644 security/apparmor/net.c

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 88e78de..c63979a 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -124,6 +124,10 @@ struct common_audit_data {
u32 denied;
uid_t ouid;
} fs;
+   struct {
+   int type, protocol;
+   struct sock *sk;
+   } net;
};
} apparmor_audit_data;
 #endif
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 86103ce..96cf725 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -4,10 +4,9 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
 
 apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
   path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-  resource.o sid.o file.o
-
-clean-files := capability_names.h rlim_names.h
+  resource.o sid.o file.o net.o
 
+clean-files := capability_names.h rlim_names.h af_names.h
 
 # Build a lower case string table of capability names
 # Transforms lines from
@@ -20,6 +19,8 @@ cmd_make-caps = echo "static const char *capability_names[] = 
{" > $@ ;\
-e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
echo "};" >> $@
 
+quiet_cmd_make-af = GEN $@
+cmd_make-af = echo "static const char *address_family_names[] = {" > $@ ; sed 
-n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ 
\\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2]  = 
\"\\1\",/p" $< | tr A-Z a-z >> $@ ; echo "};" >> $@
 
 # Build a lower case string table of rlimit names.
 # Transforms lines from
@@ -55,6 +56,7 @@ cmd_make-rlim = echo "static const char 
*rlim_names[RLIM_NLIMITS] = {" > $@ ;\
tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
 
 $(obj)/capability.o : $(obj)/capability_names.h
+$(obj)/net.o : $(obj)/af_names.h
 $(obj)/resource.o : $(obj)/rlim_names.h
 $(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
$(src)/Makefile
@@ -62,3 +64,5 @@ $(obj)/capability_names.h : 
$(srctree)/include/linux/capability.h \
 $(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
  $(src)/Makefile
$(call cmd,make-rlim)
+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
+   $(call cmd,make-af)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 38d6262..4267401 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -198,9 +198,15 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
{ }
 };
 
+static struct aa_fs_entry aa_fs_entry_network[] = {
+   AA_FS_FILE_BOOLEAN("af_masking",1),
+   { }
+};
+
 static struct aa_fs_entry aa_fs_entry_features[] = {
AA_FS_DIR("domain", aa_fs_entry_domain),
AA_FS_DIR("file",   aa_fs_entry_file),
+   AA_FS_DIR("network",aa_fs_entry_network),
AA_FS_FILE_BOOLEAN("namespaces",1),
AA_FS_FILE_U64("capability",VFS_CAP_FLAGS_MASK),
AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
new file mode 100644
index 000..3c7d599
--- /dev/null
+++ b/security/apparmor/include/net.h
@@ -0,0 +1,40 @@
+/*
+ * AppArmor security module
+ *
+ * This file contains AppArmor network mediation definitions.
+ *
+ * Copyright (C) 1998-2008 Novell/SUSE
+ * Copyright 2009-2010 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#ifndef __AA_NET_H
+#define __AA_NET_H
+
+#include 
+
+/* struct aa_net - network confinement data
+ * @allowed: basic network families permissions
+ * @audit_network: which network permissions to force audit
+ * @quiet_network: which network permissions to quiet rejects
+ */
+struct aa_net {
+   u16 all

[apparmor] [PATCH 10/16] AppArmor: Make chroot relative the default path lookup type

2012-02-22 Thread John Johansen
Profiles that want name lookup past the chroot to the namespace root
must be marked as such, all other profiles should be chroot relative.

Currently the autogenerated null (learning), and unconfined  profiles are
not marked as such. Make sure they are properly flagged. This should not
affect behavior except for auto-generated profiles when a chroot is entered.
Profiles loaded from userspace will not be affected as they provide their
own value for the flag.

This change does not affect mediation as it only changes the path reported by
the unconfined (none mediating), an null learning profiles.

Also ensure that if a profile is ever loaded with out path flags set, that
it defaults to being chroot relative.

Signed-off-by: John Johansen 
---
 security/apparmor/policy.c|3 +++
 security/apparmor/policy_unpack.c |3 ++-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 4f0eade..537e5dc 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -655,6 +655,9 @@ struct aa_profile *aa_alloc_profile(const char *hname)
return NULL;
}
 
+   /* default to chroot relative paths */
+   profile->path_flags = PATH_CHROOT_REL;
+
/* refcount released by caller */
return profile;
 }
diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 5c46acf..6137b10 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -25,6 +25,7 @@
 #include "include/audit.h"
 #include "include/context.h"
 #include "include/match.h"
+#include "include/path.h"
 #include "include/policy.h"
 #include "include/policy_unpack.h"
 #include "include/sid.h"
@@ -523,7 +524,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
else
/* set a default value if path_flags field is not present */
-   profile->path_flags = PFLAG_MEDIATE_DELETED;
+   profile->path_flags = PFLAG_MEDIATE_DELETED | PATH_CHROOT_REL;
 
if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
goto fail;
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 09/16] AppArmor: Move path failure information into aa_get_name and rename

2012-02-22 Thread John Johansen
Move the path name lookup failure messages into the main path name lookup
routine, as the information is useful in more than just aa_path_perm.

Also rename aa_get_name to aa_path_name as it is not getting a reference
counted object with a corresponding put fn.

Signed-off-by: John Johansen 
---
 security/apparmor/domain.c   |5 ++---
 security/apparmor/file.c |   18 +++---
 security/apparmor/include/path.h |3 ++-
 security/apparmor/path.c |   22 ++
 4 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c1e18ba..7c69599 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
state = profile->file.start;
 
/* buffer freed below, name is pointer into buffer */
-   error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer,
-   &name);
+   error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
+&name, &info);
if (error) {
if (profile->flags &
(PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
error = 0;
-   info = "Exec failed name resolution";
name = bprm->filename;
goto audit;
}
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index bba875c..3022c0f 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -278,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, 
struct path *path,
int error;
 
flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
-   error = aa_get_name(path, flags, &buffer, &name);
+   error = aa_path_name(path, flags, &buffer, &name, &info);
if (error) {
if (error == -ENOENT && is_deleted(path->dentry)) {
/* Access to open files that are deleted are
 * give a pass (implicit delegation)
 */
error = 0;
+   info = NULL;
perms.allow = request;
-   } else if (error == -ENOENT)
-   info = "Failed name lookup - deleted entry";
-   else if (error == -ESTALE)
-   info = "Failed name lookup - disconnected path";
-   else if (error == -ENAMETOOLONG)
-   info = "Failed name lookup - name too long";
-   else
-   info = "Failed name lookup";
+   }
} else {
aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
 &perms);
@@ -364,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct 
dentry *old_dentry,
lperms = nullperms;
 
/* buffer freed below, lname is pointer in buffer */
-   error = aa_get_name(&link, profile->path_flags, &buffer, &lname);
+   error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
+&info);
if (error)
goto audit;
 
/* buffer2 freed below, tname is pointer in buffer2 */
-   error = aa_get_name(&target, profile->path_flags, &buffer2, &tname);
+   error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
+&info);
if (error)
goto audit;
 
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 27b327a..286ac75 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -26,6 +26,7 @@ enum path_flags {
PATH_MEDIATE_DELETED = 0x1, /* mediate deleted paths */
 };
 
-int aa_get_name(struct path *path, int flags, char **buffer, const char 
**name);
+int aa_path_name(struct path *path, int flags, char **buffer,
+const char **name, const char **info);
 
 #endif /* __AA_PATH_H */
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index 2bda438..e0447c5 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -157,7 +157,7 @@ out:
  * Returns: %0 else error on failure
  */
 static int get_name_to_buffer(struct path *path, int flags, char *buffer,
- int size, char **name)
+ int size, char **name, const char **info)
 {
int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
int error = d_namespace_path(path, buffer, size - adjust, name, flags);
@@ -169,15 +169,27 @@ static int get_name_to_buffer(struct path *path, int 
flags, char *buffer,
 */
strcpy(&buffer[size - 2], "/");
 
+   if (info && error) {
+   if (error == -ENOENT)
+   *info = "Failed name lookup - deleted entry";
+   else if (er

[apparmor] [PATCH 04/16] AppArmor: fix mapping of META_READ to audit and quiet flags

2012-02-22 Thread John Johansen
The mapping of AA_MAY_META_READ for the allow mask was also being mapped
to the audit and quiet masks. This would result in some operations being
audited when the should not.

This flaw was hidden by the previous audit bug which would drop some
messages that where supposed to be audited.

Signed-off-by: John Johansen 
---
 security/apparmor/file.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 7312db7..bba875c 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -173,8 +173,6 @@ static u32 map_old_perms(u32 old)
if (old & 0x40) /* AA_EXEC_MMAP */
new |= AA_EXEC_MMAP;
 
-   new |= AA_MAY_META_READ;
-
return new;
 }
 
@@ -212,6 +210,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, 
unsigned int state,
perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
perms.xindex = dfa_other_xindex(dfa, state);
}
+   perms.allow |= AA_MAY_META_READ;
 
/* change_profile wasn't determined by ownership in old mapping */
if (ACCEPT_TABLE(dfa)[state] & 0x8000)
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 02/16] AppArmor: Fix dropping of allowed operations that are force audited

2012-02-22 Thread John Johansen
The audit permission flag, that specifies an audit message should be
provided when an operation is allowed, was being ignored in some cases.

This is because the auto audit mode (which determines the audit mode from
system flags) was incorrectly assigned the same value as audit mode. The
shared value would result in messages that should be audited going through
a second evaluation as to whether they should be audited based on the
auto audit, resulting in some messages being dropped.

Signed-off-by: John Johansen 
---
 security/apparmor/audit.c |1 +
 security/apparmor/include/audit.h |5 ++---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
index 96502b2..f419e12 100644
--- a/security/apparmor/audit.c
+++ b/security/apparmor/audit.c
@@ -89,6 +89,7 @@ static char *aa_audit_type[] = {
"STATUS",
"ERROR",
"KILLED"
+   "AUTO"
 };
 
 /*
diff --git a/security/apparmor/include/audit.h 
b/security/apparmor/include/audit.h
index 1951786..9317cd8 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -28,8 +28,6 @@ struct aa_profile;
 extern const char *audit_mode_names[];
 #define AUDIT_MAX_INDEX 5
 
-#define AUDIT_APPARMOR_AUTO 0  /* auto choose audit message type */
-
 enum audit_mode {
AUDIT_NORMAL,   /* follow normal auditing of accesses */
AUDIT_QUIET_DENIED, /* quiet all denied access messages */
@@ -45,7 +43,8 @@ enum audit_type {
AUDIT_APPARMOR_HINT,
AUDIT_APPARMOR_STATUS,
AUDIT_APPARMOR_ERROR,
-   AUDIT_APPARMOR_KILL
+   AUDIT_APPARMOR_KILL,
+   AUDIT_APPARMOR_AUTO
 };
 
 extern const char *op_table[];
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 11/16] AppArmor: Add ability to load extended policy

2012-02-22 Thread John Johansen
Add the base support for the new policy extensions. This does not bring
any additional functionality, or change current semantics.

Signed-off-by: John Johansen 
---
 security/apparmor/include/apparmor.h |   13 +
 security/apparmor/include/policy.h   |   13 +
 security/apparmor/policy.c   |1 +
 security/apparmor/policy_unpack.c|   22 ++
 4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/include/apparmor.h 
b/security/apparmor/include/apparmor.h
index 43cf834..9cef358 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -19,6 +19,19 @@
 
 #include "match.h"
 
+/*
+ * Class of mediation types in the AppArmor policy db
+ */
+#define AA_CLASS_ENTRY 0
+#define AA_CLASS_UNKNOWN   1
+#define AA_CLASS_FILE  2
+#define AA_CLASS_CAP   3
+#define AA_CLASS_NET   4
+#define AA_CLASS_RLIMITS   5
+#define AA_CLASS_DOMAIN6
+
+#define AA_CLASS_LAST  AA_CLASS_DOMAIN
+
 /* Control parameters settable through module/boot flags */
 extern enum audit_mode aa_g_audit;
 extern int aa_g_audit_header;
diff --git a/security/apparmor/include/policy.h 
b/security/apparmor/include/policy.h
index aeda5cf..9e18e96 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -129,6 +129,17 @@ struct aa_namespace {
struct list_head sub_ns;
 };
 
+/* struct aa_policydb - match engine for a policy
+ * dfa: dfa pattern match
+ * start: set of start states for the different classes of data
+ */
+struct aa_policydb {
+   /* Generic policy DFA specific rule types will be subsections of it */
+   struct aa_dfa *dfa;
+   unsigned int start[AA_CLASS_LAST + 1];
+
+};
+
 /* struct aa_profile - basic confinement data
  * @base - base components of the profile (name, refcount, lists, lock ...)
  * @parent: parent of profile
@@ -143,6 +154,7 @@ struct aa_namespace {
  * @flags: flags controlling profile behavior
  * @path_flags: flags controlling path generation behavior
  * @size: the memory consumed by this profiles rules
+ * @policy: general match rules governing policy
  * @file: The set of rules governing basic file access and domain transitions
  * @caps: capabilities for the profile
  * @rlimits: rlimits for the profile
@@ -179,6 +191,7 @@ struct aa_profile {
u32 path_flags;
int size;
 
+   struct aa_policydb policy;
struct aa_file_rules file;
struct aa_caps caps;
struct aa_rlimit rlimits;
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 537e5dc..8b7febb 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -752,6 +752,7 @@ static void free_profile(struct aa_profile *profile)
 
aa_free_sid(profile->sid);
aa_put_dfa(profile->xmatch);
+   aa_put_dfa(profile->policy.dfa);
 
aa_put_profile(profile->replacedby);
 
diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 6137b10..c7a6d03 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -562,6 +562,28 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
if (!unpack_rlimits(e, profile))
goto fail;
 
+   if (unpack_nameX(e, AA_STRUCT, "policydb")) {
+   /* generic policy dfa - optional and may be NULL */
+   profile->policy.dfa = unpack_dfa(e);
+   if (IS_ERR(profile->policy.dfa)) {
+   error = PTR_ERR(profile->policy.dfa);
+   profile->policy.dfa = NULL;
+   goto fail;
+   }
+   if (!unpack_u32(e, &profile->policy.start[0], "start"))
+   /* default start state */
+   profile->policy.start[0] = DFA_START;
+   /* setup class index */
+   for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) {
+   profile->policy.start[i] =
+   aa_dfa_next(profile->policy.dfa,
+   profile->policy.start[0],
+   i);
+   }
+   if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+   goto fail;
+   }
+
/* get file rules */
profile->file.dfa = unpack_dfa(e);
if (IS_ERR(profile->file.dfa)) {
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 03/16] AppArmor: Fix underflow in xindex calculation

2012-02-22 Thread John Johansen
If the xindex value stored in the accept tables is 0, the extraction of
that value will result in an underflow (0 - 4).

In properly compiled policy this should not happen for file rules but
it may be possible for other rule types in the future.

To exploit this underflow a user would have to be able to load a corrupt
policy, which requires CAP_MAC_ADMIN, overwrite system policy in kernel
memory or know of a compiler error resulting in the flaw being present
for loaded policy (no such flaw is known at this time).

Signed-off-by: John Johansen 
---
 security/apparmor/include/file.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index ab8c6d8..f98fd47 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -117,7 +117,7 @@ static inline u16 dfa_map_xindex(u16 mask)
index |= AA_X_NAME;
} else if (old_index == 3) {
index |= AA_X_NAME | AA_X_CHILD;
-   } else {
+   } else if (old_index) {
index |= AA_X_TABLE;
index |= old_index - 4;
}
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor


[apparmor] [PATCH 01/16] AppArmor: Add mising end of structure test to caps unpacking

2012-02-22 Thread John Johansen
The unpacking of struct capsx is missing a check for the end of the
caps structure.  This can lead to unpack failures depending on what else
is packed into the policy file being unpacked.

Signed-off-by: John Johansen 
---
 security/apparmor/policy_unpack.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/security/apparmor/policy_unpack.c 
b/security/apparmor/policy_unpack.c
index 741dd13..5c46acf 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -554,6 +554,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
goto fail;
if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
goto fail;
+   if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+   goto fail;
}
 
if (!unpack_rlimits(e, profile))
-- 
1.7.9


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor