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

John Johansen john.johansen at canonical.com
Sat Dec 31 20:22:09 UTC 2011


On 12/31/2011 01:07 AM, Kees Cook wrote:
> Since the parser needs to know which rlimits are known to the kernel,
> export the name/value mappings via the "rlimit" subdirectory in the
> securityfs "features" directory.
>
So I have a different concern than Seth's, which may make things easier.

Basically we don't need the rlimit entry #, it doesn't hurt to have it here
it just isn't needed.  The interface defines a fixed ordering, and the kernel
remaps that to its internal order if it needs it.

Sorry I didn't have the specifics earlier, but I had to dig back and refresh
my memory of what was needed.

What we need for rlimits is
- which ones are supported
- whether setting more than the current tasks limit is supported

Currently the rlimit rules control setting only the current tasks rlimits.
But rlimits where extended a while ago to allow setting other tasks limits
as well.

We are going to extend our support with the policy db, providing matching
against the target tasks profile.

I was thinking a mask of the rlimits by name might be sufficient.  It seems
silly to use multiple files for that.

And then we can have another boolean file indicating the extended match support


So now to messing with the spec,

I was thinking perhaps something similar for file and network as well
   a mask of the supported permissions
   and other files for other parts of what is supported

   eg.
   file/
     mask  (exec,read,write,append,link,..)
     owner (true)  #simple ownership test we currently do
     link_pair (true)
     extended_owner (false)  #arbitrary matching against owner info
     ...

   I am still not clear on everything networking will need, I need to look back
   into it more but basically we need to know the different families supported,
   the permission masks, conditionals, maybe which families have extended matching
   (that is which address formats the module understands and can do anything more
    with than the broad matching we currently do).

Hrmm thinking about it some of the conditional matching stuff should probably
be pulled out of file and stuck in a separate directory.  Call it matching or
dfa.
   matching/
     dfa16 - support the newer dfa16 format
     dfa32 - support the newer larger dfa32 format
     diff_encode - support differential encoding
     kernel_var - support kernel vars
     back_refs - support back references
     ..
     owner
     extended owner
     
And while we are at messing with the spec it might be worthwhile grouping all
the domain transition ones together in a dir
   domain/
     change_hat
     change_hatv
     change_profile     
     change_onexec

and in the future we can add stacking etc.


> Signed-off-by: Kees Cook<kees at ubuntu.com>
> ---
>   security/apparmor/Makefile           |    4 ++--
>   security/apparmor/apparmorfs.c       |   19 ++++++++++++++++++-
>   security/apparmor/include/resource.h |    2 ++
>   3 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
> index 2dafe50..b877b4e 100644
> --- a/security/apparmor/Makefile
> +++ b/security/apparmor/Makefile
> @@ -36,11 +36,11 @@ cmd_make-caps = echo "static const char *capability_names[] = {">  $@ ;\
>   # to
>   # RLIMIT_STACK,
>   quiet_cmd_make-rlim = GEN     $@
> -cmd_make-rlim = echo "static const char *rlim_names[] = {">  $@ ;\
> +cmd_make-rlim = echo "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 "};">>  $@
>
> diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
> index e7ed75a..671f412 100644
> --- a/security/apparmor/apparmorfs.c
> +++ b/security/apparmor/apparmorfs.c
> @@ -25,9 +25,11 @@
>   #include "include/audit.h"
>   #include "include/context.h"
>   #include "include/policy.h"
> +#include "include/resource.h"
>
>   enum aa_fs_value {
>   	AA_FS_TYPE_BOOLEAN,
> +	AA_FS_TYPE_INTEGER,
>   	AA_FS_TYPE_U64,
>   	AA_FS_TYPE_FOPS,
>   	AA_FS_TYPE_DIR,
> @@ -42,6 +44,7 @@ struct aa_fs_entry {
>   	enum aa_fs_value v_type;
>   	union {
>   		bool boolean;
> +		int integer;
>   		unsigned long u64;
>   		struct aa_fs_entry *files;
>   	} v;
> @@ -177,6 +180,9 @@ static int aa_fs_seq_show(struct seq_file *seq, void *v)
>   			seq_printf(seq, "%s\n", fs_file->v.boolean ?
>   						"yes" : "no");
>   			break;
> +		case AA_FS_TYPE_INTEGER:
> +			seq_printf(seq, "%d\n", fs_file->v.integer);
> +			break;
>   		case AA_FS_TYPE_U64:
>   			seq_printf(seq, "%#08lx\n", fs_file->v.u64);
>   			break;
> @@ -217,6 +223,8 @@ static const struct file_operations aa_fs_seq_file_ops = {
>   #define AA_FS_DIR(_name, _value) \
>   	{ .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) }
>
> +static struct aa_fs_entry aa_fs_entry_rlimit[RLIM_NLIMITS + 1] = { };
> +
>   static struct aa_fs_entry aa_fs_entry_features[] = {
>   	AA_FS_FILE_BOOLEAN("change_hat",	1),
>   	AA_FS_FILE_BOOLEAN("change_hatv",	1),
> @@ -224,6 +232,7 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
>   	AA_FS_FILE_BOOLEAN("change_profile",	1),
>   	AA_FS_FILE_BOOLEAN("namespaces",	1),
>   	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
> +	AA_FS_DIR("rlimit",			aa_fs_entry_rlimit),
>   	{ }
>   };
>
> @@ -346,7 +355,7 @@ void __init aa_destroy_aafs(void)
>    */
>   int __init aa_create_aafs(void)
>   {
> -	int error;
> +	int error, limit;
>
>   	if (!apparmor_initialized)
>   		return 0;
> @@ -356,6 +365,14 @@ int __init aa_create_aafs(void)
>   		return -EEXIST;
>   	}
>
> +	/* Populate rlimit name table. */
> +	for (limit = 0; limit<  RLIM_NLIMITS; ++limit) {
> +		aa_fs_entry_rlimit[limit].name = rlim_names[limit];
> +		aa_fs_entry_rlimit[limit].v_type = AA_FS_TYPE_INTEGER;
> +		aa_fs_entry_rlimit[limit].v.integer = limit;
> +		aa_fs_entry_rlimit[limit].file_ops =&aa_fs_seq_file_ops;
> +	}
> +
>   	/* Populate fs tree. */
>   	error = aafs_create_dir(&aa_fs_entry, NULL);
>   	if (error)
> diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
> index 02baec7..665c413 100644
> --- a/security/apparmor/include/resource.h
> +++ b/security/apparmor/include/resource.h
> @@ -32,6 +32,8 @@ struct aa_rlimit {
>   	struct rlimit limits[RLIM_NLIMITS];
>   };
>
> +extern const char *rlim_names[RLIM_NLIMITS];
> +
>   int aa_map_resource(int resource);
>   int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
>   		      unsigned int resource, struct rlimit *new_rlim);




More information about the AppArmor mailing list