Linux-audit Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 05/22] audit: Fix sleep in atomic
From: Jan Kara @ 2016-12-23 13:24 UTC (permalink / raw)
  To: Paul Moore
  Cc: Jan Kara, linux-fsdevel, Amir Goldstein, Lino Sanfilippo,
	Miklos Szeredi, linux-audit
In-Reply-To: <CAHC9VhSk+Y5rKpz-JgCZQSk1W3WPeCA9w7tk2HVx2NTeaJRs5g@mail.gmail.com>

On Thu 22-12-16 18:18:36, Paul Moore wrote:
> On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> > Audit tree code was happily adding new notification marks while holding
> > spinlocks. Since fsnotify_add_mark() acquires group->mark_mutex this can
> > lead to sleeping while holding a spinlock, deadlocks due to lock
> > inversion, and probably other fun. Fix the problem by acquiring
> > group->mark_mutex earlier.
> >
> > CC: Paul Moore <paul@paul-moore.com>
> > Signed-off-by: Jan Kara <jack@suse.cz>
> > ---
> >  kernel/audit_tree.c | 13 +++++++++++--
> >  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> [SIDE NOTE: this patch explains your comments and my earlier concern
> about the locked/unlocked variants of fsnotify_add_mark() in
> untag_chunk()]
> 
> Ouch.  Thanks for catching this ... what is your goal with these
> patches, are you targeting this as a fix during the v4.10-rcX cycle?
> If not, any objections if I pull this patch into the audit tree and
> send this to Linus during the v4.10-rcX cycle (assuming it passes
> testing, yadda yadda)?

Sure, go ahead. I plan these patches for the next merge window. So I can
rebase the series once you merge audit fixes...

								Honza
