Page MenuHomeFreeBSD

Use shared vnode locks for ELF interpreter
ClosedPublic

Authored by trasz on Apr 10 2019, 11:51 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Nov 19, 8:34 PM
Unknown Object (File)
Wed, Nov 13, 9:48 AM
Unknown Object (File)
Thu, Nov 7, 7:13 AM
Unknown Object (File)
Tue, Nov 5, 10:51 AM
Unknown Object (File)
Tue, Oct 29, 2:37 PM
Unknown Object (File)
Sun, Oct 27, 11:22 AM
Unknown Object (File)
Oct 20 2024, 10:50 PM
Unknown Object (File)
Oct 20 2024, 10:50 PM
Subscribers

Details

Summary

Use shared vnode locks for the ELF interpreter.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

trasz retitled this revision from Use shared lookups for ELF interpreter to Use shared vnode locks for ELF interpreter.Apr 10 2019, 11:51 AM
trasz edited the summary of this revision. (Show Details)

Basically the relock invalidates all benefits of the shared locking.

I thought about taking excl in lookup(), and then downgrade to shared after VV_TEXT is set, but again this is nonsensical and perhormance is worse.

sys/kern/imgact_elf.c
769 ↗(On Diff #56043)

This drops the vnode lock, so exec_check_permissions() above results are no longer valid.

The relock happens pretty much never, since the function is used for loading the interpreter - which is busy all the time. I had a printf there for testing, and it's called just once, early during boot.

Handle the fact that LK_UPGRADE might drop the lock.

The relock happens pretty much never, since the function is used for loading the interpreter - which is busy all the time. I had a printf there for testing, and it's called just once, early during boot.

It depends on the interpreter. You only see it for the default ld-elf.so.1.

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

In fact again should include lookup.

In D19874#426683, @kib wrote:

The relock happens pretty much never, since the function is used for loading the interpreter - which is busy all the time. I had a printf there for testing, and it's called just once, early during boot.

It depends on the interpreter. You only see it for the default ld-elf.so.1.

Well, yes, it's an optimization for the common case.

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

I'm not sure why. What is a scenario that could break it?

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

Imagine that the interpreter is being removed or renamed/overwritten while you unlocked the vnode

I hate to get aborted processes when I do 'make install' in parallel.

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

But we keep the usecount bumped, so if it got replaced/renamed we still can access the "previous version of the file", right?

I can imagine a situation where the binary depends on the new interpreter to work (wouldn't work with the old interpreter under the same path), but if we tried to run it in parallel with upgrading it could still fail without this patch.

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

Also, from my understanding of lookup() this LK_UPGRADE happens even without the patch - at the end of lookup() itself, and we don't do anything special to handle that.

sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

Usermode has to provide relatively straight-forward guarantee: it never writes into the canonical interpreter, for everything to work. Your patch breaks this guarantee, if userspace renamed the interpreter and then wrote to the old file, it might break some process doing execve().

lookup() could need LK_UPGRADE only if something weird occured like dot lookup as the last path. Otherwise, if you look at the code right before VOP_LOOKUP() invocation, you note that last component is locked exclusively if lookup obtains a new lock (and it does for regular files).

I do not understand your desire to keep more complicated and buggy code, where restart to namei() with changed locking flag is actually simpler. IMO you do not need even to downgrade the lock after VV_TEXT is set,

Improve after feedback from kib@.

trasz added inline comments.
sys/kern/imgact_elf.c
779 ↗(On Diff #56050)

Ah, now I get it. Thanks!

I'm not opposed to what you're saying, it's just I like to understand the "why".

Did you tested this with DEBUG_VFS_LOCKS ?

This revision is now accepted and ready to land.Apr 10 2019, 7:23 PM
In D19874#426822, @kib wrote:

Did you tested this with DEBUG_VFS_LOCKS ?

Yes.

This revision was automatically updated to reflect the committed changes.