<feed xmlns='http://www.w3.org/2005/Atom'>
<title>user/sven/linux.git/kernel/audit_tree.c, branch v3.10.93</title>
<subtitle>Linux Kernel
</subtitle>
<id>https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.10.93</id>
<link rel='self' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/atom?h=v3.10.93'/>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/'/>
<updated>2014-11-21T17:22:52Z</updated>
<entry>
<title>audit: keep inode pinned</title>
<updated>2014-11-21T17:22:52Z</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@suse.cz</email>
</author>
<published>2014-11-04T10:27:12Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=bd501a2eb28282b657555b32acbc65b6c102af1d'/>
<id>urn:sha1:bd501a2eb28282b657555b32acbc65b6c102af1d</id>
<content type='text'>
commit 799b601451b21ebe7af0e6e8f6e2ccd4683c5064 upstream.

Audit rules disappear when an inode they watch is evicted from the cache.
This is likely not what we want.

The guilty commit is "fsnotify: allow marks to not pin inodes in core",
which didn't take into account that audit_tree adds watches with a zero
mask.

Adding any mask should fix this.

Fixes: 90b1e7a57880 ("fsnotify: allow marks to not pin inodes in core")
Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
Signed-off-by: Paul Moore &lt;pmoore@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>kernel/audit_tree.c:audit_add_tree_rule(): protect `rule' from kill_rules()</title>
<updated>2013-06-12T23:29:46Z</updated>
<author>
<name>Chen Gang</name>
<email>gang.chen@asianux.com</email>
</author>
<published>2013-06-12T21:05:07Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=736f3203a06eafd0944103775a98584082744c6b'/>
<id>urn:sha1:736f3203a06eafd0944103775a98584082744c6b</id>
<content type='text'>
audit_add_tree_rule() must set 'rule-&gt;tree = NULL;' firstly, to protect
the rule itself freed in kill_rules().

The reason is when it is killed, the 'rule' itself may have already
released, we should not access it.  one example: we add a rule to an
inode, just at the same time the other task is deleting this inode.

The work flow for adding a rule:

    audit_receive() -&gt; (need audit_cmd_mutex lock)
      audit_receive_skb() -&gt;
        audit_receive_msg() -&gt;
          audit_receive_filter() -&gt;
            audit_add_rule() -&gt;
              audit_add_tree_rule() -&gt; (need audit_filter_mutex lock)
                ...
                unlock audit_filter_mutex
                get_tree()
                ...
                iterate_mounts() -&gt; (iterate all related inodes)
                  tag_mount() -&gt;
                    tag_trunk() -&gt;
                      create_trunk() -&gt; (assume it is 1st rule)
                        fsnotify_add_mark() -&gt;
                          fsnotify_add_inode_mark() -&gt;  (add mark to inode-&gt;i_fsnotify_marks)
                        ...
                        get_tree(); (each inode will get one)
                ...
                lock audit_filter_mutex

The work flow for deleting an inode:

    __destroy_inode() -&gt;
     fsnotify_inode_delete() -&gt;
       __fsnotify_inode_delete() -&gt;
        fsnotify_clear_marks_by_inode() -&gt;  (get mark from inode-&gt;i_fsnotify_marks)
          fsnotify_destroy_mark() -&gt;
           fsnotify_destroy_mark_locked() -&gt;
             audit_tree_freeing_mark() -&gt;
               evict_chunk() -&gt;
                 ...
                 tree-&gt;goner = 1
                 ...
                 kill_rules() -&gt;   (assume current-&gt;audit_context == NULL)
                   call_rcu() -&gt;   (rule-&gt;tree != NULL)
                     audit_free_rule_rcu() -&gt;
                       audit_free_rule()
                 ...
                 audit_schedule_prune() -&gt;  (assume current-&gt;audit_context == NULL)
                   kthread_run() -&gt;    (need audit_cmd_mutex and audit_filter_mutex lock)
                     prune_one() -&gt;    (delete it from prue_list)
                       put_tree(); (match the original get_tree above)

Signed-off-by: Chen Gang &lt;gang.chen@asianux.com&gt;
Cc: Eric Paris &lt;eparis@redhat.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>kernel/audit_tree.c: tree will leak memory when failure occurs in audit_trim_trees()</title>
<updated>2013-04-29T22:54:26Z</updated>
<author>
<name>Chen Gang</name>
<email>gang.chen@asianux.com</email>
</author>
<published>2013-04-29T22:05:19Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=12b2f117f3bf738c1a00a6f64393f1953a740bd4'/>
<id>urn:sha1:12b2f117f3bf738c1a00a6f64393f1953a740bd4</id>
<content type='text'>
audit_trim_trees() calls get_tree().  If a failure occurs we must call
put_tree().

[akpm@linux-foundation.org: run put_tree() before mutex_lock() for small scalability improvement]
Signed-off-by: Chen Gang &lt;gang.chen@asianux.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Eric Paris &lt;eparis@redhat.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>audit: catch possible NULL audit buffers</title>
<updated>2013-01-11T22:54:55Z</updated>
<author>
<name>Kees Cook</name>
<email>keescook@chromium.org</email>
</author>
<published>2013-01-11T22:32:07Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=0644ec0cc8a33fb654e348897ad7684e22a4b5d8'/>
<id>urn:sha1:0644ec0cc8a33fb654e348897ad7684e22a4b5d8</id>
<content type='text'>
It's possible for audit_log_start() to return NULL.  Handle it in the
various callers.

Signed-off-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Eric Paris &lt;eparis@redhat.com&gt;
Cc: Jeff Layton &lt;jlayton@redhat.com&gt;
Cc: "Eric W. Biederman" &lt;ebiederm@xmission.com&gt;
Cc: Julien Tinnes &lt;jln@google.com&gt;
Cc: Will Drewry &lt;wad@google.com&gt;
Cc: Steve Grubb &lt;sgrubb@redhat.com&gt;
Cc: Andrea Arcangeli &lt;aarcange@redhat.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>fsnotify: pass group to fsnotify_destroy_mark()</title>
<updated>2012-12-11T18:44:36Z</updated>
<author>
<name>Lino Sanfilippo</name>
<email>LinoSanfilippo@gmx.de</email>
</author>
<published>2011-06-14T15:29:51Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=e2a29943e9a2ee2aa737a77f550f46ba72269db4'/>
<id>urn:sha1:e2a29943e9a2ee2aa737a77f550f46ba72269db4</id>
<content type='text'>
In fsnotify_destroy_mark() dont get the group from the passed mark anymore,
but pass the group itself as an additional parameter to the function.

Signed-off-by: Lino Sanfilippo &lt;LinoSanfilippo@gmx.de&gt;
Signed-off-by: Eric Paris &lt;eparis@redhat.com&gt;
</content>
</entry>
<entry>
<title>audit: clean up refcounting in audit-tree</title>
<updated>2012-08-15T10:55:22Z</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@suse.cz</email>
</author>
<published>2012-08-15T10:55:22Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=b3e8692b4dde5cf5fc60e4b95385229a72623182'/>
<id>urn:sha1:b3e8692b4dde5cf5fc60e4b95385229a72623182</id>
<content type='text'>
Drop the initial reference by fsnotify_init_mark early instead of
audit_tree_freeing_mark() at destroy time.

In the cases we destroy the mark before we drop the initial reference we need to
get rid of the get_mark that balances the put_mark in audit_tree_freeing_mark().

Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
</content>
</entry>
<entry>
<title>audit: fix refcounting in audit-tree</title>
<updated>2012-08-15T10:55:22Z</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@suse.cz</email>
</author>
<published>2012-08-15T10:55:22Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=a2140fc0cb0325bb6384e788edd27b9a568714e2'/>
<id>urn:sha1:a2140fc0cb0325bb6384e788edd27b9a568714e2</id>
<content type='text'>
Refcounting of fsnotify_mark in audit tree is broken.  E.g:

                              refcount
create_chunk
  alloc_chunk                 1
  fsnotify_add_mark           2

untag_chunk
  fsnotify_get_mark           3
  fsnotify_destroy_mark
    audit_tree_freeing_mark   2
  fsnotify_put_mark           1
  fsnotify_put_mark           0
  via destroy_list
    fsnotify_mark_destroy    -1

This was reported by various people as triggering Oops when stopping auditd.

We could just remove the put_mark from audit_tree_freeing_mark() but that would
break freeing via inode destruction.  So this patch simply omits a put_mark
after calling destroy_mark or adds a get_mark before.

The additional get_mark is necessary where there's no other put_mark after
fsnotify_destroy_mark() since it assumes that the caller is holding a reference
(or the inode is keeping the mark pinned, not the case here AFAICS).

Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
Reported-by: Valentin Avram &lt;aval13@gmail.com&gt;
Reported-by: Peter Moody &lt;pmoody@google.com&gt;
Acked-by: Eric Paris &lt;eparis@redhat.com&gt;
CC: stable@vger.kernel.org
</content>
</entry>
<entry>
<title>audit: don't free_chunk() after fsnotify_add_mark()</title>
<updated>2012-08-15T10:55:22Z</updated>
<author>
<name>Miklos Szeredi</name>
<email>mszeredi@suse.cz</email>
</author>
<published>2012-08-15T10:55:22Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=0fe33aae0e94b4097dd433c9399e16e17d638cd8'/>
<id>urn:sha1:0fe33aae0e94b4097dd433c9399e16e17d638cd8</id>
<content type='text'>
Don't do free_chunk() after fsnotify_add_mark().  That one does a delayed unref
via the destroy list and this results in use-after-free.

Signed-off-by: Miklos Szeredi &lt;mszeredi@suse.cz&gt;
Acked-by: Eric Paris &lt;eparis@redhat.com&gt;
CC: stable@vger.kernel.org
</content>
</entry>
<entry>
<title>VFS: Make clone_mnt()/copy_tree()/collect_mounts() return errors</title>
<updated>2012-07-14T12:37:27Z</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2012-06-25T11:55:18Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=be34d1a3bc4b6f357a49acb55ae870c81337e4f0'/>
<id>urn:sha1:be34d1a3bc4b6f357a49acb55ae870c81337e4f0</id>
<content type='text'>
copy_tree() can theoretically fail in a case other than ENOMEM, but always
returns NULL which is interpreted by callers as -ENOMEM.  Change it to return
an explicit error.

Also change clone_mnt() for consistency and because union mounts will add new
error cases.

Thanks to Andreas Gruenbacher &lt;agruen@suse.de&gt; for a bug fix.
[AV: folded braino fix by Dan Carpenter]

Original-author: Valerie Aurora &lt;vaurora@redhat.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Cc: Valerie Aurora &lt;valerie.aurora@gmail.com&gt;
Cc: Andreas Gruenbacher &lt;agruen@suse.de&gt;
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>audit_tree,rcu: Convert call_rcu(__put_tree) to kfree_rcu()</title>
<updated>2011-07-20T21:10:11Z</updated>
<author>
<name>Lai Jiangshan</name>
<email>laijs@cn.fujitsu.com</email>
</author>
<published>2011-03-15T10:03:53Z</published>
<link rel='alternate' type='text/html' href='https://git.stealer.net/cgit.cgi/user/sven/linux.git/commit/?id=3b097c46964b07479855b01056c61540b8cadd50'/>
<id>urn:sha1:3b097c46964b07479855b01056c61540b8cadd50</id>
<content type='text'>
The rcu callback __put_tree() just calls a kfree(),
so we use kfree_rcu() instead of the call_rcu(__put_tree).

Signed-off-by: Lai Jiangshan &lt;laijs@cn.fujitsu.com&gt;
Signed-off-by: Paul E. McKenney &lt;paulmck@linux.vnet.ibm.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Eric Paris &lt;eparis@redhat.com&gt;
Reviewed-by: Josh Triplett &lt;josh@joshtriplett.org&gt;
</content>
</entry>
</feed>