> 
> 
> > diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> > index f3130eb0a4bd..156b6a93f4fc 100644
> > --- a/kernel/audit_tree.c
> > +++ b/kernel/audit_tree.c
> > @@ -231,6 +231,7 @@ static void untag_chunk(struct node *p)
> >         if (size)
> >                 new = alloc_chunk(size);
> >
> > +       mutex_lock(&entry->group->mark_mutex);
> >         spin_lock(&entry->lock);
> >         if (chunk->dead || !entry->inode) {
> >                 spin_unlock(&entry->lock);
> > @@ -258,7 +259,8 @@ static void untag_chunk(struct node *p)
> >         if (!new)
> >                 goto Fallback;
> >
> > -       if (fsnotify_add_mark(&new->mark, entry->group, entry->inode, NULL, 1)) {
> > +       if (fsnotify_add_mark_locked(&new->mark, entry->group, entry->inode,
> > +                                    NULL, 1)) {
> >                 fsnotify_put_mark(&new->mark);
> >                 goto Fallback;
> >         }
> > @@ -309,6 +311,7 @@ static void untag_chunk(struct node *p)
> >         spin_unlock(&hash_lock);
> >         spin_unlock(&entry->lock);
> >  out:
> > +       mutex_unlock(&entry->group->mark_mutex);
> >         fsnotify_put_mark(entry);
> >         spin_lock(&hash_lock);
> >  }
> > @@ -385,17 +388,21 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
> >
> >         chunk_entry = &chunk->mark;
> >
> > +       mutex_lock(&old_entry->group->mark_mutex);
> >         spin_lock(&old_entry->lock);
> >         if (!old_entry->inode) {
> >                 /* old_entry is being shot, lets just lie */
> >                 spin_unlock(&old_entry->lock);
> > +               mutex_unlock(&old_entry->group->mark_mutex);
> >                 fsnotify_put_mark(old_entry);
> >                 free_chunk(chunk);
> >                 return -ENOENT;
> >         }
> >
> > -       if (fsnotify_add_mark(chunk_entry, old_entry->group, old_entry->inode, NULL, 1)) {
> > +       if (fsnotify_add_mark_locked(chunk_entry, old_entry->group,
> > +                                    old_entry->inode, NULL, 1)) {
> >                 spin_unlock(&old_entry->lock);
> > +               mutex_unlock(&old_entry->group->mark_mutex);
> >                 fsnotify_put_mark(chunk_entry);
> >                 fsnotify_put_mark(old_entry);
> >                 return -ENOSPC;
> > @@ -411,6 +418,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
> >                 chunk->dead = 1;
> >                 spin_unlock(&chunk_entry->lock);
> >                 spin_unlock(&old_entry->lock);
> > +               mutex_unlock(&old_entry->group->mark_mutex);
> >
> >                 fsnotify_destroy_mark(chunk_entry, audit_tree_group);
> >
> > @@ -443,6 +451,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
> >         spin_unlock(&hash_lock);
> >         spin_unlock(&chunk_entry->lock);
> >         spin_unlock(&old_entry->lock);
> > +       mutex_unlock(&old_entry->group->mark_mutex);
> >         fsnotify_destroy_mark(old_entry, audit_tree_group);
> >         fsnotify_put_mark(chunk_entry); /* drop initial reference */
> >         fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
> > --
> > 2.10.2
> >
> 
> 
> 
> -- 
> paul moore
> www.paul-moore.com
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* Re: [PATCH 04/22] fsnotify: Remove fsnotify_duplicate_mark()
From: Jan Kara @ 2016-12-23 13:22 UTC (permalink / raw)
  To: Paul Moore
  Cc: Jan Kara, linux-fsdevel, Amir Goldstein, Lino Sanfilippo,
	Miklos Szeredi, linux-audit
In-Reply-To: <CAHC9VhSAsG3bEi1f+7YO7DPgD0LLytRVRN1Ej_g6kjxVBQ5XKw@mail.gmail.com>

On Thu 22-12-16 18:13:11, Paul Moore wrote:
> On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> > There are only two calls sites of fsnotify_duplicate_mark(). Those are
> > in kernel/audit_tree.c and both are bogus. Vfsmount pointer is unused
> > for audit tree, inode pointer and group gets set in
> > fsnotify_add_mark_locked() later anyway, mask and free_mark are already
> > set in alloc_chunk(). In fact, calling fsnotify_duplicate_mark() is
> > actively harmful because following fsnotify_add_mark_locked() will leak
> > group reference by overwriting the group pointer. So just remove the two
> > calls to fsnotify_duplicate_mark() and the function.
> >
> > Signed-off-by: Jan Kara <jack@suse.cz>
> > ---
> >  fs/notify/mark.c                 | 12 ------------
> >  include/linux/fsnotify_backend.h |  2 --
> >  kernel/audit_tree.c              |  6 ++----
> >  3 files changed, 2 insertions(+), 18 deletions(-)
> 
> At first glance this looks reasonable, although you keep mentioning
> "fsnotify_add_mark_locked" above when untag_chunk() is calling
> "fsnotify_add_mark"; I just wanted to make sure you hadn't intended to
> take the mutex in the audit code instead of relying on the locking in
> fsnotify_add_mark().

No, I didn't want to take mutex in the audit code. It is just that
fsnotify_add_mark() is a thin wrapper around fsnotify_add_mark_locked() so
I was speaking about that function.

								Honza

> 
> > diff --git a/fs/notify/mark.c b/fs/notify/mark.c
> > index d3fea0bd89e2..6043306e8e21 100644
> > --- a/fs/notify/mark.c
> > +++ b/fs/notify/mark.c
> > @@ -510,18 +510,6 @@ void fsnotify_detach_group_marks(struct fsnotify_group *group)
> >         }
> >  }
> >
> > -void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old)
> > -{
> > -       assert_spin_locked(&old->lock);
> > -       new->inode = old->inode;
> > -       new->mnt = old->mnt;
> > -       if (old->group)
> > -               fsnotify_get_group(old->group);
> > -       new->group = old->group;
> > -       new->mask = old->mask;
> > -       new->free_mark = old->free_mark;
> > -}
> > -
> >  /*
> >   * Nothing fancy, just initialize lists and locks and counters.
> >   */
> > diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> > index 0cf34d6cc253..487246546ebe 100644
> > --- a/include/linux/fsnotify_backend.h
> > +++ b/include/linux/fsnotify_backend.h
> > @@ -323,8 +323,6 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(str
> >  extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode);
> >  /* find (and take a reference) to a mark associated with group and vfsmount */
> >  extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt);
> > -/* copy the values from old into new */
> > -extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);
> >  /* set the ignored_mask of a mark */
> >  extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask);
> >  /* set the mask of a mark (might pin the object into memory */
> > diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> > index 8b1dde96a0fa..f3130eb0a4bd 100644
> > --- a/kernel/audit_tree.c
> > +++ b/kernel/audit_tree.c
> > @@ -258,8 +258,7 @@ static void untag_chunk(struct node *p)
> >         if (!new)
> >                 goto Fallback;
> >
> > -       fsnotify_duplicate_mark(&new->mark, entry);
> > -       if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, NULL, 1)) {
> > +       if (fsnotify_add_mark(&new->mark, entry->group, entry->inode, NULL, 1)) {
> >                 fsnotify_put_mark(&new->mark);
> >                 goto Fallback;
> >         }
> > @@ -395,8 +394,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
> >                 return -ENOENT;
> >         }
> >
> > -       fsnotify_duplicate_mark(chunk_entry, old_entry);
> > -       if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, NULL, 1)) {
> > +       if (fsnotify_add_mark(chunk_entry, old_entry->group, old_entry->inode, NULL, 1)) {
> >                 spin_unlock(&old_entry->lock);
> >                 fsnotify_put_mark(chunk_entry);
> >                 fsnotify_put_mark(old_entry);
> > --
> > 2.10.2
> >
> 
> -- 
> paul moore
> www.paul-moore.com
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply

* Re: [PATCH 06/22] audit: Abstract hash key handling
From: Paul Moore @ 2016-12-22 23:27 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, Amir Goldstein, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <20161222091538.28702-7-jack@suse.cz>

On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> Audit tree currently uses inode pointer as a key into the hash table.
> Getting that from notification mark will be somewhat more difficult with
> coming fsnotify changes and there's no reason we really have to use the
> inode pointer. So abstract getting of hash key from the audit chunk and
> inode so that we can switch to a different key easily later.
>
> CC: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  kernel/audit_tree.c | 39 ++++++++++++++++++++++++++++-----------
>  1 file changed, 28 insertions(+), 11 deletions(-)

I have no objections with this patch in particular, but in patch 8,
are you certain that inode_to_key() and chunk_to_key() will continue
to return the same key value?

> diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> index 156b6a93f4fc..f0859828de09 100644
> --- a/kernel/audit_tree.c
> +++ b/kernel/audit_tree.c
> @@ -163,33 +163,48 @@ enum {HASH_SIZE = 128};
>  static struct list_head chunk_hash_heads[HASH_SIZE];
>  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
>
> -static inline struct list_head *chunk_hash(const struct inode *inode)
> +/* Function to return search key in our hash from inode. */
> +static unsigned long inode_to_key(const struct inode *inode)
>  {
> -       unsigned long n = (unsigned long)inode / L1_CACHE_BYTES;
> +       return (unsigned long)inode;
> +}
> +
> +/*
> + * Function to return search key in our hash from chunk. Key 0 is special and
> + * should never be present in the hash.
> + */
> +static unsigned long chunk_to_key(struct audit_chunk *chunk)
> +{
> +       return (unsigned long)chunk->mark.inode;
> +}
> +
> +static inline struct list_head *chunk_hash(unsigned long key)
> +{
> +       unsigned long n = key / L1_CACHE_BYTES;
>         return chunk_hash_heads + n % HASH_SIZE;
>  }
>
>  /* hash_lock & entry->lock is held by caller */
>  static void insert_hash(struct audit_chunk *chunk)
>  {
> -       struct fsnotify_mark *entry = &chunk->mark;
> +       unsigned long key = chunk_to_key(chunk);
>         struct list_head *list;
>
> -       if (!entry->inode)
> +       if (!key)
>                 return;
> -       list = chunk_hash(entry->inode);
> +       list = chunk_hash(key);
>         list_add_rcu(&chunk->hash, list);
>  }
>
>  /* called under rcu_read_lock */
>  struct audit_chunk *audit_tree_lookup(const struct inode *inode)
>  {
> -       struct list_head *list = chunk_hash(inode);
> +       unsigned long key = inode_to_key(inode);
> +       struct list_head *list = chunk_hash(key);
>         struct audit_chunk *p;
>
>         list_for_each_entry_rcu(p, list, hash) {
> -               /* mark.inode may have gone NULL, but who cares? */
> -               if (p->mark.inode == inode) {
> +               if (chunk_to_key(p) == key) {
>                         atomic_long_inc(&p->refs);
>                         return p;
>                 }
> @@ -585,7 +600,8 @@ int audit_remove_tree_rule(struct audit_krule *rule)
>
>  static int compare_root(struct vfsmount *mnt, void *arg)
>  {
> -       return d_backing_inode(mnt->mnt_root) == arg;
> +       return inode_to_key(d_backing_inode(mnt->mnt_root)) ==
> +              (unsigned long)arg;
>  }
>
>  void audit_trim_trees(void)
> @@ -620,9 +636,10 @@ void audit_trim_trees(void)
>                 list_for_each_entry(node, &tree->chunks, list) {
>                         struct audit_chunk *chunk = find_chunk(node);
>                         /* this could be NULL if the watch is dying else where... */
> -                       struct inode *inode = chunk->mark.inode;
>                         node->index |= 1U<<31;
> -                       if (iterate_mounts(compare_root, inode, root_mnt))
> +                       if (iterate_mounts(compare_root,
> +                                          (void *)chunk_to_key(chunk),
> +                                          root_mnt))
>                                 node->index &= ~(1U<<31);
>                 }
>                 spin_unlock(&hash_lock);
> --
> 2.10.2
>



-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH 05/22] audit: Fix sleep in atomic
From: Paul Moore @ 2016-12-22 23:18 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, Amir Goldstein, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <20161222091538.28702-6-jack@suse.cz>

On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> Audit tree code was happily adding new notification marks while holding
> spinlocks. Since fsnotify_add_mark() acquires group->mark_mutex this can
> lead to sleeping while holding a spinlock, deadlocks due to lock
> inversion, and probably other fun. Fix the problem by acquiring
> group->mark_mutex earlier.
>
> CC: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  kernel/audit_tree.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)

[SIDE NOTE: this patch explains your comments and my earlier concern
about the locked/unlocked variants of fsnotify_add_mark() in
untag_chunk()]

Ouch.  Thanks for catching this ... what is your goal with these
patches, are you targeting this as a fix during the v4.10-rcX cycle?
If not, any objections if I pull this patch into the audit tree and
send this to Linus during the v4.10-rcX cycle (assuming it passes
testing, yadda yadda)?

> diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> index f3130eb0a4bd..156b6a93f4fc 100644
> --- a/kernel/audit_tree.c
> +++ b/kernel/audit_tree.c
> @@ -231,6 +231,7 @@ static void untag_chunk(struct node *p)
>         if (size)
>                 new = alloc_chunk(size);
>
> +       mutex_lock(&entry->group->mark_mutex);
>         spin_lock(&entry->lock);
>         if (chunk->dead || !entry->inode) {
>                 spin_unlock(&entry->lock);
> @@ -258,7 +259,8 @@ static void untag_chunk(struct node *p)
>         if (!new)
>                 goto Fallback;
>
> -       if (fsnotify_add_mark(&new->mark, entry->group, entry->inode, NULL, 1)) {
> +       if (fsnotify_add_mark_locked(&new->mark, entry->group, entry->inode,
> +                                    NULL, 1)) {
>                 fsnotify_put_mark(&new->mark);
>                 goto Fallback;
>         }
> @@ -309,6 +311,7 @@ static void untag_chunk(struct node *p)
>         spin_unlock(&hash_lock);
>         spin_unlock(&entry->lock);
>  out:
> +       mutex_unlock(&entry->group->mark_mutex);
>         fsnotify_put_mark(entry);
>         spin_lock(&hash_lock);
>  }
> @@ -385,17 +388,21 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
>
>         chunk_entry = &chunk->mark;
>
> +       mutex_lock(&old_entry->group->mark_mutex);
>         spin_lock(&old_entry->lock);
>         if (!old_entry->inode) {
>                 /* old_entry is being shot, lets just lie */
>                 spin_unlock(&old_entry->lock);
> +               mutex_unlock(&old_entry->group->mark_mutex);
>                 fsnotify_put_mark(old_entry);
>                 free_chunk(chunk);
>                 return -ENOENT;
>         }
>
> -       if (fsnotify_add_mark(chunk_entry, old_entry->group, old_entry->inode, NULL, 1)) {
> +       if (fsnotify_add_mark_locked(chunk_entry, old_entry->group,
> +                                    old_entry->inode, NULL, 1)) {
>                 spin_unlock(&old_entry->lock);
> +               mutex_unlock(&old_entry->group->mark_mutex);
>                 fsnotify_put_mark(chunk_entry);
>                 fsnotify_put_mark(old_entry);
>                 return -ENOSPC;
> @@ -411,6 +418,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
>                 chunk->dead = 1;
>                 spin_unlock(&chunk_entry->lock);
>                 spin_unlock(&old_entry->lock);
> +               mutex_unlock(&old_entry->group->mark_mutex);
>
>                 fsnotify_destroy_mark(chunk_entry, audit_tree_group);
>
> @@ -443,6 +451,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
>         spin_unlock(&hash_lock);
>         spin_unlock(&chunk_entry->lock);
>         spin_unlock(&old_entry->lock);
> +       mutex_unlock(&old_entry->group->mark_mutex);
>         fsnotify_destroy_mark(old_entry, audit_tree_group);
>         fsnotify_put_mark(chunk_entry); /* drop initial reference */
>         fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
> --
> 2.10.2
>



-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH 04/22] fsnotify: Remove fsnotify_duplicate_mark()
From: Paul Moore @ 2016-12-22 23:13 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, Amir Goldstein, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <20161222091538.28702-5-jack@suse.cz>

On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> There are only two calls sites of fsnotify_duplicate_mark(). Those are
> in kernel/audit_tree.c and both are bogus. Vfsmount pointer is unused
> for audit tree, inode pointer and group gets set in
> fsnotify_add_mark_locked() later anyway, mask and free_mark are already
> set in alloc_chunk(). In fact, calling fsnotify_duplicate_mark() is
> actively harmful because following fsnotify_add_mark_locked() will leak
> group reference by overwriting the group pointer. So just remove the two
> calls to fsnotify_duplicate_mark() and the function.
>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  fs/notify/mark.c                 | 12 ------------
>  include/linux/fsnotify_backend.h |  2 --
>  kernel/audit_tree.c              |  6 ++----
>  3 files changed, 2 insertions(+), 18 deletions(-)

At first glance this looks reasonable, although you keep mentioning
"fsnotify_add_mark_locked" above when untag_chunk() is calling
"fsnotify_add_mark"; I just wanted to make sure you hadn't intended to
take the mutex in the audit code instead of relying on the locking in
fsnotify_add_mark().

> diff --git a/fs/notify/mark.c b/fs/notify/mark.c
> index d3fea0bd89e2..6043306e8e21 100644
> --- a/fs/notify/mark.c
> +++ b/fs/notify/mark.c
> @@ -510,18 +510,6 @@ void fsnotify_detach_group_marks(struct fsnotify_group *group)
>         }
>  }
>
> -void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old)
> -{
> -       assert_spin_locked(&old->lock);
> -       new->inode = old->inode;
> -       new->mnt = old->mnt;
> -       if (old->group)
> -               fsnotify_get_group(old->group);
> -       new->group = old->group;
> -       new->mask = old->mask;
> -       new->free_mark = old->free_mark;
> -}
> -
>  /*
>   * Nothing fancy, just initialize lists and locks and counters.
>   */
> diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> index 0cf34d6cc253..487246546ebe 100644
> --- a/include/linux/fsnotify_backend.h
> +++ b/include/linux/fsnotify_backend.h
> @@ -323,8 +323,6 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(str
>  extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode);
>  /* find (and take a reference) to a mark associated with group and vfsmount */
>  extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt);
> -/* copy the values from old into new */
> -extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);
>  /* set the ignored_mask of a mark */
>  extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask);
>  /* set the mask of a mark (might pin the object into memory */
> diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
> index 8b1dde96a0fa..f3130eb0a4bd 100644
> --- a/kernel/audit_tree.c
> +++ b/kernel/audit_tree.c
> @@ -258,8 +258,7 @@ static void untag_chunk(struct node *p)
>         if (!new)
>                 goto Fallback;
>
> -       fsnotify_duplicate_mark(&new->mark, entry);
> -       if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, NULL, 1)) {
> +       if (fsnotify_add_mark(&new->mark, entry->group, entry->inode, NULL, 1)) {
>                 fsnotify_put_mark(&new->mark);
>                 goto Fallback;
>         }
> @@ -395,8 +394,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
>                 return -ENOENT;
>         }
>
> -       fsnotify_duplicate_mark(chunk_entry, old_entry);
> -       if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, NULL, 1)) {
> +       if (fsnotify_add_mark(chunk_entry, old_entry->group, old_entry->inode, NULL, 1)) {
>                 spin_unlock(&old_entry->lock);
>                 fsnotify_put_mark(chunk_entry);
>                 fsnotify_put_mark(old_entry);
> --
> 2.10.2
>

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH 0/22] fsnotify: Avoid SRCU stalls with fanotify permission events
From: Paul Moore @ 2016-12-22 23:04 UTC (permalink / raw)
  To: Amir Goldstein
  Cc: Jan Kara, linux-fsdevel, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <CAOQ4uxiOEmZvEijOKCUmHpjkzmQUV5S1ELoQin8j9ri-dkkOyQ@mail.gmail.com>

On Thu, Dec 22, 2016 at 4:05 PM, Amir Goldstein <amir73il@gmail.com> wrote:
> On Thu, Dec 22, 2016 at 10:58 PM, Paul Moore <paul@paul-moore.com> wrote:
>> On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
>>> Hello,
>>>
>>> currently, fanotify waits for response to a permission even from userspace
>>> process while holding fsnotify_mark_srcu lock. That has a consequence that
>>> when userspace process takes long to respond or does not respond at all,
>>> fsnotify_mark_srcu period cannot ever complete blocking reclaim of any
>>> notification marks and also blocking any process that did synchronize_srcu()
>>> on fsnotify_mark_srcu. Effectively, this eventually blocks anybody interacting
>>> with the notification subsystem. Miklos has some real world reports of this
>>> happening. Although this in principle a problem of broken userspace
>>> application (which futhermore has to have CAP_SYS_ADMIN in init_user_ns, so
>>> it is not a security problem), it is still nasty that a simple error can
>>> block the kernel like this.
>>>
>>> This patch set solves this problem ...
>>>
>>> Patches have survived testing with inotify/fanotify tests in LTP. I didn't test
>>> audit - Paul can you give these patches some testing?  Since some of the
>>> changes are really non-trivial, I'd welcome if someone reviewed the patch set.
>>
>> I'm going to take a look at the audit related patches right now,
>> expect some feedback shortly.
>>
>> In the meantime, if you wanted to play a bit with some simple audit
>> regression tests, check out the testsuite below:
>>
>> * https://github.com/linux-audit/audit-testsuite
>>
>> ... it is still rather simplistic, but the tests in tests/file_* and
>> tests/exec_name should do some basic exercises of the audit code that
>> leverages fsnotify.  If nothing else, it should give you some ideas
>> about how you might stress this a bit more with audit.
>
> Mmm that's interesting. I was looking for a good place to start with a proper
> testsuite for fsnotify.
> It seems like the 2 subsystems could use the same testsuite.
>
> I will look into it.
>
> Thanks!

No problem, I'm glad it's helpful.

FWIW, it's based off ideas from the selinux-testsuite (link below);
the general motivation being a quick and easy regression test that can
be used to verify patches and general upstream development.

* https://github.com/SELinuxProject/selinux-testsuite

In addition to individual commit testing, I've combined both the audit
and SELinux testsuites with a semi-automated weekly kernel build to
test both the -rcX releases as well the selinux/next and audit/next
branches; it's proved quite beneficial.  In case you're curious, I did
a short presentation on it this summer (slides and video at the link
below).  If you are interested, I'm happy to talk about it further,
but perhaps in another thread - I don't want to hijack Jan's patchset
with marginally relevant testing discussion :)

* http://www.paul-moore.com/blog/d/2016/08/flock-kernel-testing.html

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH 0/22] fsnotify: Avoid SRCU stalls with fanotify permission events
From: Amir Goldstein @ 2016-12-22 21:05 UTC (permalink / raw)
  To: Paul Moore
  Cc: Jan Kara, linux-fsdevel, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <CAHC9VhTscoiyBaSrRXG_PT2qGL=TiN4mdj2qv=oUnWW5eTPMPg@mail.gmail.com>

On Thu, Dec 22, 2016 at 10:58 PM, Paul Moore <paul@paul-moore.com> wrote:
> On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
>> Hello,
>>
>> currently, fanotify waits for response to a permission even from userspace
>> process while holding fsnotify_mark_srcu lock. That has a consequence that
>> when userspace process takes long to respond or does not respond at all,
>> fsnotify_mark_srcu period cannot ever complete blocking reclaim of any
>> notification marks and also blocking any process that did synchronize_srcu()
>> on fsnotify_mark_srcu. Effectively, this eventually blocks anybody interacting
>> with the notification subsystem. Miklos has some real world reports of this
>> happening. Although this in principle a problem of broken userspace
>> application (which futhermore has to have CAP_SYS_ADMIN in init_user_ns, so
>> it is not a security problem), it is still nasty that a simple error can
>> block the kernel like this.
>>
>> This patch set solves this problem ...
>>
>> Patches have survived testing with inotify/fanotify tests in LTP. I didn't test
>> audit - Paul can you give these patches some testing?  Since some of the
>> changes are really non-trivial, I'd welcome if someone reviewed the patch set.
>
> I'm going to take a look at the audit related patches right now,
> expect some feedback shortly.
>
> In the meantime, if you wanted to play a bit with some simple audit
> regression tests, check out the testsuite below:
>
> * https://github.com/linux-audit/audit-testsuite
>
> ... it is still rather simplistic, but the tests in tests/file_* and
> tests/exec_name should do some basic exercises of the audit code that
> leverages fsnotify.  If nothing else, it should give you some ideas
> about how you might stress this a bit more with audit.
>


Mmm that's interesting. I was looking for a good place to start with a proper
testsuite for fsnotify.
It seems like the 2 subsystems could use the same testsuite.

I will look into it.

Thanks!

^ permalink raw reply

* Re: [PATCH 0/22] fsnotify: Avoid SRCU stalls with fanotify permission events
From: Paul Moore @ 2016-12-22 20:58 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, Amir Goldstein, Lino Sanfilippo, Miklos Szeredi,
	linux-audit
In-Reply-To: <20161222091538.28702-1-jack@suse.cz>

On Thu, Dec 22, 2016 at 4:15 AM, Jan Kara <jack@suse.cz> wrote:
> Hello,
>
> currently, fanotify waits for response to a permission even from userspace
> process while holding fsnotify_mark_srcu lock. That has a consequence that
> when userspace process takes long to respond or does not respond at all,
> fsnotify_mark_srcu period cannot ever complete blocking reclaim of any
> notification marks and also blocking any process that did synchronize_srcu()
> on fsnotify_mark_srcu. Effectively, this eventually blocks anybody interacting
> with the notification subsystem. Miklos has some real world reports of this
> happening. Although this in principle a problem of broken userspace
> application (which futhermore has to have CAP_SYS_ADMIN in init_user_ns, so
> it is not a security problem), it is still nasty that a simple error can
> block the kernel like this.
>
> This patch set solves this problem ...
>
> Patches have survived testing with inotify/fanotify tests in LTP. I didn't test
> audit - Paul can you give these patches some testing?  Since some of the
> changes are really non-trivial, I'd welcome if someone reviewed the patch set.

I'm going to take a look at the audit related patches right now,
expect some feedback shortly.

In the meantime, if you wanted to play a bit with some simple audit
regression tests, check out the testsuite below:

* https://github.com/linux-audit/audit-testsuite

... it is still rather simplistic, but the tests in tests/file_* and
tests/exec_name should do some basic exercises of the audit code that
leverages fsnotify.  If nothing else, it should give you some ideas
about how you might stress this a bit more with audit.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH 1/2] selinux: log errors when loading new policy
From: Gary Tierney @ 2016-12-19 16:00 UTC (permalink / raw)
  To: sds; +Cc: selinux, linux-audit
In-Reply-To: <1482161529.28570.25.camel@tycho.nsa.gov>

On Mon, Dec 19, 2016 at 10:32:09AM -0500, Stephen Smalley wrote:
> On Mon, 2016-12-19 at 15:19 +0000, Gary Tierney wrote:
> > On Mon, Dec 19, 2016 at 09:43:06AM -0500, Stephen Smalley wrote:
> > > 
> > > On Sat, 2016-12-17 at 20:48 +0000, Gary Tierney wrote:
> > > > 
> > > > Adds error and warning messages to the codepaths which can fail
> > > > when
> > > > loading a new policy.  If a policy fails to load, an error
> > > > message
> > > > will
> > > > be printed to dmesg with a description of what
> > > > failed.  Previously if
> > > > there was an error during policy loading there would be no
> > > > indication
> > > > that it failed.
> > > > 
> > > > Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
> > > > ---
> > > >  security/selinux/selinuxfs.c | 26 +++++++++++++++++++++-----
> > > >  1 file changed, 21 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/security/selinux/selinuxfs.c
> > > > b/security/selinux/selinuxfs.c
> > > > index 0aac402..2139cc7 100644
> > > > --- a/security/selinux/selinuxfs.c
> > > > +++ b/security/selinux/selinuxfs.c
> > > > @@ -522,20 +522,32 @@ static ssize_t sel_write_load(struct file
> > > > *file, const char __user *buf,
> > > >  		goto out;
> > > >  
> > > >  	length = security_load_policy(data, count);
> > > > -	if (length)
> > > > +	if (length) {
> > > > +		pr_err("SELinux: %s: failed to load policy\n",
> > > > +		      __func__);
> > > 
> > > Not sure about your usage of pr_err() vs pr_warn();
> > > security_load_policy() may simply fail due to invalid policy from
> > > userspace, not a kernel-internal error per se.
> > > 
> > 
> > The intention was to make a distinction between failures on or after
> > security_load_policy().  If security_load_policy() fails then no
> > audit message
> > will be logged about loading a new policy, so it seemed more
> > appropriate to
> > treat that case as KERN_ERROR.  Though with what you said in mind, it
> > is
> > probably better to change this to pr_warn() as security_load_policy()
> > is
> > unlikely to cause an actual kernel-internal error.
> 
> Yes, I tend to view them in the reverse; a failure on
> security_load_policy() is just a typical userspace-induced (or OOM)
> failure, whereas failure on any of the later calls will leave the
> kernel in an inconsistent internal state, so if anything, those should
> be the pr_err() cases instead, while security_load_policy() failure
> might even need/want a pr_warn_ratelimited() since it can be induced by
> userspace (albeit only root with :security load_policy permission).
> 

Noted.

> > 
> > > 
> > > I would tend to omit the function name; I don't think it is
> > > especially
> > > helpful.
> > > 
> > 
> > Agreed.  It seems to be used as a convention throughout
> > security/selinux,
> > though am happy to drop it from the patch.
> > 
> > I was planning to send a v2 with pr_err() swapped for pr_warn() and
> > __func__
> > dropped from the log message, though keeping in mind that Steve has
> > prepared a
> > patch for this (also, logging to the audit subsystem might be more
> > appropriate) would it be better to drop #1 and keep #2?
> 
> Not sure - I'd have to see Steve's patch or at least hear more details
> from him to know whether his patch would obsolete yours or just
> complement it.
> 

Right, I'll spin up a v2 with the recommended changes and CC in Steve for his
feedback.

> > 
> > > 
> > > There was an earlier discussion about augmenting the audit logging
> > > from
> > > this function, so this might overlap with that.  I don't know where
> > > that stands.
> > > 
> > > > 
> > > >  		goto out;
> > > > +	}
> > > >  
> > > >  	length = sel_make_bools();
> > > > -	if (length)
> > > > +	if (length) {
> > > > +		pr_warn("SELinux: %s: failed to load policy
> > > > booleans\n",
> > > > +		       __func__);
> > > >  		goto out1;
> > > > +	}
> > > >  
> > > >  	length = sel_make_classes();
> > > > -	if (length)
> > > > +	if (length) {
> > > > +		pr_warn("SELinux: %s: failed to load policy
> > > > classes\n",
> > > > +		       __func__);
> > > >  		goto out1;
> > > > +	}
> > > >  
> > > >  	length = sel_make_policycap();
> > > > -	if (length)
> > > > +	if (length) {
> > > > +		pr_warn("SELinux: %s: failed to load policy
> > > > capabilities\n",
> > > > +		       __func__);
> > > >  		goto out1;
> > > > +	}
> > > >  
> > > >  	length = count;
> > > >  
> > > > @@ -1299,9 +1311,13 @@ static int sel_make_bools(void)
> > > >  
> > > >  		isec = (struct inode_security_struct *)inode-
> > > > > 
> > > > > i_security;
> > > >  		ret = security_genfs_sid("selinuxfs", page,
> > > > SECCLASS_FILE, &sid);
> > > > -		if (ret)
> > > > +		if (ret) {
> > > > +			pr_warn_ratelimited("SELinux: %s: failed
> > > > to
> > > > lookup sid for %s\n",
> > > > +					   __func__, page);
> > > >  			goto out;
> > > >  
> > > > +		}
> > > > +
> > > >  		isec->sid = sid;
> > > >  		isec->initialized = LABEL_INITIALIZED;
> > > >  		inode->i_fop = &sel_bool_ops;
> > 

-- 
Gary Tierney

GPG fingerprint: 412C 0EF9 C305 68E6 B660  BDAF 706E D765 85AA 79D8
https://sks-keyservers.net/pks/lookup?op=get&search=0x706ED76585AA79D8

^ permalink raw reply

* Re: [PATCH 1/2] selinux: log errors when loading new policy
From: Stephen Smalley @ 2016-12-19 15:32 UTC (permalink / raw)
  To: Gary Tierney; +Cc: selinux, linux-audit
In-Reply-To: <20161219151946.GA5359@workstation>

On Mon, 2016-12-19 at 15:19 +0000, Gary Tierney wrote:
> On Mon, Dec 19, 2016 at 09:43:06AM -0500, Stephen Smalley wrote:
> > 
> > On Sat, 2016-12-17 at 20:48 +0000, Gary Tierney wrote:
> > > 
> > > Adds error and warning messages to the codepaths which can fail
> > > when
> > > loading a new policy.  If a policy fails to load, an error
> > > message
> > > will
> > > be printed to dmesg with a description of what
> > > failed.  Previously if
> > > there was an error during policy loading there would be no
> > > indication
> > > that it failed.
> > > 
> > > Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
> > > ---
> > >  security/selinux/selinuxfs.c | 26 +++++++++++++++++++++-----
> > >  1 file changed, 21 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/security/selinux/selinuxfs.c
> > > b/security/selinux/selinuxfs.c
> > > index 0aac402..2139cc7 100644
> > > --- a/security/selinux/selinuxfs.c
> > > +++ b/security/selinux/selinuxfs.c
> > > @@ -522,20 +522,32 @@ static ssize_t sel_write_load(struct file
> > > *file, const char __user *buf,
> > >  		goto out;
> > >  
> > >  	length = security_load_policy(data, count);
> > > -	if (length)
> > > +	if (length) {
> > > +		pr_err("SELinux: %s: failed to load policy\n",
> > > +		      __func__);
> > 
> > Not sure about your usage of pr_err() vs pr_warn();
> > security_load_policy() may simply fail due to invalid policy from
> > userspace, not a kernel-internal error per se.
> > 
> 
> The intention was to make a distinction between failures on or after
> security_load_policy().  If security_load_policy() fails then no
> audit message
> will be logged about loading a new policy, so it seemed more
> appropriate to
> treat that case as KERN_ERROR.  Though with what you said in mind, it
> is
> probably better to change this to pr_warn() as security_load_policy()
> is
> unlikely to cause an actual kernel-internal error.

Yes, I tend to view them in the reverse; a failure on
security_load_policy() is just a typical userspace-induced (or OOM)
failure, whereas failure on any of the later calls will leave the
kernel in an inconsistent internal state, so if anything, those should
be the pr_err() cases instead, while security_load_policy() failure
might even need/want a pr_warn_ratelimited() since it can be induced by
userspace (albeit only root with :security load_policy permission).

> 
> > 
> > I would tend to omit the function name; I don't think it is
> > especially
> > helpful.
> > 
> 
> Agreed.  It seems to be used as a convention throughout
> security/selinux,
> though am happy to drop it from the patch.
> 
> I was planning to send a v2 with pr_err() swapped for pr_warn() and
> __func__
> dropped from the log message, though keeping in mind that Steve has
> prepared a
> patch for this (also, logging to the audit subsystem might be more
> appropriate) would it be better to drop #1 and keep #2?

Not sure - I'd have to see Steve's patch or at least hear more details
from him to know whether his patch would obsolete yours or just
complement it.

> 
> > 
> > There was an earlier discussion about augmenting the audit logging
> > from
> > this function, so this might overlap with that.  I don't know where
> > that stands.
> > 
> > > 
> > >  		goto out;
> > > +	}
> > >  
> > >  	length = sel_make_bools();
> > > -	if (length)
> > > +	if (length) {
> > > +		pr_warn("SELinux: %s: failed to load policy
> > > booleans\n",
> > > +		       __func__);
> > >  		goto out1;
> > > +	}
> > >  
> > >  	length = sel_make_classes();
> > > -	if (length)
> > > +	if (length) {
> > > +		pr_warn("SELinux: %s: failed to load policy
> > > classes\n",
> > > +		       __func__);
> > >  		goto out1;
> > > +	}
> > >  
> > >  	length = sel_make_policycap();
> > > -	if (length)
> > > +	if (length) {
> > > +		pr_warn("SELinux: %s: failed to load policy
> > > capabilities\n",
> > > +		       __func__);
> > >  		goto out1;
> > > +	}
> > >  
> > >  	length = count;
> > >  
> > > @@ -1299,9 +1311,13 @@ static int sel_make_bools(void)
> > >  
> > >  		isec = (struct inode_security_struct *)inode-
> > > > 
> > > > i_security;
> > >  		ret = security_genfs_sid("selinuxfs", page,
> > > SECCLASS_FILE, &sid);
> > > -		if (ret)
> > > +		if (ret) {
> > > +			pr_warn_ratelimited("SELinux: %s: failed
> > > to
> > > lookup sid for %s\n",
> > > +					   __func__, page);
> > >  			goto out;
> > >  
> > > +		}
> > > +
> > >  		isec->sid = sid;
> > >  		isec->initialized = LABEL_INITIALIZED;
> > >  		inode->i_fop = &sel_bool_ops;
> 

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit

^ permalink raw reply

* Re: [PATCH 1/2] selinux: log errors when loading new policy
From: Gary Tierney @ 2016-12-19 15:19 UTC (permalink / raw)
  To: sds; +Cc: selinux, linux-audit
In-Reply-To: <1482158586.28570.17.camel@tycho.nsa.gov>

On Mon, Dec 19, 2016 at 09:43:06AM -0500, Stephen Smalley wrote:
> On Sat, 2016-12-17 at 20:48 +0000, Gary Tierney wrote:
> > Adds error and warning messages to the codepaths which can fail when
> > loading a new policy.  If a policy fails to load, an error message
> > will
> > be printed to dmesg with a description of what failed.  Previously if
> > there was an error during policy loading there would be no indication
> > that it failed.
> > 
> > Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
> > ---
> >  security/selinux/selinuxfs.c | 26 +++++++++++++++++++++-----
> >  1 file changed, 21 insertions(+), 5 deletions(-)
> > 
> > diff --git a/security/selinux/selinuxfs.c
> > b/security/selinux/selinuxfs.c
> > index 0aac402..2139cc7 100644
> > --- a/security/selinux/selinuxfs.c
> > +++ b/security/selinux/selinuxfs.c
> > @@ -522,20 +522,32 @@ static ssize_t sel_write_load(struct file
> > *file, const char __user *buf,
> >  		goto out;
> >  
> >  	length = security_load_policy(data, count);
> > -	if (length)
> > +	if (length) {
> > +		pr_err("SELinux: %s: failed to load policy\n",
> > +		      __func__);
> 
> Not sure about your usage of pr_err() vs pr_warn();
> security_load_policy() may simply fail due to invalid policy from
> userspace, not a kernel-internal error per se.
> 

The intention was to make a distinction between failures on or after
security_load_policy().  If security_load_policy() fails then no audit message
will be logged about loading a new policy, so it seemed more appropriate to
treat that case as KERN_ERROR.  Though with what you said in mind, it is
probably better to change this to pr_warn() as security_load_policy() is
unlikely to cause an actual kernel-internal error.

> I would tend to omit the function name; I don't think it is especially
> helpful.
> 

Agreed.  It seems to be used as a convention throughout security/selinux,
though am happy to drop it from the patch.

I was planning to send a v2 with pr_err() swapped for pr_warn() and __func__
dropped from the log message, though keeping in mind that Steve has prepared a
patch for this (also, logging to the audit subsystem might be more
appropriate) would it be better to drop #1 and keep #2?

> There was an earlier discussion about augmenting the audit logging from
> this function, so this might overlap with that.  I don't know where
> that stands.
> 
> >  		goto out;
> > +	}
> >  
> >  	length = sel_make_bools();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > booleans\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = sel_make_classes();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > classes\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = sel_make_policycap();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > capabilities\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = count;
> >  
> > @@ -1299,9 +1311,13 @@ static int sel_make_bools(void)
> >  
> >  		isec = (struct inode_security_struct *)inode-
> > >i_security;
> >  		ret = security_genfs_sid("selinuxfs", page,
> > SECCLASS_FILE, &sid);
> > -		if (ret)
> > +		if (ret) {
> > +			pr_warn_ratelimited("SELinux: %s: failed to
> > lookup sid for %s\n",
> > +					   __func__, page);
> >  			goto out;
> >  
> > +		}
> > +
> >  		isec->sid = sid;
> >  		isec->initialized = LABEL_INITIALIZED;
> >  		inode->i_fop = &sel_bool_ops;

-- 
Gary Tierney

GPG fingerprint: 412C 0EF9 C305 68E6 B660  BDAF 706E D765 85AA 79D8
https://sks-keyservers.net/pks/lookup?op=get&search=0x706ED76585AA79D8

^ permalink raw reply

* Re: [PATCH 1/2] selinux: log errors when loading new policy
From: Steve Grubb @ 2016-12-19 15:08 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: linux-audit, selinux
In-Reply-To: <1482158586.28570.17.camel@tycho.nsa.gov>

On Monday, December 19, 2016 9:43:06 AM EST Stephen Smalley wrote:
> On Sat, 2016-12-17 at 20:48 +0000, Gary Tierney wrote:
> > Adds error and warning messages to the codepaths which can fail when
> > loading a new policy.  If a policy fails to load, an error message
> > will
> > be printed to dmesg with a description of what failed.  Previously if
> > there was an error during policy loading there would be no indication
> > that it failed.
> > 
> > Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
> > ---
> >  security/selinux/selinuxfs.c | 26 +++++++++++++++++++++-----
> >  1 file changed, 21 insertions(+), 5 deletions(-)
> > 
> > diff --git a/security/selinux/selinuxfs.c
> > b/security/selinux/selinuxfs.c
> > index 0aac402..2139cc7 100644
> > --- a/security/selinux/selinuxfs.c
> > +++ b/security/selinux/selinuxfs.c
> > @@ -522,20 +522,32 @@ static ssize_t sel_write_load(struct file
> > *file, const char __user *buf,
> >  		goto out;
> >  
> >  	length = security_load_policy(data, count);
> > -	if (length)
> > +	if (length) {
> > +		pr_err("SELinux: %s: failed to load policy\n",
> > +		      __func__);
> 
> Not sure about your usage of pr_err() vs pr_warn();
> security_load_policy() may simply fail due to invalid policy from
> userspace, not a kernel-internal error per se.
> 
> I would tend to omit the function name; I don't think it is especially
> helpful.
> 
> There was an earlier discussion about augmenting the audit logging from
> this function, so this might overlap with that.  I don't know where
> that stands.

I have a new patch that I'm going to send soon that addresses this. But I also 
have a second patch that fixes the setboolean auditing as well, but it 
deadlocks the system. I talked about it with Paul and I have an idea on how to 
fix the deadlock but I haven't sent the updated patches yet. I plan to get to 
them later this week.

-Steve

> >  		goto out;
> > +	}
> >  
> >  	length = sel_make_bools();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > booleans\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = sel_make_classes();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > classes\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = sel_make_policycap();
> > -	if (length)
> > +	if (length) {
> > +		pr_warn("SELinux: %s: failed to load policy
> > capabilities\n",
> > +		       __func__);
> >  		goto out1;
> > +	}
> >  
> >  	length = count;
> >  
> > @@ -1299,9 +1311,13 @@ static int sel_make_bools(void)
> >  
> >  		isec = (struct inode_security_struct *)inode-
> > 
> > >i_security;
> > 
> >  		ret = security_genfs_sid("selinuxfs", page,
> > SECCLASS_FILE, &sid);
> > -		if (ret)
> > +		if (ret) {
> > +			pr_warn_ratelimited("SELinux: %s: failed to
> > lookup sid for %s\n",
> > +					   __func__, page);
> >  			goto out;
> >  
> > +		}
> > +
> >  		isec->sid = sid;
> >  		isec->initialized = LABEL_INITIALIZED;
> >  		inode->i_fop = &sel_bool_ops;

^ permalink raw reply

* Re: [PATCH 1/2] selinux: log errors when loading new policy
From: Stephen Smalley @ 2016-12-19 14:43 UTC (permalink / raw)
  To: Gary Tierney, selinux; +Cc: linux-audit
In-Reply-To: <1482007719-14313-2-git-send-email-gary.tierney@gmx.com>

On Sat, 2016-12-17 at 20:48 +0000, Gary Tierney wrote:
> Adds error and warning messages to the codepaths which can fail when
> loading a new policy.  If a policy fails to load, an error message
> will
> be printed to dmesg with a description of what failed.  Previously if
> there was an error during policy loading there would be no indication
> that it failed.
> 
> Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
> ---
>  security/selinux/selinuxfs.c | 26 +++++++++++++++++++++-----
>  1 file changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/security/selinux/selinuxfs.c
> b/security/selinux/selinuxfs.c
> index 0aac402..2139cc7 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -522,20 +522,32 @@ static ssize_t sel_write_load(struct file
> *file, const char __user *buf,
>  		goto out;
>  
>  	length = security_load_policy(data, count);
> -	if (length)
> +	if (length) {
> +		pr_err("SELinux: %s: failed to load policy\n",
> +		      __func__);

Not sure about your usage of pr_err() vs pr_warn();
security_load_policy() may simply fail due to invalid policy from
userspace, not a kernel-internal error per se.

I would tend to omit the function name; I don't think it is especially
helpful.

There was an earlier discussion about augmenting the audit logging from
this function, so this might overlap with that.  I don't know where
that stands.

>  		goto out;
> +	}
>  
>  	length = sel_make_bools();
> -	if (length)
> +	if (length) {
> +		pr_warn("SELinux: %s: failed to load policy
> booleans\n",
> +		       __func__);
>  		goto out1;
> +	}
>  
>  	length = sel_make_classes();
> -	if (length)
> +	if (length) {
> +		pr_warn("SELinux: %s: failed to load policy
> classes\n",
> +		       __func__);
>  		goto out1;
> +	}
>  
>  	length = sel_make_policycap();
> -	if (length)
> +	if (length) {
> +		pr_warn("SELinux: %s: failed to load policy
> capabilities\n",
> +		       __func__);
>  		goto out1;
> +	}
>  
>  	length = count;
>  
> @@ -1299,9 +1311,13 @@ static int sel_make_bools(void)
>  
>  		isec = (struct inode_security_struct *)inode-
> >i_security;
>  		ret = security_genfs_sid("selinuxfs", page,
> SECCLASS_FILE, &sid);
> -		if (ret)
> +		if (ret) {
> +			pr_warn_ratelimited("SELinux: %s: failed to
> lookup sid for %s\n",
> +					   __func__, page);
>  			goto out;
>  
> +		}
> +
>  		isec->sid = sid;
>  		isec->initialized = LABEL_INITIALIZED;
>  		inode->i_fop = &sel_bool_ops;

--
Linux-audit mailing list
Linux-audit@redhat.com
https://www.redhat.com/mailman/listinfo/linux-audit

^ permalink raw reply

* Re: [PATCH] audit: add feature audit_lost reset
From: Paul Moore @ 2016-12-16 22:58 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: linux-audit
In-Reply-To: <8c740656caee622c9a9f8642ac48f22e1bf6933c.1481869063.git.rgb@redhat.com>

On Fri, Dec 16, 2016 at 1:59 AM, Richard Guy Briggs <rgb@redhat.com> wrote:
> Add a method to reset the audit_lost value.
>
> An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
> will return a positive value repesenting the current audit_lost value
> and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
> only flag set, the reset command will be ignored.  The value sent with
> the command is ignored.
>
> An AUDIT_LOST_RESET message will be queued to the listening audit
> daemon.  The message will be similar to a CONFIG_CHANGE message with the
> fields "lost=0" and "old=" containing the value of audit_lost at reset
> ending with a successful result code.
>
> See: https://github.com/linux-audit/audit-kernel/issues/3
>
> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> ---
> v3: Switch, from returing a message to the initiating process, to
> queueing the message for the audit log.
>
> v2: Switch from AUDIT_GET to AUDIT_SET, adding a +ve return code and
> sending a dedicated AUDIT_LOST_RESET message.
> ---
>  include/uapi/linux/audit.h |    2 ++
>  kernel/audit.c             |   16 +++++++++++++++-
>  2 files changed, 17 insertions(+), 1 deletions(-)
>
> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index 208df7b..6d38bff 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -70,6 +70,7 @@
>  #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
>  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off */
>  #define AUDIT_GET_FEATURE      1019    /* Get which features are enabled */
> +#define AUDIT_LOST_RESET       1020    /* Reset the audit_lost value */
>
>  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
>  #define AUDIT_USER_AVC         1107    /* We filter this differently */
> @@ -325,6 +326,7 @@ enum {
>  #define AUDIT_STATUS_RATE_LIMIT                0x0008
>  #define AUDIT_STATUS_BACKLOG_LIMIT     0x0010
>  #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
> +#define AUDIT_STATUS_LOST              0x0040
>
>  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT     0x00000001
>  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
> diff --git a/kernel/audit.c b/kernel/audit.c
> index f1ca116..441e8c0 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -122,7 +122,7 @@
>     3) suppressed due to audit_rate_limit
>     4) suppressed due to audit_backlog_limit
>  */
> -static atomic_t    audit_lost = ATOMIC_INIT(0);
> +static atomic_t        audit_lost = ATOMIC_INIT(0);
>
>  /* The netlink socket. */
>  static struct sock *audit_sock;
> @@ -920,6 +920,20 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>                         if (err < 0)
>                                 return err;
>                 }
> +               if (s.mask == AUDIT_STATUS_LOST) {
> +                       struct audit_buffer *ab;
> +                       u32 lost = atomic_xchg(&audit_lost, 0);
> +
> +                       ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOST_RESET);
> +                       if (unlikely(!ab))
> +                               return lost;

I'm generally not a fan of adding the likely/unlikely optimizations in
non-critial/control path code like this one, but don't respin the
patch just for this.  However, if you do have to respin the patch
please fix this.

> +                       audit_log_format(ab, "lost=0 old=%u", lost);
> +                       audit_log_session_info(ab);
> +                       audit_log_task_context(ab);
> +                       audit_log_format(ab, " res=1");

We're still need to userspace code, so no rush on this, but we should
get Steve's opinion on the format; he'll surely have something to say.

> +                       audit_log_end(ab);
> +                       return lost;
> +               }
>                 break;
>         }
>         case AUDIT_GET_FEATURE:
> --
> 1.7.1
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit



-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Paul Moore @ 2016-12-16 22:47 UTC (permalink / raw)
  To: Steve Grubb, Richard Guy Briggs; +Cc: linux-audit
In-Reply-To: <20161216033942.GI1707@madcap2.tricolour.ca>

On Thu, Dec 15, 2016 at 10:39 PM, Richard Guy Briggs <rgb@redhat.com> wrote:
> On 2016-12-15 22:12, Steve Grubb wrote:
>> On Thursday, December 15, 2016 7:50:48 PM EST Paul Moore wrote:
>> > On Thu, Dec 15, 2016 at 7:22 PM, Steve Grubb <sgrubb@redhat.com> wrote:
>> > > I'm planning to replace all the config change logging with the
>> > > audit_log_task_simple function I sent so that we have everything. Can we
>> > > go ahead and pull that in so that we can start using it?
>> >
>> > There needs to be more than one user of the function to make it
>> > worthwhile; so far that function has only been proposed with a single
>> > user.  Propose it with multiple users and we can look at it seriously.
>>
>> That's because I have several unrelated patches that use it. Do you want me to
>> send all of them at once? There's going to be at least 5 users of the
>> function. Possibly more. I want it to be the default for all future events
>> added because it concisely gives the necessary information for well-formed
>> events.
>
> I'd send the audit_log_task_simple() patch alone, then send each feature
> that uses it in a separate patch set.  Failing that, send it as a
> separate patch in the first patch set to make it available for all, then
> follow it with more separate patchsets for other events.
>
> There is a chicken and egg problem here.

The extremely safe way to do this would be to submit the unrelated
patches first, each written to *not* make use of your new
consolidation function, then submit a single patch which adds the
function and integrates it with the others.

This approach also has the advantage that you are able to submit fixes
as you run across then and not have to wait for everything.  I know
you already have at least one patch ready to, you just need to remove
the references to audit_log_task_simple.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* [PATCH] audit: add feature audit_lost reset
From: Richard Guy Briggs @ 2016-12-16  6:59 UTC (permalink / raw)
  To: linux-audit; +Cc: Richard Guy Briggs

Add a method to reset the audit_lost value.

An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
will return a positive value repesenting the current audit_lost value
and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
only flag set, the reset command will be ignored.  The value sent with
the command is ignored.

An AUDIT_LOST_RESET message will be queued to the listening audit
daemon.  The message will be similar to a CONFIG_CHANGE message with the
fields "lost=0" and "old=" containing the value of audit_lost at reset
ending with a successful result code.

See: https://github.com/linux-audit/audit-kernel/issues/3

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
---
v3: Switch, from returing a message to the initiating process, to
queueing the message for the audit log.

v2: Switch from AUDIT_GET to AUDIT_SET, adding a +ve return code and
sending a dedicated AUDIT_LOST_RESET message.
---
 include/uapi/linux/audit.h |    2 ++
 kernel/audit.c             |   16 +++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 208df7b..6d38bff 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -70,6 +70,7 @@
 #define AUDIT_TTY_SET		1017	/* Set TTY auditing status */
 #define AUDIT_SET_FEATURE	1018	/* Turn an audit feature on or off */
 #define AUDIT_GET_FEATURE	1019	/* Get which features are enabled */
+#define AUDIT_LOST_RESET	1020	/* Reset the audit_lost value */
 
 #define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages mostly uninteresting to kernel */
 #define AUDIT_USER_AVC		1107	/* We filter this differently */
@@ -325,6 +326,7 @@ enum {
 #define AUDIT_STATUS_RATE_LIMIT		0x0008
 #define AUDIT_STATUS_BACKLOG_LIMIT	0x0010
 #define AUDIT_STATUS_BACKLOG_WAIT_TIME	0x0020
+#define AUDIT_STATUS_LOST		0x0040
 
 #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT	0x00000001
 #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME	0x00000002
diff --git a/kernel/audit.c b/kernel/audit.c
index f1ca116..441e8c0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -122,7 +122,7 @@
    3) suppressed due to audit_rate_limit
    4) suppressed due to audit_backlog_limit
 */
