From: John Johansen <john.johansen@canonical.com>
To: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: john.johansen@canonical.com,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [AppArmor #4 0/12] AppArmor security module
Date: Tue, 23 Feb 2010 00:38:44 -0800 [thread overview]
Message-ID: <4B839414.90201@canonical.com> (raw)
In-Reply-To: <201002230159.o1N1x07J088559@www262.sakura.ne.jp>
Tetsuo Handa wrote:
> Starting from apparmorfs.c and jumping randomly...
>
>
>
>
>
> 346 static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)(...snipped...)
> 369 /*
> 370 * verify: transition names string
> 371 */
> 372 for (c = j = 0; j < size - 1; j++) {
> 373 if (!str[j])
> 374 c++;
> 375 }
> 376 /* names beginning with : require an embedded \0 */
> 377 if (*str == ':' && c != 1)
> 378 goto fail;
> 379 /* fail - all other cases with embedded \0 */
> 380 else if (c)
> 381 goto fail;
> 382 profile->file.trans.table[i] = str;
> You need to "profile->file.trans.table[i] = str;" before "goto fail;"
> in order to let "aa_free_domain_entries()" to kzfree().
>
>
sigh, yep. You know the depressing thing is I patched that once and seem
to have dropped the fix when I fiddled with the code, again. :(
>
>
>
> 333 static struct aa_namespace *aa_prepare_namespace(const char *name)
> 334 {
> 335 struct aa_namespace *ns, *root;
> 336
> 337 root = aa_current_profile()->ns;
> aa_current_profile() returns NULL if current_cred()->security->profile == NULL.
>
that should never happen anymore, see last comment
> 338
> 339 write_lock(&root->lock);
> 340 if (name)
> 341 /* released by caller */
> 342 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
> 343 else
> 344 /* released by caller */
> 345 ns = aa_get_namespace(root);
> The "if (!ns) { ... } " block is for only name != NULL case because
> aa_alloc_namespace(NULL) returns NULL. Thus, you might want to do like
>
err, no. It is only for if the name is specified and the profile couldn't be
found in
342 ns = aa_get_namespace(__aa_find_namespace(&root->sub_ns, name));
The other case of ns = aa_get_namespace(root); is guaranteed to succeed.
I should move the whole if (!ns) block under if (name)
> else {
> /* released by caller */
> ns = aa_get_namespace(root);
> goto out_unlock;
> }
>
> 369 }
> out_unlock:
> 370 write_unlock(&root->lock);
> 371
> 372 /* return ref */
> 373 return ns;
>
>
>
>
>
> 889 ssize_t aa_interface_replace_profiles(void *udata, size_t size, bool add_only)
> (...snipped...)
> 946 /* must be cleared as it is shared with replaced-by */
> 947 kzfree(new_profile->rename);
> 948 new_profile->rename = NULL;
> Is it OK to clear now because replacement may not be taken place due to
> aa_audit_iface() returning -ENOMEM?
>
yes. The rename field is only used at this one point and the rename profile,
if found is used. However if the rename fails the name of what was to be renamed isn't currently audited and it really should be.
So this should be moved and used as part of auditing.
>
>
>
>
> 108 static const char *hname_tail(const char *hname)
> 109 {
> 110 char *split;
> 111 /* check for namespace which begins with a : and ends with : or \0 */
> 112 hname = strstrip((char *)hname);
> Oops. strstrip() has gone in 2.6.33 .
>
Hrmm, I had missed that. It exists after a fashion as front for strim but
I missed that on my .33 build
>
>
>
>
> 28 static void *kvmalloc(size_t size)
> 29 {
> I think you should return NULL for size == 0.
> kmalloc(0, GFP_KERNEL) returns ZERO_SIZE_PTR, which results in
> copy_from_user(ZERO_SIZE_PTR, userbuf, (size_t) -1)
> at aa_simple_write_to_buffer() if aa_profile_remove() got ((size_t) -1)
> for "size" parameter. This will cause problem if access_ok() check inside
> copy_from_user() is "return 1;".
> 30 void *buffer = kmalloc(size, GFP_KERNEL);
> 31 if (!buffer)
> 32 buffer = vmalloc(size);
> 33 return buffer;
> 34 }
>
agreed, will do
>
>
>
> 1003 ssize_t aa_interface_remove_profiles(char *fqname, size_t size)
> (...snipped...)
> 1027 /* ref count held by cred */
> 1028 root = aa_current_profile()->ns;
> aa_current_profile() may return NULL.
>
see below
>
> 278 static void *p_start(struct seq_file *f, loff_t *pos)
> 279 __acquires(root->lock)
> 280 {
> 281 struct aa_profile *profile = NULL;
> 282 struct aa_namespace *root = aa_current_profile()->ns;
> aa_current_profile() may return NULL.
No, it shouldn't anymore. That is one of the cleanups this round,
I got rid of the use of NULL to represent the unconfined profile.
Previously you would get a mix of "unfilter profiles" where the
unconfined profile was used and post filtered where NULL was used
to represent unconfined. This was because NULL used to be used
to represent unconfined everywhere but with profile namespaces
we need to carry which unconfined profile it is. Getting rid of
the mixed use allowed for several cleanups and made the code
easier to read too.
However I do notice that I missed cleaning up the comment for
aa_current_profile. I will make another pass at all the comments
and see if I missed anything else.
I will also up the policy/context comments to note that the
context should not ever have a NULL value for profile. It should
either be pointing to a confining profile or to the unconfined
profile for the namespace.
As always, thanks for the review Tetsuo
john
next prev parent reply other threads:[~2010-02-23 8:38 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-19 9:36 [AppArmor #4 0/12] AppArmor security module john.johansen
2010-02-19 9:36 ` [PATCH 01/12] Miscellaneous functions and defines needed by AppArmor, including the base path resolution routines john.johansen
2010-02-19 11:03 ` Al Viro
2010-02-20 12:17 ` John Johansen
2010-02-20 17:25 ` John Johansen
2010-02-20 19:10 ` John Johansen
2010-02-20 12:24 ` John Johansen
2010-02-19 9:36 ` [PATCH 02/12] Update kenel audit range comments to show AppArmor's registered range of 1500-1599. This range used to be reserved for LSPP but LSPP uses the SELinux range and the range was given to AppArmor. Patch is not in mainline -- pending AppArmor code submission to lkml john.johansen
2010-02-19 9:36 ` [PATCH 03/12] AppArmor contexts attach profiles and state to tasks, files, etc. when a direct profile reference is not sufficient john.johansen
2010-02-19 9:36 ` [PATCH 04/12] The basic routines and defines for AppArmor policy. AppArmor policy is defined by a few basic components. profiles - the basic unit of confinement contain all the information to enforce policy on a task john.johansen
2010-02-19 9:36 ` [PATCH 05/12] A basic dfa matching engine based off the dfa engine in the Dragon Book. It uses simple row comb compression with a check field john.johansen
2010-02-19 9:36 ` [PATCH 06/12] AppArmor policy is loaded in a platform independent flattened binary stream. Verify and unpack the data converting it to the internal format needed for enforcement john.johansen
2010-02-19 9:36 ` [PATCH 07/12] AppArmor /proc/<pid>/attr/* and apparmorfs interfaces to userspace john.johansen
2010-02-19 9:36 ` [PATCH 08/12] AppArmor: file enforcement routines john.johansen
2010-02-19 9:36 ` [PATCH 09/12] AppArmor ipc, rlimit, network and capability routines john.johansen
2010-02-19 9:36 ` [PATCH 10/12] AppArmor routines for controlling domain transitions john.johansen
2010-02-19 9:36 ` [PATCH 11/12] AppArmor hooks to interface with the LSM, module parameters and initialization john.johansen
2010-02-22 22:14 ` Serge E. Hallyn
2010-02-23 7:58 ` John Johansen
2010-02-19 9:36 ` [PATCH 12/12] Kconfig and Makefiles to enable configuration and building of AppArmor john.johansen
2010-02-22 22:16 ` Serge E. Hallyn
2010-02-23 7:45 ` John Johansen
2010-03-03 7:50 ` Kees Cook
2010-02-23 1:59 ` [AppArmor #4 0/12] AppArmor security module Tetsuo Handa
2010-02-23 8:38 ` John Johansen [this message]
2010-02-23 8:31 ` Tetsuo Handa
2010-02-23 9:17 ` John Johansen
2010-02-26 3:22 ` Tetsuo Handa
2010-02-26 6:31 ` Tetsuo Handa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B839414.90201@canonical.com \
--to=john.johansen@canonical.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox