* How to add /bin/sh to the build environment
@ 2021-11-08 9:25 Foo Chuan Wei
2021-11-08 16:54 ` Xinglu Chen
0 siblings, 1 reply; 8+ messages in thread
From: Foo Chuan Wei @ 2021-11-08 9:25 UTC (permalink / raw)
To: help-guix
I am trying to package the Standard ML of New Jersey (SML/NJ) compiler
in Guix. My current understanding is that its installation process
relies on the existence of /bin/sh in a fundamental way. Is there a way
to add /bin/sh to the build environment?
In the build phase of the package definition, I tried something like
this:
(mkdir-p "/bin")
(symlink (which "sh") "/bin/sh")
However, `mkdir-p` always fails with:
ice-9/boot-9.scm:1669:16: In procedure raise-exception:
In procedure mkdir: Permission denied
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-08 9:25 How to add /bin/sh to the build environment Foo Chuan Wei
@ 2021-11-08 16:54 ` Xinglu Chen
2021-11-08 20:19 ` Foo Chuan Wei
0 siblings, 1 reply; 8+ messages in thread
From: Xinglu Chen @ 2021-11-08 16:54 UTC (permalink / raw)
To: Foo Chuan Wei, help-guix
[-- Attachment #1: Type: text/plain, Size: 767 bytes --]
Hi,
On Mon, Nov 08 2021, Foo Chuan Wei wrote:
> I am trying to package the Standard ML of New Jersey (SML/NJ) compiler
> in Guix. My current understanding is that its installation process
> relies on the existence of /bin/sh in a fundamental way. Is there a way
> to add /bin/sh to the build environment?
>
> In the build phase of the package definition, I tried something like
> this:
>
> (mkdir-p "/bin")
> (symlink (which "sh") "/bin/sh")
I would use ‘substitute*’ from (guix build utils) to patch the
references to /bin/sh
(lambda* (#:key inputs #:allow-other-keys)
(let ((sh (assoc-ref inputs "bash")))
(substitute* "some-file"
(("\"/bin/sh\"") (string-append "\"" sh "/bin/sh\"")))))
Hope that helps!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-08 16:54 ` Xinglu Chen
@ 2021-11-08 20:19 ` Foo Chuan Wei
2021-11-08 22:23 ` Leo Famulari
2021-11-08 22:58 ` Philip McGrath
0 siblings, 2 replies; 8+ messages in thread
From: Foo Chuan Wei @ 2021-11-08 20:19 UTC (permalink / raw)
To: Xinglu Chen; +Cc: help-guix
On 2021-11-08 17:54 +0100, Xinglu Chen wrote:
> I would use ‘substitute*’ from (guix build utils) to patch the
> references to /bin/sh
>
> (lambda* (#:key inputs #:allow-other-keys)
> (let ((sh (assoc-ref inputs "bash")))
> (substitute* "some-file"
> (("\"/bin/sh\"") (string-append "\"" sh "/bin/sh\"")))))
>
> Hope that helps!
Thank you for the suggestion, but this will not work for packaging
SML/NJ. The build process depends on the existence of /bin/sh in a
fundamental way:
* Part of the build process relies on programs written in Standard ML.
* The part written in Standard ML uses a function from the SML Basis
Library: `OS.Process.system`.
* `OS.Process.system` will always use /bin/sh. This is hardcoded. I
cannot change it. If I change it, the behavior of `OS.Process.system`
would probably be wrong in the final product (the sml compiler).
I'm not even sure if I can use `substitute*`, since the build process
relies on binary "bootfiles" where /bin/sh is hardcoded.
Note that I've managed to work around the problem.
Before building:
* Create a symlink /tmp/sh that points to `(which "sh")`.
* Edit the binary bootfiles so that they use /tmp/sh instead of /bin/sh.
After building:
* Edit the resulting binaries so that they use /bin/sh instead of /tmp/sh.
Is there really no way to create /bin/sh in the build environment, so
that binary patching can be avoided?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-08 20:19 ` Foo Chuan Wei
@ 2021-11-08 22:23 ` Leo Famulari
2021-11-09 1:36 ` Philip McGrath
2021-11-08 22:58 ` Philip McGrath
1 sibling, 1 reply; 8+ messages in thread
From: Leo Famulari @ 2021-11-08 22:23 UTC (permalink / raw)
To: Xinglu Chen, help-guix
As you found, it's not possible to write to the root directory of the
build environment as the build user.
I don't remember exactly, but I believe this was done as part of the fix
for CVE-2021-27851 [0].
Of course it can be annoying that /bin/sh cannot be added to the build
environment, but specifying a particular shell is an important part of
how Guix achieves the functional packaging model.
Relying on /bin/sh while building *could* be done properly with some
care, but since its use could indicate that the package will use /bin/sh
at run-time, we choose to omit it from the build environment, although
it does exist on Guix System and most systems that Guix supports.
On Mon, Nov 08, 2021 at 08:19:27PM +0000, Foo Chuan Wei wrote:
> * `OS.Process.system` will always use /bin/sh. This is hardcoded. I
> cannot change it. If I change it, the behavior of `OS.Process.system`
> would probably be wrong in the final product (the sml compiler).
>
> I'm not even sure if I can use `substitute*`, since the build process
> relies on binary "bootfiles" where /bin/sh is hardcoded.
It will be necessary to fix this issue in the SML/NJ package definition
(I think you've done this in a followup patch), because Guix does not
accept packages that rely on pre-built binaries — everything must be
built from source code. There are some exceptions but I don't think that
SML/NJ will qualify due to its obscurity compared to other language
implementations. If SML/NJ cannot be built without the binary bootfiles,
it probably won't be eligible for inclusion in GNU Guix.
[0] The CVE ID will appear on the blog post shortly... it took several
weeks to get the ID assigned and I forgot to add it to the blog post
until now.
https://guix.gnu.org/en/blog/2021/risk-of-local-privilege-escalation-via-guix-daemon/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-08 20:19 ` Foo Chuan Wei
2021-11-08 22:23 ` Leo Famulari
@ 2021-11-08 22:58 ` Philip McGrath
1 sibling, 0 replies; 8+ messages in thread
From: Philip McGrath @ 2021-11-08 22:58 UTC (permalink / raw)
To: Xinglu Chen, help-guix
Hi,
On 11/8/21 15:19, Foo Chuan Wei wrote:
> * Part of the build process relies on programs written in Standard ML.
> * The part written in Standard ML uses a function from the SML Basis
> Library: `OS.Process.system`.
> * `OS.Process.system` will always use /bin/sh. This is hardcoded. I
> cannot change it. If I change it, the behavior of `OS.Process.system`
> would probably be wrong in the final product (the sml compiler).
A similar issue came up for Racket, which has a family of functions like
`process` and `system` that execute commands using `sh`.[0]
Maybe this kind of function is common enough in programming language
implementations that it should be documented in the Guix manual's
packaging guidelines? For example, even libc has a `system` function
specified to use "/bin/sh" (I haven't looked at how Guix handles it).
Part of the issue with Guix is that, even if you somehow arranged for
"/bin/sh" to exist in the build environment, Guix users will likely also
want to run the SML/NJ compiler and compiled SML/NJ programs in
environments where "/bin/sh" doesn't exist. For Racket, thanks to some
discussion with Jack Hill,[1] I added a patch that uses a Guix-specific
C preprocessor macro to intercept attempts to execute "/bin/sh" in
librktio (Racket's cross-platform IO library) and substitute the store
path to Guix's `bash-minimal`. The current patch is at [2].
(A subtlety I'd forgotten is that, in addition to functions like
`system` that are specified to use `sh`, Racket's build process was also
calling functions like `system*`, which are more like `execve`, with
"/bin/sh" as an argument. Since that approach is recommended for
portability and robustness, the patch intercepts those attempts, too.)
The approach was especially defensible for Racket because the Racket
Reference merely specifies that the functions will use some `sh`, not
that it will be any particular `sh` or will be located at any particular
path. From a quick look at the SML Basis Library reference[3], it
specifies that `OS.Process.system` uses "the operating system's default
shell", though it does go on to say that, "on Unix systems" (but
apparently not Mac OS?), the default shell is '/bin/sh'". Since Guix
doesn't really have a "default shell" in general, I think using the an
explicit package input might make sense for SML/NJ's
`OS.Process.system`, too.
[0]:
https://docs.racket-lang.org/reference/subprocess.html#%28def._%28%28lib._racket%2Fsystem..rkt%29._process%29%29
[1]: https://issues.guix.gnu.org/47180
[2]:
https://git.savannah.gnu.org/gitweb/?p=guix.git;a=blob;f=gnu/packages/patches/racket-minimal-sh-via-rktio.patch;h=6bc2ee8331f046959fd493f8e1604e682ddc4a0d;hb=HEAD
[3]:
https://smlfamily.github.io/Basis/os-process.html#SIG:OS_PROCESS.system:VAL
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-08 22:23 ` Leo Famulari
@ 2021-11-09 1:36 ` Philip McGrath
2021-11-09 3:51 ` Foo Chuan Wei
2021-11-10 1:41 ` Leo Famulari
0 siblings, 2 replies; 8+ messages in thread
From: Philip McGrath @ 2021-11-09 1:36 UTC (permalink / raw)
To: Leo Famulari, Xinglu Chen, help-guix
(I wrote my earlier reply before I saw Leo's.)
On 11/8/21 17:23, Leo Famulari wrote:
> It will be necessary to fix this issue in the SML/NJ package definition
> (I think you've done this in a followup patch)
Is this <https://issues.guix.gnu.org/38606>, or somewhere else?
> Guix does not
> accept packages that rely on pre-built binaries — everything must be
> built from source code. There are some exceptions but I don't think that
> SML/NJ will qualify due to its obscurity compared to other language
> implementations. If SML/NJ cannot be built without the binary bootfiles,
> it probably won't be eligible for inclusion in GNU Guix.
Mostly I wanted to follow up to say that, from my perspective, SML/NJ is
a very noteworthy and influential language implementation. Perhaps the
most familiar example for Guix folks would be that Guile's fibers are
based on Concurrent ML, which is an SML/NJ extension:
https://wingolog.org/archives/2017/06/29/a-new-concurrent-ml
Personally I've only read ML, not written it, but from a Debian bug I
found through searching online
(<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=220046>), it appears
that there are no known Standard ML implementations that avoid this
bootstrapping problem. SML/NJ, in addition to being one of the most
important implementations in its own right, is apparently capable of
bootstrapping at least one other implementation, MLton. (Unlike some on
that thread, I don't consider the 5x slowdown for the bootstrap build to
be prohibitive: bootstrapping Chez Scheme via Racket has a 10x slowdown.)
It is very valuable that Guix maintains such high standards for
bootstrapping from source. However, Guix does still contain some
compilers that have bootstrapping limitations. SML/NJ is no worse that
Chez Scheme in this respect, and comparably important. (One difference
is that there is a path to backporting the bootstrap simulation from
Racket's fork to the upstream variant, which would remove the
problem---but I don't that wasn't true when Chez Scheme was first added
to Guix.) The status quo is that no Standard ML language implementation
at all seems to be in Guix. I think including SML/NJ would be better
than waiting for someone to write a hypothetical Standard ML compiler in
a host language with a better bootstrapping story.
-Philip
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-09 1:36 ` Philip McGrath
@ 2021-11-09 3:51 ` Foo Chuan Wei
2021-11-10 1:41 ` Leo Famulari
1 sibling, 0 replies; 8+ messages in thread
From: Foo Chuan Wei @ 2021-11-09 3:51 UTC (permalink / raw)
To: philip; +Cc: help-guix
On 2021-11-08 20:36 -0500, Philip McGrath wrote:
> On 11/8/21 17:23, Leo Famulari wrote:
> > It will be necessary to fix this issue in the SML/NJ package definition
> > (I think you've done this in a followup patch)
>
> Is this <https://issues.guix.gnu.org/38606>, or somewhere else?
On 2021-11-07, I submitted a patch that can be found at
https://issues.guix.gnu.org/38606, but that patch doesn't fix the
/bin/sh issue. It merely avoids the issue by disabling the building of
SML/NJ libraries. `OS.Process.system` is used during the building of
SML/NJ libraries.
I eventually figured out how to build the whole thing (including
libraries), but it involves using `sed` to patch strings in some
binaries. I will submit a non-WIP patch, hopefully within this week.
By the way, should I submit the new patch to
https://issues.guix.gnu.org/38606 (38606@debbugs.gnu.org), or should I
start a new thread by submitting it to guix-patches@gnu.org?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: How to add /bin/sh to the build environment
2021-11-09 1:36 ` Philip McGrath
2021-11-09 3:51 ` Foo Chuan Wei
@ 2021-11-10 1:41 ` Leo Famulari
1 sibling, 0 replies; 8+ messages in thread
From: Leo Famulari @ 2021-11-10 1:41 UTC (permalink / raw)
To: Philip McGrath; +Cc: help-guix, Xinglu Chen
On Mon, Nov 08, 2021 at 08:36:08PM -0500, Philip McGrath wrote:
> Mostly I wanted to follow up to say that, from my perspective, SML/NJ is a
> very noteworthy and influential language implementation. Perhaps the most
> familiar example for Guix folks would be that Guile's fibers are based on
> Concurrent ML, which is an SML/NJ extension:
> https://wingolog.org/archives/2017/06/29/a-new-concurrent-ml
Thanks for sharing your knowledge. I stand corrected!
> Personally I've only read ML, not written it, but from a Debian bug I found
> through searching online
> (<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=220046>), it appears
> that there are no known Standard ML implementations that avoid this
> bootstrapping problem. SML/NJ, in addition to being one of the most
> important implementations in its own right, is apparently capable of
> bootstrapping at least one other implementation, MLton. (Unlike some on that
> thread, I don't consider the 5x slowdown for the bootstrap build to be
> prohibitive: bootstrapping Chez Scheme via Racket has a 10x slowdown.)
>
> It is very valuable that Guix maintains such high standards for
> bootstrapping from source. However, Guix does still contain some compilers
> that have bootstrapping limitations. SML/NJ is no worse that Chez Scheme in
> this respect, and comparably important. (One difference is that there is a
> path to backporting the bootstrap simulation from Racket's fork to the
> upstream variant, which would remove the problem---but I don't that wasn't
> true when Chez Scheme was first added to Guix.) The status quo is that no
> Standard ML language implementation at all seems to be in Guix. I think
> including SML/NJ would be better than waiting for someone to write a
> hypothetical Standard ML compiler in a host language with a better
> bootstrapping story.
I see. Maybe it's worth attempting to patch the binary to use /tmp/sh
while bootstrapping, in that case. Or maybe there *is* some way to add
/bin/sh to the build environment for just this package, without
having to make the change for all packages, which would be undesirable.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-11-10 1:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-08 9:25 How to add /bin/sh to the build environment Foo Chuan Wei
2021-11-08 16:54 ` Xinglu Chen
2021-11-08 20:19 ` Foo Chuan Wei
2021-11-08 22:23 ` Leo Famulari
2021-11-09 1:36 ` Philip McGrath
2021-11-09 3:51 ` Foo Chuan Wei
2021-11-10 1:41 ` Leo Famulari
2021-11-08 22:58 ` Philip McGrath
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).