-static atomic_t    audit_lost = ATOMIC_INIT(0);
+static atomic_t	audit_lost = ATOMIC_INIT(0);
 
 /* The netlink socket. */
 static struct sock *audit_sock;
@@ -920,6 +920,20 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			if (err < 0)
 				return err;
 		}
+		if (s.mask == AUDIT_STATUS_LOST) {
+			struct audit_buffer *ab;
+			u32 lost = atomic_xchg(&audit_lost, 0);
+
+			ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOST_RESET);
+			if (unlikely(!ab))
+				return lost;
+			audit_log_format(ab, "lost=0 old=%u", lost);
+			audit_log_session_info(ab);
+			audit_log_task_context(ab);
+			audit_log_format(ab, " res=1");
+			audit_log_end(ab);
+			return lost;
+		}
 		break;
 	}
 	case AUDIT_GET_FEATURE:
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Richard Guy Briggs @ 2016-12-16  3:59 UTC (permalink / raw)
  To: Steve Grubb; +Cc: linux-audit
In-Reply-To: <1803050.hqkP3u55ii@x2>

On 2016-12-15 19:22, Steve Grubb wrote:
> On Thursday, December 15, 2016 3:39:16 PM EST Paul Moore wrote:
> > On Sat, Dec 10, 2016 at 6:52 AM, Richard Guy Briggs <rgb@redhat.com> wrote:
> > > Add a method to reset the audit_lost value.
> > > 
> > > An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
> > > will return a positive value repesenting the current audit_lost value
> > > and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
> > > only flag set, the reset command will be ignored.  The value sent with
> > > the command is ignored.
> > > 
> > > An AUDIT_LOST_RESET message will be sent to the listening audit daemon.
> > > The data field will contain a u32 with the positive value of the
> > > audit_lost value when it was reset.
> > > 
> > > See: https://github.com/linux-audit/audit-kernel/issues/3
> > > 
> > > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > > ---
> > > 
> > >  include/uapi/linux/audit.h |    2 ++
> > >  kernel/audit.c             |    8 +++++++-
> > >  2 files changed, 9 insertions(+), 1 deletions(-)
> > > 
> > > diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> > > index 208df7b..6d38bff 100644
> > > --- a/include/uapi/linux/audit.h
> > > +++ b/include/uapi/linux/audit.h
> > > @@ -70,6 +70,7 @@
> > > 
> > >  #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
> > >  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off
> > >  */ #define AUDIT_GET_FEATURE      1019    /* Get which features are
> > >  enabled */> 
> > > +#define AUDIT_LOST_RESET       1020    /* Reset the audit_lost value */
> > > 
> > >  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly
> > >  uninteresting to kernel */ #define AUDIT_USER_AVC         1107    /* We
> > >  filter this differently */> 
> > > @@ -325,6 +326,7 @@ enum {
> > > 
> > >  #define AUDIT_STATUS_RATE_LIMIT                0x0008
> > >  #define AUDIT_STATUS_BACKLOG_LIMIT     0x0010
> > >  #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
> > > 
> > > +#define AUDIT_STATUS_LOST              0x0040
> > > 
> > >  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT     0x00000001
> > >  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
> > > 
> > > diff --git a/kernel/audit.c b/kernel/audit.c
> > > index f1ca116..19cfee0 100644
> > > --- a/kernel/audit.c
> > > +++ b/kernel/audit.c
> > > @@ -122,7 +122,7 @@
> > > 
> > >     3) suppressed due to audit_rate_limit
> > >     4) suppressed due to audit_backlog_limit
> > >  
> > >  */
> > > 
> > > -static atomic_t    audit_lost = ATOMIC_INIT(0);
> > > +static atomic_t        audit_lost = ATOMIC_INIT(0);
> > > 
> > >  /* The netlink socket. */
> > >  static struct sock *audit_sock;
> > > 
> > > @@ -920,6 +920,12 @@ static int audit_receive_msg(struct sk_buff *skb,
> > > struct nlmsghdr *nlh)> 
> > >                         if (err < 0)
> > >                         
> > >                                 return err;
> > >                 
> > >                 }
> > > 
> > > +               if (s.mask == AUDIT_STATUS_LOST) {
> > > +                       u32 lost = atomic_xchg(&audit_lost, 0);
> > > +
> > > +                       audit_send_reply(skb, seq, AUDIT_LOST_RESET, 0, 0,
> > > &lost, sizeof(lost));
> > I'm not sure it makes much sense to both return the lost value as a
> > netlink return code as well as send a separate netlink message back to
> > the controlling task with the same information.  What I meant earlier
> > was that we would emit an audit record, similar to
> > audit_log_config_change(), so that the audit log would not only have
> > information that the status count was reset, but also the subject
> > information necessary to associate the action with an individual.
> > 
> > Does that make sense?
> 
> I'm planning to replace all the config change logging with the 
> audit_log_task_simple function I sent so that we have everything. Can we go 
> ahead and pull that in so that we can start using it?

I was too late for this kernel release even with the first version of
this patch, so now we have plenty of time to get this right and have it
sit in next for a while.

> Thanks,
> -Steve

- RGB

--
Richard Guy Briggs <rgb@redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Richard Guy Briggs @ 2016-12-16  3:54 UTC (permalink / raw)
  To: Paul Moore; +Cc: linux-audit
In-Reply-To: <CAHC9VhQwVKTmFnYUmOAHSv5RfPs_BYaHcpzxcMyMfWm-kKuHXA@mail.gmail.com>

On 2016-12-15 15:39, Paul Moore wrote:
> On Sat, Dec 10, 2016 at 6:52 AM, Richard Guy Briggs <rgb@redhat.com> wrote:
> > Add a method to reset the audit_lost value.
> >
> > An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
> > will return a positive value repesenting the current audit_lost value
> > and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
> > only flag set, the reset command will be ignored.  The value sent with
> > the command is ignored.
> >
> > An AUDIT_LOST_RESET message will be sent to the listening audit daemon.
> > The data field will contain a u32 with the positive value of the
> > audit_lost value when it was reset.
> >
> > See: https://github.com/linux-audit/audit-kernel/issues/3
> >
> > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > ---
> >  include/uapi/linux/audit.h |    2 ++
> >  kernel/audit.c             |    8 +++++++-
> >  2 files changed, 9 insertions(+), 1 deletions(-)
> >
> > diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> > index 208df7b..6d38bff 100644
> > --- a/include/uapi/linux/audit.h
> > +++ b/include/uapi/linux/audit.h
> > @@ -70,6 +70,7 @@
> >  #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
> >  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off */
> >  #define AUDIT_GET_FEATURE      1019    /* Get which features are enabled */
> > +#define AUDIT_LOST_RESET       1020    /* Reset the audit_lost value */
> >
> >  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
> >  #define AUDIT_USER_AVC         1107    /* We filter this differently */
> > @@ -325,6 +326,7 @@ enum {
> >  #define AUDIT_STATUS_RATE_LIMIT                0x0008
> >  #define AUDIT_STATUS_BACKLOG_LIMIT     0x0010
> >  #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
> > +#define AUDIT_STATUS_LOST              0x0040
> >
> >  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT     0x00000001
> >  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
> > diff --git a/kernel/audit.c b/kernel/audit.c
> > index f1ca116..19cfee0 100644
> > --- a/kernel/audit.c
> > +++ b/kernel/audit.c
> > @@ -122,7 +122,7 @@
> >     3) suppressed due to audit_rate_limit
> >     4) suppressed due to audit_backlog_limit
> >  */
> > -static atomic_t    audit_lost = ATOMIC_INIT(0);
> > +static atomic_t        audit_lost = ATOMIC_INIT(0);
> >
> >  /* The netlink socket. */
> >  static struct sock *audit_sock;
> > @@ -920,6 +920,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
> >                         if (err < 0)
> >                                 return err;
> >                 }
> > +               if (s.mask == AUDIT_STATUS_LOST) {
> > +                       u32 lost = atomic_xchg(&audit_lost, 0);
> > +
> > +                       audit_send_reply(skb, seq, AUDIT_LOST_RESET, 0, 0, &lost, sizeof(lost));
> 
> I'm not sure it makes much sense to both return the lost value as a
> netlink return code as well as send a separate netlink message back to
> the controlling task with the same information.  What I meant earlier
> was that we would emit an audit record, similar to
> audit_log_config_change(), so that the audit log would not only have
> information that the status count was reset, but also the subject
> information necessary to associate the action with an individual.

I would argue that both are useful, but I missed your point about having
the record sent to the regular queue rather than sent to the process
that is doing the reset.  The process doing the reset will see that
message, but auditd won't, so it won't end up in the log itself, which
was the whole point of sending the notice of an action that requires
trackng.

I'll respin.  I still see value in returing a +ve value to the caller to
detect that feature.

> Does that make sense?

It does.  (The discussion of audit_log_task_simple was a hijack of this
thread that really belongs in a new thread or at least a new subject
name).

> > +                       return lost;
> > +               }
> >                 break;
> >         }
> >         case AUDIT_GET_FEATURE:
> 
> paul moore

