2019-03-16 12:12:25

by Richard Guy Briggs

[permalink] [raw]
Subject: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
verified xattrs"), the call to audit_log_start() is missing a context to
link it to an audit event. Since this event is in user context, add
the process' syscall context to the record.

In addition, the orphaned keyword "locked" appears in the record.
Normalize this by changing it to "xattr=(locked)".

Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/109

Signed-off-by: Richard Guy Briggs <[email protected]>
---
security/integrity/evm/evm_secfs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index 015aea8fdf1e..4171d174e9da 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
if (count > XATTR_NAME_MAX)
return -E2BIG;

- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR);
+ ab = audit_log_start(audit_context(), GFP_KERNEL,
+ AUDIT_INTEGRITY_EVM_XATTR);
if (!ab)
return -ENOMEM;

@@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
inode_lock(inode);
err = simple_setattr(evm_xattrs, &newattrs);
inode_unlock(inode);
- audit_log_format(ab, "locked");
+ audit_log_format(ab, "xattr=(locked)");
if (!err)
err = count;
goto out;
--
1.8.3.1



2019-03-20 23:49:21

by Paul Moore

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Sat, Mar 16, 2019 at 8:10 AM Richard Guy Briggs <[email protected]> wrote:
> In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
> verified xattrs"), the call to audit_log_start() is missing a context to
> link it to an audit event. Since this event is in user context, add
> the process' syscall context to the record.
>
> In addition, the orphaned keyword "locked" appears in the record.
> Normalize this by changing it to "xattr=(locked)".
>
> Please see the github issue
> https://github.com/linux-audit/audit-kernel/issues/109
>
> Signed-off-by: Richard Guy Briggs <[email protected]>
> ---
> security/integrity/evm/evm_secfs.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
> index 015aea8fdf1e..4171d174e9da 100644
> --- a/security/integrity/evm/evm_secfs.c
> +++ b/security/integrity/evm/evm_secfs.c
> @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> if (count > XATTR_NAME_MAX)
> return -E2BIG;
>
> - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR);
> + ab = audit_log_start(audit_context(), GFP_KERNEL,
> + AUDIT_INTEGRITY_EVM_XATTR);

This part is fine.

> if (!ab)
> return -ENOMEM;
>
> @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> inode_lock(inode);
> err = simple_setattr(evm_xattrs, &newattrs);
> inode_unlock(inode);
> - audit_log_format(ab, "locked");
> + audit_log_format(ab, "xattr=(locked)");

Two things come to mind:

* While we can clearly trust the string above, should we be logging
the xattr field value as an untrusted string so it is consistent with
how we record other xattr names?
* I'm not sure you can ever have parens in a xattr (I would hope not),
but if we are going to use the xattr field, perhaps we should simply
stick with the name as provided (".") so we don't ever run afoul of
xattr names? I'm curious to hear what the IMA/EVM folks think of
this.

--
paul moore
http://www.paul-moore.com

2019-03-21 00:51:25

by Richard Guy Briggs

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On 2019-03-20 19:48, Paul Moore wrote:
> On Sat, Mar 16, 2019 at 8:10 AM Richard Guy Briggs <[email protected]> wrote:
> > In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
> > verified xattrs"), the call to audit_log_start() is missing a context to
> > link it to an audit event. Since this event is in user context, add
> > the process' syscall context to the record.
> >
> > In addition, the orphaned keyword "locked" appears in the record.
> > Normalize this by changing it to "xattr=(locked)".
> >
> > Please see the github issue
> > https://github.com/linux-audit/audit-kernel/issues/109
> >
> > Signed-off-by: Richard Guy Briggs <[email protected]>
> > ---
> > security/integrity/evm/evm_secfs.c | 5 +++--
> > 1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
> > index 015aea8fdf1e..4171d174e9da 100644
> > --- a/security/integrity/evm/evm_secfs.c
> > +++ b/security/integrity/evm/evm_secfs.c
> > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> > if (count > XATTR_NAME_MAX)
> > return -E2BIG;
> >
> > - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR);
> > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > + AUDIT_INTEGRITY_EVM_XATTR);
>
> This part is fine.
>
> > if (!ab)
> > return -ENOMEM;
> >
> > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> > inode_lock(inode);
> > err = simple_setattr(evm_xattrs, &newattrs);
> > inode_unlock(inode);
> > - audit_log_format(ab, "locked");
> > + audit_log_format(ab, "xattr=(locked)");
>
> Two things come to mind:
>
> * While we can clearly trust the string above, should we be logging
> the xattr field value as an untrusted string so it is consistent with
> how we record other xattr names?

