audit.47 filesystem problems (reported by Rob Myers)

Timothy R. Chavez tinytim at us.ibm.com
Tue May 24 19:07:46 UTC 2005


On Tuesday 24 May 2005 14:05, Timothy R. Chavez wrote:
> On Tuesday 24 May 2005 12:43, Timothy R. Chavez wrote:
> 
> <snip>
> 
> > Problem 2:
> > 
> > An OOPS when referencing a NULL pointer when watching /var/audit/audit.log in 
> > an SMP environment which has not yet been reproduced.
> > 
> > Diagnosis:
> > 
> > Because this has not be reproducible and we're in an SMP environment its 
> > probably safe to say there is a race.  Because the OOPs occurred from within 
> > permission() and we're dealing with file system watches it is safe to assume 
> > that the race occurred somewhere in or under audit_notify_watch().
> > 
> > Solution:
> > 
> 
> Ok, just looking at audit_notify_watch() in kernel:auditsc.c,
> 
> int audit_notify_watch(struct inode *inode, int mask)
> {
>         int ret = 0;
>         struct audit_context *context = current->audit_context;
>         struct audit_aux_data_watched *ax;
>         struct audit_wentry *wentry = NULL;
>                                                                                                                                                                      
>         if (likely(!audit_enabled))
>                 goto audit_notify_watch_exit;
>                                                                                                                                                                      
>         if (!inode)
>                 goto audit_notify_watch_exit;
>                                                                                                                                                                      
> Possibly in an SMP environment there could be a race here
> where we're trying to get a reference to inode->i_audit->wentry,
> we pass the check in audit_wentry_get() to check if it's still OK,
> then another CPU changes it, such that it becomes invalid in
> some way (ie: NULL).  With the read_lock() we force anything
> that's interested in this i_audit->wentry to block until we got
> the reference successfully.  Does this make sense?
> 
>         read_lock(&inode->i_audit->lock);
>         wentry = audit_wentry_get(inode->i_audit->wentry);
>         if (!wentry) 
>                 goto audit_notify_watch_exit;
>         read_unlock(&inode->i_audit->lock);
> 

*cough* of course I'd want to release the lock of !wentry :-) *cough*
 
-tim




More information about the Linux-audit mailing list