- RGB

--
Richard Guy Briggs <rgb@redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Richard Guy Briggs @ 2016-12-16  3:39 UTC (permalink / raw)
  To: Steve Grubb; +Cc: linux-audit
In-Reply-To: <14416625.8shW6piCVY@x2>

On 2016-12-15 22:12, Steve Grubb wrote:
> On Thursday, December 15, 2016 7:50:48 PM EST Paul Moore wrote:
> > On Thu, Dec 15, 2016 at 7:22 PM, Steve Grubb <sgrubb@redhat.com> wrote:
> > > I'm planning to replace all the config change logging with the
> > > audit_log_task_simple function I sent so that we have everything. Can we
> > > go ahead and pull that in so that we can start using it?
> > 
> > There needs to be more than one user of the function to make it
> > worthwhile; so far that function has only been proposed with a single
> > user.  Propose it with multiple users and we can look at it seriously.
> 
> That's because I have several unrelated patches that use it. Do you want me to 
> send all of them at once? There's going to be at least 5 users of the 
> function. Possibly more. I want it to be the default for all future events 
> added because it concisely gives the necessary information for well-formed 
> events.

I'd send the audit_log_task_simple() patch alone, then send each feature
that uses it in a separate patch set.  Failing that, send it as a
separate patch in the first patch set to make it available for all, then
follow it with more separate patchsets for other events.