That would be a question for Steve.

> * I'm not sure you can ever have parens in a xattr (I would hope not),
> but if we are going to use the xattr field, perhaps we should simply
> stick with the name as provided (".") so we don't ever run afoul of
> xattr names? I'm curious to hear what the IMA/EVM folks think of
> this.

The legal xaddr names start with XATTR_SECURITY_PREFIX which is
"security." so there is no danger of collision with legal names, but I
suppose someone could try to use "(locked)" as a name which would look
identical but fail with a different res= number. I think I prefer your
idea of printing the given value verbatim.

> paul moore

- RGB

--
Richard Guy Briggs <[email protected]>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635

2019-03-21 01:04:49

by Paul Moore

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Wed, Mar 20, 2019 at 8:50 PM Richard Guy Briggs <[email protected]> wrote:
> On 2019-03-20 19:48, Paul Moore wrote:
> > On Sat, Mar 16, 2019 at 8:10 AM Richard Guy Briggs <[email protected]> wrote:
> > > In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
> > > verified xattrs"), the call to audit_log_start() is missing a context to
> > > link it to an audit event. Since this event is in user context, add
> > > the process' syscall context to the record.
> > >
> > > In addition, the orphaned keyword "locked" appears in the record.
> > > Normalize this by changing it to "xattr=(locked)".
> > >
> > > Please see the github issue
> > > https://github.com/linux-audit/audit-kernel/issues/109
> > >
> > > Signed-off-by: Richard Guy Briggs <[email protected]>
> > > ---
> > > security/integrity/evm/evm_secfs.c | 5 +++--
> > > 1 file changed, 3 insertions(+), 2 deletions(-)

...

> > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> > > inode_lock(inode);
> > > err = simple_setattr(evm_xattrs, &newattrs);
> > > inode_unlock(inode);
> > > - audit_log_format(ab, "locked");
> > > + audit_log_format(ab, "xattr=(locked)");
> >
> > Two things come to mind:
> >
> > * While we can clearly trust the string above, should we be logging
> > the xattr field value as an untrusted string so it is consistent with
> > how we record other xattr names?
>
> That would be a question for Steve.

Yep, that's who I wanted to hear from, it's not really something I
expected you to answer Richard. I vaguely remember something about
Steve's audit libs being able to handle both trusted and untrusted
value strings for a given field, but I could have confused "able to
handle" with "don't care".

--
paul moore
http://www.paul-moore.com

