New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make singularity binary runtime relocatable #5454
Make singularity binary runtime relocatable #5454
Conversation
992ce73
to
c16fb99
Compare
Hi @chrisburr - thanks for posting this. There is definitely interest in accomplishing this goal, but it would be a bit more involved than the patch here. A couple of points off the top of my head:
I'm going to mark this PR as a request change so it isn't accidentally merged - but it is definitely a good idea if it can be done in a way that handles the various loose ends, and is provably correct through tests. @cclerget and @ikaneshiro may want to join the discussion here too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see notes in the thread. This is a nice goal, but would need to be worked up some more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR @chrisburr.
The relocation of files may not work as expected like @dctrud mentioned, that would probably require some additional checks at compile time in mconfig
to make sure an installation is relocatable.
internal/pkg/buildcfg/confgen/gen.go
Outdated
for _, w := range d.Words[3:] { | ||
s += " + " + w | ||
} | ||
s = "var " + d.Words[1] + " = RelocatePath(" + s + ")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably make things easier to maintain by calling RelocatePath
only for the relevant defined variables, so far those variables are actively used by singularity :
BINDIR
LIBEXECDIR
SYSCONFDIR
SESSIONDIR
SINGULARITY_CONFDIR
PLUGIN_ROOTDIR
) | ||
|
||
func RelocatePath(original string) (string) { | ||
if ! strings.HasPrefix(original, "{{.Prefix}}") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RelocatePath
should return original
when SINGULARITY_SUID_INSTALL == 1
as the very first check to avoid to reach panic panic("Unrecognized executable: " + executablePath)
at line 76 when the executable is starter-suid
and to also ignore relocation for setuid installation :
func RelocatePath(original string) (string) {
if SINGULARITY_SUID_INSTALL == 1 {
return original
}
...
}
Regarding panic in switch it would be safest to return original
as default and could be simplified to:
switch filepath.Base(executablePath) {
case "singularity":
// PREFIX/bin
prefix = filepath.Join(filepath.Dir(executablePath), "..")
case "starter":
// PREFIX/libexec/singularity/bin
prefix = filepath.Join(filepath.Dir(executablePath), "..", "..", "..")
default:
return original
}
c16fb99
to
a7e6020
Compare
Thank you @dctrud and @cclerget for reviewing this PR promptly and I'm sorry for not finding time to address your suggestions until now.
I think this isn't necessary now that relocation is only supported for non-setuid installs. Do you agree or are there other security concerns?
I'm inclined to agree and say it's only supported for simple hierarchies rather than adding the complexity of doing this generically. The I've tested this for conda-forge to make sure the relocation still works with the latest changes and the build has succeeded. I'm not sure how this could be tested in the context of your CI pipeline as it would require singularity to be reconfigured/built with the |
Thanks again for the contribution!
I feel will still do need some sort of testing. We need to guard against the case that code is accidentally modified in the future, giving a pathway to it being used in a setuid install. Given that pointing to different locations in a setuid install is pretty dangerous, I feel quite strongly about this.
This testing is a bit more difficult... let me think about it a bit. |
I've added 6602ed1 which prevents the relocation code from being generated at all if it's a setuid install. If the code is accidentally modified to try and relocate a setuid install it should:
Actually (3) could be made a Another crude check could be to grep the binaries to make sure # Without setuid
$ rg --binary RelocatePath builddir/
Binary file builddir/cmd/starter/c/starter matches (found "\u{0}" byte around offset 7)
Binary file builddir/cmd/starter/c/starter-suid matches (found "\u{0}" byte around offset 7)
Binary file builddir/singularity matches (found "\u{0}" byte around offset 7)
# With setuid (no matches)
$ rg --binary RelocatePath builddir/ |
It's not ideal but one option is to manually test release candidates using
If the CI passes everything then relocation is fine as it has successfully ran the |
@cclerget @ikaneshiro - any thoughts on the code now, and how testing it might be relatively easily integrated into our CI? I think we'd need a rather big change to do that... but I'm wary of having this type of stuff not automatically tested. |
Another issue - this may be be incompatible with the 3.6.4 unsquashfs wrapping, as a user of conda-forge Singularity has reported a panic: #5668 (comment) - not clear whether that issue is relevant in this code. |
The issue is explained by the warning:
If I'm not sure what the changes are in Singularity 3.6.4 but the failure to mount |
@chrisburr - The big change in 3.6.4 is that due to a security issue that occurs from Pinging @cclerget for any thoughts about this.... should we be making a |
4f09a9e
to
6b20d7c
Compare
@dctrud @cclerget Any thoughts on this? I think I could avoid needing |
6b20d7c
to
d6e9c94
Compare
Hi @chrisburr - I'll ask @cclerget again if he can respond on that as it's related to the wrapping of unsquashfs for security reasons, which he coded up. If he's not able to I'll try to take a look soon. Sorry for the inaction on this. |
It may or may not be relevant that both docker and kubernetes also prevent unprivileged mounting of /proc by default inside containers. They do provide options to enable it though and I don't think it is a security concern when used along with the no new privileges kernel feature that singularity always enables. For reference, the docker option is |
Sorry for the delay, after looking at the issue with
This is caused by
I really doubt sane systems doesn't mount /proc, and in the case where Singularity is run inside a container without |
d6e9c94
to
9c5093a
Compare
Hi @cclerget, thanks for taking a look!
It looks like you're correct and 1990a60 has fixed the issue so that was a much easier fix than I expected. I think this PR is now ready from my perspective. (It's exposed an unrelated issue, #5858, that affects relocation but that's a task for a separate PR.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you very much @chrisburr for your patience and your work 👍 . Added for 3.8 milestone
Opened - apptainer/singularity-admindocs#114 - as a docs reminder for this. |
Description of the Pull Request (PR):
On a few occasions there have have been requests for the singularity binaries to be runtime relocatable (when being used with user-namespaces). Personally, this is interesting to me for
conda-forge
andDIRACOS
which both provide software installations which can be relocated without the need for rebuilding.This is achieved by using
os.Executable
to determine the path the current running binary and path lookups are then modified accordingly. It's my first time writing go so the code might need some work but I'm primarily interested in if this is a feature that you're willing to support?This patch has been used by conda-forge and DIRACOS for the past few months without any issues. Within DIRAC it has been used by O(100,000) continuously running jobs.
This fixes or addresses the following GitHub issues:
Before submitting a PR, make sure you have done the following:
make testall
Attn: @singularity-maintainers