There is a chicken and egg problem here.

> -Steve

- RGB

--
Richard Guy Briggs <rgb@redhat.com>
Kernel Security Engineering, Base Operating Systems, Red Hat
Remote, Ottawa, Canada
Voice: +1.647.777.2635, Internal: (81) 32635

^ permalink raw reply

* audit 2.7 released
From: Steve Grubb @ 2016-12-16  3:22 UTC (permalink / raw)
  To: Linux Audit

Hello,

I've just released a new version of the audit daemon. It can be downloaded 
from http://people.redhat.com/sgrubb/audit. It will also be in rawhide
soon. The ChangeLog is:

- Remove config file permission checks in auparse
- Audisp-remote should detect normal socket close and mark remote_ended
- Allow auditctl to list rules if no capabilities but root euid
- In libaudit, use the last word of the syscall bit mask
- In auditd, write_logs option was not correctly handled (#1382397)
- In libaudit, allow filtering on new exclude filter fields (Richard Guy Briggs)
- In auditd, fix looping when checking active connections
- In auparse, the auparse_state_t pointer to keep escape_mode information
- In libaudit, add support for rules using sessionid (Richard Guy Briggs)
- Remove entry filter support
- Add auparse_destroy_ext function
- Improve ENRICHED logging format performance in auditd
- Fix regex rule file matching in augenrules (#1396792)
- Add numeric field/record accessors to auparse
- Fix auditd freeing in middle of reply buffer when nolog is used
- Switch auparse uid/gid cache to lru to limit growth
- Prevent ausearch from clobbering type field on loginuid search
- Add audit_get_session function to libaudit
- Add session and uid to most audit events
- Add auparse_classify code interface for subj, obj, action, results

The main goal of this update is to land the auparse_classify interface to 
auparse. This will unlock many new capabilities in subsequent releases of the 
2.7 series. If you are a programmer and do stuff with R or machine learning, 
let me know. This is aimed squarely at transforming data into knowledge.

Aside from that, this fixes remote logging, and logging with the nolog and 
write_logs = no option, it allows audit rules on the new exclude filter fields 
and rules that use sessionid.

The entry filter support has been dropped. It was deprecated a couple years 
ago. There are performance enhancements and correctness fixes.

Please let me know if you run across any problems with this release.

-Steve

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Steve Grubb @ 2016-12-16  3:12 UTC (permalink / raw)
  To: Paul Moore; +Cc: Richard Guy Briggs, linux-audit
In-Reply-To: <CAHC9VhS4yCw6bfYJVLOzy1VOZnF+FZyA8wS3O6UjVT4SZ45KUA@mail.gmail.com>

On Thursday, December 15, 2016 7:50:48 PM EST Paul Moore wrote:
> On Thu, Dec 15, 2016 at 7:22 PM, Steve Grubb <sgrubb@redhat.com> wrote:
> > I'm planning to replace all the config change logging with the
> > audit_log_task_simple function I sent so that we have everything. Can we
> > go ahead and pull that in so that we can start using it?
> 
> There needs to be more than one user of the function to make it
> worthwhile; so far that function has only been proposed with a single
> user.  Propose it with multiple users and we can look at it seriously.

That's because I have several unrelated patches that use it. Do you want me to 
send all of them at once? There's going to be at least 5 users of the 
function. Possibly more. I want it to be the default for all future events 
added because it concisely gives the necessary information for well-formed 
events.

-Steve

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Paul Moore @ 2016-12-16  0:50 UTC (permalink / raw)
  To: Steve Grubb; +Cc: Richard Guy Briggs, linux-audit
In-Reply-To: <1803050.hqkP3u55ii@x2>

On Thu, Dec 15, 2016 at 7:22 PM, Steve Grubb <sgrubb@redhat.com> wrote:
> I'm planning to replace all the config change logging with the
> audit_log_task_simple function I sent so that we have everything. Can we go
> ahead and pull that in so that we can start using it?

There needs to be more than one user of the function to make it
worthwhile; so far that function has only been proposed with a single
user.  Propose it with multiple users and we can look at it seriously.

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Steve Grubb @ 2016-12-16  0:22 UTC (permalink / raw)
  To: linux-audit; +Cc: Richard Guy Briggs
In-Reply-To: <CAHC9VhQwVKTmFnYUmOAHSv5RfPs_BYaHcpzxcMyMfWm-kKuHXA@mail.gmail.com>

On Thursday, December 15, 2016 3:39:16 PM EST Paul Moore wrote:
> On Sat, Dec 10, 2016 at 6:52 AM, Richard Guy Briggs <rgb@redhat.com> wrote:
> > Add a method to reset the audit_lost value.
> > 
> > An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
> > will return a positive value repesenting the current audit_lost value
> > and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
> > only flag set, the reset command will be ignored.  The value sent with
> > the command is ignored.
> > 
> > An AUDIT_LOST_RESET message will be sent to the listening audit daemon.
> > The data field will contain a u32 with the positive value of the
> > audit_lost value when it was reset.
> > 
> > See: https://github.com/linux-audit/audit-kernel/issues/3
> > 
> > Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> > ---
> > 
> >  include/uapi/linux/audit.h |    2 ++
> >  kernel/audit.c             |    8 +++++++-
> >  2 files changed, 9 insertions(+), 1 deletions(-)
> > 
> > diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> > index 208df7b..6d38bff 100644
> > --- a/include/uapi/linux/audit.h
> > +++ b/include/uapi/linux/audit.h
> > @@ -70,6 +70,7 @@
> > 
> >  #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
> >  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off
> >  */ #define AUDIT_GET_FEATURE      1019    /* Get which features are
> >  enabled */> 
> > +#define AUDIT_LOST_RESET       1020    /* Reset the audit_lost value */
> > 
> >  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly
> >  uninteresting to kernel */ #define AUDIT_USER_AVC         1107    /* We
> >  filter this differently */> 
> > @@ -325,6 +326,7 @@ enum {
> > 
> >  #define AUDIT_STATUS_RATE_LIMIT                0x0008
> >  #define AUDIT_STATUS_BACKLOG_LIMIT     0x0010
> >  #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
> > 
> > +#define AUDIT_STATUS_LOST              0x0040
> > 
> >  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT     0x00000001
> >  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
> > 
> > diff --git a/kernel/audit.c b/kernel/audit.c
> > index f1ca116..19cfee0 100644
> > --- a/kernel/audit.c
> > +++ b/kernel/audit.c
> > @@ -122,7 +122,7 @@
> > 
> >     3) suppressed due to audit_rate_limit
> >     4) suppressed due to audit_backlog_limit
> >  
> >  */
> > 
> > -static atomic_t    audit_lost = ATOMIC_INIT(0);
> > +static atomic_t        audit_lost = ATOMIC_INIT(0);
> > 
> >  /* The netlink socket. */
> >  static struct sock *audit_sock;
> > 
> > @@ -920,6 +920,12 @@ static int audit_receive_msg(struct sk_buff *skb,
> > struct nlmsghdr *nlh)> 
> >                         if (err < 0)
> >                         
> >                                 return err;
> >                 
> >                 }
> > 
> > +               if (s.mask == AUDIT_STATUS_LOST) {
> > +                       u32 lost = atomic_xchg(&audit_lost, 0);
> > +
> > +                       audit_send_reply(skb, seq, AUDIT_LOST_RESET, 0, 0,
> > &lost, sizeof(lost));
> I'm not sure it makes much sense to both return the lost value as a
> netlink return code as well as send a separate netlink message back to
> the controlling task with the same information.  What I meant earlier
> was that we would emit an audit record, similar to
> audit_log_config_change(), so that the audit log would not only have
> information that the status count was reset, but also the subject
> information necessary to associate the action with an individual.
> 
> Does that make sense?

I'm planning to replace all the config change logging with the 
audit_log_task_simple function I sent so that we have everything. Can we go 
ahead and pull that in so that we can start using it?

Thanks,
-Steve

> > +                       return lost;
> > +               }
> > 
> >                 break;
> >         
> >         }
> > 
> >         case AUDIT_GET_FEATURE:
> > --
> > 1.7.1
> > 
> > --
> > Linux-audit mailing list
> > Linux-audit@redhat.com
> > https://www.redhat.com/mailman/listinfo/linux-audit