2019-03-26 15:13:59

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Wed, 2019-03-20 at 20:50 -0400, Richard Guy Briggs wrote:
> On 2019-03-20 19:48, Paul Moore wrote:
> > On Sat, Mar 16, 2019 at 8:10 AM Richard Guy Briggs <[email protected]> wrote:
> > > In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
> > > verified xattrs"), the call to audit_log_start() is missing a context to
> > > link it to an audit event. Since this event is in user context, add
> > > the process' syscall context to the record.
> > >
> > > In addition, the orphaned keyword "locked" appears in the record.
> > > Normalize this by changing it to "xattr=(locked)".
> > >
> > > Please see the github issue
> > > https://github.com/linux-audit/audit-kernel/issues/109
> > >
> > > Signed-off-by: Richard Guy Briggs <[email protected]>
> > > ---
> > > security/integrity/evm/evm_secfs.c | 5 +++--
> > > 1 file changed, 3 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
> > > index 015aea8fdf1e..4171d174e9da 100644
> > > --- a/security/integrity/evm/evm_secfs.c
> > > +++ b/security/integrity/evm/evm_secfs.c
> > > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> > > if (count > XATTR_NAME_MAX)
> > > return -E2BIG;
> > >
> > > - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR);
> > > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > > + AUDIT_INTEGRITY_EVM_XATTR);
> >
> > This part is fine.
> >
> > > if (!ab)
> > > return -ENOMEM;
> > >
> > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
> > > inode_lock(inode);
> > > err = simple_setattr(evm_xattrs, &newattrs);
> > > inode_unlock(inode);
> > > - audit_log_format(ab, "locked");
> > > + audit_log_format(ab, "xattr=(locked)");
> >
> > Two things come to mind:
> >
> > * While we can clearly trust the string above, should we be logging
> > the xattr field value as an untrusted string so it is consistent with
> > how we record other xattr names?
>
> That would be a question for Steve.
>
> > * I'm not sure you can ever have parens in a xattr (I would hope not),
> > but if we are going to use the xattr field, perhaps we should simply
> > stick with the name as provided (".") so we don't ever run afoul of
> > xattr names? I'm curious to hear what the IMA/EVM folks think of
> > this.
>
> The legal xaddr names start with XATTR_SECURITY_PREFIX which is
> "security." so there is no danger of collision with legal names, but I
> suppose someone could try to use "(locked)" as a name which would look
> identical but fail with a different res= number. I think I prefer your
> idea of printing the given value verbatim.

I really don't have a preference - "locked", "(locked)", "." or "(.)".
 Any of them is fine.

Thanks!

Mimi


2019-03-26 15:24:07

by Steve Grubb

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Wednesday, March 20, 2019 8:50:08 PM EDT Richard Guy Briggs wrote:
> On 2019-03-20 19:48, Paul Moore wrote:
> > On Sat, Mar 16, 2019 at 8:10 AM Richard Guy Briggs <[email protected]>
wrote:
> > > In commit fa516b66a1bf ("EVM: Allow runtime modification of the set of
> > > verified xattrs"), the call to audit_log_start() is missing a context
> > > to
> > > link it to an audit event. Since this event is in user context, add
> > > the process' syscall context to the record.
> > >
> > > In addition, the orphaned keyword "locked" appears in the record.
> > > Normalize this by changing it to "xattr=(locked)".
> > >
> > > Please see the github issue
> > > https://github.com/linux-audit/audit-kernel/issues/109
> > >
> > > Signed-off-by: Richard Guy Briggs <[email protected]>
> > > ---
> > >
> > > security/integrity/evm/evm_secfs.c | 5 +++--
> > > 1 file changed, 3 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/security/integrity/evm/evm_secfs.c
> > > b/security/integrity/evm/evm_secfs.c index 015aea8fdf1e..4171d174e9da
> > > 100644
> > > --- a/security/integrity/evm/evm_secfs.c
> > > +++ b/security/integrity/evm/evm_secfs.c
> > > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > const char __user *buf,> >
> > > if (count > XATTR_NAME_MAX)
> > >
> > > return -E2BIG;
> > >
> > > - ab = audit_log_start(NULL, GFP_KERNEL,
> > > AUDIT_INTEGRITY_EVM_XATTR);
> > > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > > + AUDIT_INTEGRITY_EVM_XATTR);
> >
> > This part is fine.
> >
> > > if (!ab)
> > >
> > > return -ENOMEM;
> > >
> > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > const char __user *buf,> >
> > > inode_lock(inode);
> > > err = simple_setattr(evm_xattrs, &newattrs);
> > > inode_unlock(inode);
> > >
> > > - audit_log_format(ab, "locked");
> > > + audit_log_format(ab, "xattr=(locked)");
> >
> > Two things come to mind:
> >
> > * While we can clearly trust the string above, should we be logging
> > the xattr field value as an untrusted string so it is consistent with
> > how we record other xattr names?
>
> That would be a question for Steve.

All fields with the same name must be represented the same way. If one
instance is untrusted, every instance of the same keyword must be untrusted.

-Steve


> > * I'm not sure you can ever have parens in a xattr (I would hope not),
> > but if we are going to use the xattr field, perhaps we should simply
> > stick with the name as provided (".") so we don't ever run afoul of
> > xattr names? I'm curious to hear what the IMA/EVM folks think of
> > this.
>
> The legal xaddr names start with XATTR_SECURITY_PREFIX which is
> "security." so there is no danger of collision with legal names, but I
> suppose someone could try to use "(locked)" as a name which would look
> identical but fail with a different res= number. I think I prefer your
> idea of printing the given value verbatim.
>
> > paul moore
>
> - RGB
>
> --
> Richard Guy Briggs <[email protected]>
> Sr. S/W Engineer, Kernel Security, Base Operating Systems
> Remote, Ottawa, Red Hat Canada
> IRC: rgb, SunRaycer
> Voice: +1.647.777.2635, Internal: (81) 32635





2019-03-26 15:30:30

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Tue, 2019-03-26 at 11:22 -0400, Steve Grubb wrote:

> > > > --- a/security/integrity/evm/evm_secfs.c
> > > > +++ b/security/integrity/evm/evm_secfs.c
> > > > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > const char __user *buf,> >
> > > > if (count > XATTR_NAME_MAX)
> > > >
> > > > return -E2BIG;
> > > >
> > > > - ab = audit_log_start(NULL, GFP_KERNEL,
> > > > AUDIT_INTEGRITY_EVM_XATTR);
> > > > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > > > + AUDIT_INTEGRITY_EVM_XATTR);
> > >
> > > This part is fine.
> > >
> > > > if (!ab)
> > > >
> > > > return -ENOMEM;
> > > >
> > > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > const char __user *buf,> >
> > > > inode_lock(inode);
> > > > err = simple_setattr(evm_xattrs, &newattrs);
> > > > inode_unlock(inode);
> > > >
> > > > - audit_log_format(ab, "locked");
> > > > + audit_log_format(ab, "xattr=(locked)");
> > >
> > > Two things come to mind:
> > >
> > > * While we can clearly trust the string above, should we be logging
> > > the xattr field value as an untrusted string so it is consistent with
> > > how we record other xattr names?
> >
> > That would be a question for Steve.
>
> All fields with the same name must be represented the same way. If one
> instance is untrusted, every instance of the same keyword must be untrusted.

Normal case:
audit_log_format(ab, "xattr=");
audit_log_untrustedstring(ab, xattr->name);

Ok, so the above audit_log_format() call should be replaced with
 audit_log_untrustedstring().

Mimi


2019-03-26 16:15:11

by Richard Guy Briggs

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On 2019-03-26 11:29, Mimi Zohar wrote:
> On Tue, 2019-03-26 at 11:22 -0400, Steve Grubb wrote:
>
> > > > > --- a/security/integrity/evm/evm_secfs.c
> > > > > +++ b/security/integrity/evm/evm_secfs.c
> > > > > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > > const char __user *buf,> >
> > > > > if (count > XATTR_NAME_MAX)
> > > > >
> > > > > return -E2BIG;
> > > > >
> > > > > - ab = audit_log_start(NULL, GFP_KERNEL,
> > > > > AUDIT_INTEGRITY_EVM_XATTR);
> > > > > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > > > > + AUDIT_INTEGRITY_EVM_XATTR);
> > > >
> > > > This part is fine.
> > > >
> > > > > if (!ab)
> > > > >
> > > > > return -ENOMEM;
> > > > >
> > > > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > > const char __user *buf,> >
> > > > > inode_lock(inode);
> > > > > err = simple_setattr(evm_xattrs, &newattrs);
> > > > > inode_unlock(inode);
> > > > >
> > > > > - audit_log_format(ab, "locked");
> > > > > + audit_log_format(ab, "xattr=(locked)");
> > > >
> > > > Two things come to mind:
> > > >
> > > > * While we can clearly trust the string above, should we be logging
> > > > the xattr field value as an untrusted string so it is consistent with
> > > > how we record other xattr names?
> > >
> > > That would be a question for Steve.
> >
> > All fields with the same name must be represented the same way. If one
> > instance is untrusted, every instance of the same keyword must be untrusted.
>
> Normal case:
> audit_log_format(ab, "xattr=");
> audit_log_untrustedstring(ab, xattr->name);
>
> Ok, so the above audit_log_format() call should be replaced with
> ?audit_log_untrustedstring().

Ok, so I think we can agree on "audit_log_untrustedstring(ab,
"xattr=.");" and simpler yet just print the contents regardless and not
special case this print. V2 coming...

> Mimi

- RGB

--
Richard Guy Briggs <[email protected]>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635

2019-03-26 17:44:51

by Richard Guy Briggs

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On 2019-03-26 12:14, Richard Guy Briggs wrote:
> On 2019-03-26 11:29, Mimi Zohar wrote:
> > On Tue, 2019-03-26 at 11:22 -0400, Steve Grubb wrote:
> >
> > > > > > --- a/security/integrity/evm/evm_secfs.c
> > > > > > +++ b/security/integrity/evm/evm_secfs.c
> > > > > > @@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > > > const char __user *buf,> >
> > > > > > if (count > XATTR_NAME_MAX)
> > > > > >
> > > > > > return -E2BIG;
> > > > > >
> > > > > > - ab = audit_log_start(NULL, GFP_KERNEL,
> > > > > > AUDIT_INTEGRITY_EVM_XATTR);
> > > > > > + ab = audit_log_start(audit_context(), GFP_KERNEL,
> > > > > > + AUDIT_INTEGRITY_EVM_XATTR);
> > > > >
> > > > > This part is fine.
> > > > >
> > > > > > if (!ab)
> > > > > >
> > > > > > return -ENOMEM;
> > > > > >
> > > > > > @@ -222,7 +223,7 @@ static ssize_t evm_write_xattrs(struct file *file,
> > > > > > const char __user *buf,> >
> > > > > > inode_lock(inode);
> > > > > > err = simple_setattr(evm_xattrs, &newattrs);
> > > > > > inode_unlock(inode);
> > > > > >
> > > > > > - audit_log_format(ab, "locked");
> > > > > > + audit_log_format(ab, "xattr=(locked)");
> > > > >
> > > > > Two things come to mind:
> > > > >
> > > > > * While we can clearly trust the string above, should we be logging
> > > > > the xattr field value as an untrusted string so it is consistent with
> > > > > how we record other xattr names?
> > > >
> > > > That would be a question for Steve.
> > >
> > > All fields with the same name must be represented the same way. If one
> > > instance is untrusted, every instance of the same keyword must be untrusted.
> >
> > Normal case:
> > audit_log_format(ab, "xattr=");
> > audit_log_untrustedstring(ab, xattr->name);
> >
> > Ok, so the above audit_log_format() call should be replaced with
> > ?audit_log_untrustedstring().
>
> Ok, so I think we can agree on "audit_log_untrustedstring(ab,
> "xattr=.");" and simpler yet just print the contents regardless and not
> special case this print. V2 coming...

Ok, what I typed above wasn't quite what I intended... This is what I
meant:

audit_log_format(ab, "xattr=");
audit_log_untrustedstring(ab, ".");

But, I'll just move the normal case above the "." locking detection and
log all cases the same way.

> > Mimi
>
> - RGB

- RGB

--
Richard Guy Briggs <[email protected]>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635

2019-03-26 17:57:00

by Matthew Garrett

[permalink] [raw]
Subject: Re: [PATCH ghak109 V1] audit: link integrity evm_write_xattrs record to syscall event

On Tue, Mar 26, 2019 at 10:43 AM Richard Guy Briggs <[email protected]> wrote:

> Ok, what I typed above wasn't quite what I intended... This is what I
> meant:
>
> audit_log_format(ab, "xattr=");
> audit_log_untrustedstring(ab, ".");
>
> But, I'll just move the normal case above the "." locking detection and
> log all cases the same way.

Sounds good to me.