^ permalink raw reply

* Re: [PATCH v2] audit: add feature audit_lost reset
From: Paul Moore @ 2016-12-15 20:39 UTC (permalink / raw)
  To: Richard Guy Briggs; +Cc: linux-audit
In-Reply-To: <75c9c4dcd0a57ba6afec676ec55155e70ccb6a28.1481370732.git.rgb@redhat.com>

On Sat, Dec 10, 2016 at 6:52 AM, Richard Guy Briggs <rgb@redhat.com> wrote:
> Add a method to reset the audit_lost value.
>
> An AUDIT_SET message with the AUDIT_STATUS_LOST flag set by itself
> will return a positive value repesenting the current audit_lost value
> and reset the counter to zero.  If AUDIT_STATUS_LOST is not the
> only flag set, the reset command will be ignored.  The value sent with
> the command is ignored.
>
> An AUDIT_LOST_RESET message will be sent to the listening audit daemon.
> The data field will contain a u32 with the positive value of the
> audit_lost value when it was reset.
>
> See: https://github.com/linux-audit/audit-kernel/issues/3
>
> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> ---
>  include/uapi/linux/audit.h |    2 ++
>  kernel/audit.c             |    8 +++++++-
>  2 files changed, 9 insertions(+), 1 deletions(-)
>
> diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
> index 208df7b..6d38bff 100644
> --- a/include/uapi/linux/audit.h
> +++ b/include/uapi/linux/audit.h
> @@ -70,6 +70,7 @@
>  #define AUDIT_TTY_SET          1017    /* Set TTY auditing status */
>  #define AUDIT_SET_FEATURE      1018    /* Turn an audit feature on or off */
>  #define AUDIT_GET_FEATURE      1019    /* Get which features are enabled */
> +#define AUDIT_LOST_RESET       1020    /* Reset the audit_lost value */
>
>  #define AUDIT_FIRST_USER_MSG   1100    /* Userspace messages mostly uninteresting to kernel */
>  #define AUDIT_USER_AVC         1107    /* We filter this differently */
> @@ -325,6 +326,7 @@ enum {
>  #define AUDIT_STATUS_RATE_LIMIT                0x0008
>  #define AUDIT_STATUS_BACKLOG_LIMIT     0x0010
>  #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020
> +#define AUDIT_STATUS_LOST              0x0040
>
>  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT     0x00000001
>  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002
> diff --git a/kernel/audit.c b/kernel/audit.c
> index f1ca116..19cfee0 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -122,7 +122,7 @@
>     3) suppressed due to audit_rate_limit
>     4) suppressed due to audit_backlog_limit
>  */
> -static atomic_t    audit_lost = ATOMIC_INIT(0);
> +static atomic_t        audit_lost = ATOMIC_INIT(0);
>
>  /* The netlink socket. */
>  static struct sock *audit_sock;
> @@ -920,6 +920,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
>                         if (err < 0)
>                                 return err;
>                 }
> +               if (s.mask == AUDIT_STATUS_LOST) {
> +                       u32 lost = atomic_xchg(&audit_lost, 0);
> +
> +                       audit_send_reply(skb, seq, AUDIT_LOST_RESET, 0, 0, &lost, sizeof(lost));

I'm not sure it makes much sense to both return the lost value as a
netlink return code as well as send a separate netlink message back to
the controlling task with the same information.  What I meant earlier
was that we would emit an audit record, similar to
audit_log_config_change(), so that the audit log would not only have
information that the status count was reset, but also the subject
information necessary to associate the action with an individual.

Does that make sense?

> +                       return lost;
> +               }
>                 break;
>         }
>         case AUDIT_GET_FEATURE:
> --
> 1.7.1
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://www.redhat.com/mailman/listinfo/linux-audit

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [GIT PULL] Audit patches for v4.10
From: Paul Moore @ 2016-12-14 21:14 UTC (permalink / raw)
  To: linux-audit
In-Reply-To: <1522672.4tJvQfugPF@sifl>

On Wed, Dec 14, 2016 at 1:27 PM, Paul Moore <pmoore@redhat.com> wrote:
> Hi Linus,
>
> After the small number of patches for v4.9, we've got a much bigger pile for
> v4.10 ...

[NOTE: dropped everyone except for the linux-audit list]

Due to the large number of changes in audit#next for v4.10 I've
decided to not do the usual audit#next rebase following the
pull-request to Linus; the next branch will remain based on v4.8 for
the v4.11 development cycle.  I've also merged the two patches in my
next-queue branch into audit#next.

As a reminder, the normal process is documented here:

* http://www.paul-moore.com/blog/d/2016/03/kernel-repo-process.html

-- 
paul moore
www.paul-moore.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox