This is quite ironic. It appears to be working with the hardened kernel from Arch Linux though.
rfs613 reported in IRC:
Just as an FYI... while pmbootstrap installs an alpine linux chroot, this doesn't work if your host OS is Alpine.
More specifically, if you use the default grsec-enabled Alpine.
the chroot command works, but inside the chroot, you cannot install setuid binaries. So "apk add sudo" fails with a permission error.
This is apparently a grsec feature. It can be disabled, or you can run vanilla kernel (no grsec) to get around it.
Looks like it works in Arch, because it only uses 2% or so from the original grsec patchset. (source as found by rfs613). (For some context, grsec is a hardening patchset, that some distros have used. grsec doesn't distribute its patchset openly anymore, so distributions have renamed their grsec kernels to "hardened" and use some sort of fork now.)
cmdr2 reported in IRC that sysctl -w kernel.grsecurity.chroot_deny_chmod=0 does disable grsec in Alpine and pmbootstrap works.
I think we could check for that option, before executing any command in a chroot the first time in a pmbootstrap session (the lifetime of one pmbootstrap command, such as "chroot" or "install") and throw an error, telling the user how to turn this off. Then we could close this issue :)
To comprehensively disable grsec until the next reboot, I suggest:
ls -1 /proc/sys/kernel/grsecurity | xargs -I '___' sudo sysctl -w kernel.grsecurity.___=0
The previous sysctl command I suggested only disables one flag, and the build fails later due to some other flag blocking it. That throws a 'mv ..... : could not preserve permissions' error (something like that, can't find the error now).
Thanks for the details, @cmdr2 and @PabloCastellano!
@cmdr2, could you test if the following script raises an exception, when the option is enabled, and runs through without complaining when it is not?
Then we could add a check like that to pmbootstrap and close this ticket :+1:
#!/usr/bin/env python3
import os
def grsec_check():
path = "/proc/sys/kernel/grsecurity/chroot_deny_chmod"
if not os.path.exists(path):
return
with open(path, "r") as handle:
status = handle.readlines()[0].rstrip()
if status != "0":
raise RuntimeError("You're running a kernel based on the grsec"
" patchset. To get pmbootstrap working, you"
" will need to disable some options with"
" sysctl: (link to a wiki page here).")
grsec_check()
Yeah, seems fair. I ran the script and it behaves as expected.
With grsec enabled:
$ sudo python grsec_check.py
Traceback (most recent call last):
File "grsec_check.py", line 19, in <module>
grsec_check()
File "grsec_check.py", line 13, in grsec_check
raise RuntimeError("You're running a kernel based on the grsec"
RuntimeError: You're running a kernel based on the grsec patchset. To get pmbootstrap working, you will need to disable some options with sysctl: (link to a wiki page here).`
With grsec disabled:
$ sudo python grsec_check.py
$
BTW, this fix needs to read the file with root permissions. It is currently failing the build because ./pmbootstrap is run as a normal user, and doesn't have permissions to read the grsec proc file.
with open(path, "r") as handle:
status = handle.readlines()[0].rstrip()
Sorry I missed this earlier because I ran the script in the previous comment with 'sudo'. I didn't get a chance to write a patch for this today.
Okay, thanks again for the feedback, I'll reopen this ticket.
If you want to write a patch, I recommend reading the file with something like this:
status = pmb.helpers.run.root(args, ["cat", "/path/to/proc"], return_stdout=True).rstrip()
The way it is currently implemented, it would read the file whenever a command gets executed inside the chroot, so we should probably cache the result for one pmbootstrap session.
Another thought: this only makes sense, if we can get the grsec/hardened kernel to work at all (as you've mentioned other problems in the channel with qemu #140). If we can't get it to work, we could simply check if the path exists and always raise the exception.
Thanks! If it is something quick for you, and not too much trouble, could you please check that line in? :) I seem to have messed up my fork and I won't be able to get to this before this Sunday. But I'm not sure if anyone else is working with a grsec host, so it might not be all that urgent.
You're right about the trade-off with the hardened kernel. I'll give the qemu error on my host one more look this weekend and see if it can be made to work, otherwise it seems fair to require a non-hardened kernel for now.
Sure, I'll check it in. I guess, that you are the only one working with the grsec-based kernel as of now.
But now we have at least the check and display a meaningful message when it is enabled and too restrictive. That's a good improvement already, and it can be picked up from there, if there is interest :+1:
Okay, I bravely ran away from grsec, and all the issues with qemu hanging and failing (#140) got fixed after switching to a vanilla (non-hardened) kernel. So I'd vote to throw an error if grsec is detected, until someone decides to take up the cause.
Good that we already do that :)
I just tried to give pmbootstrap a try. I downloaded and installed an Alpine standard ISO, as postmarketOS is based on it, and tried to run pmbootstrap in it, but it failed due to the grsec issue.
I'd recommend adding the requirement of a vanilla kernel to the README, maybe even the message
in https://github.com/postmarketOS/pmbootstrap/blob/1c13ca4fd9e32952a8e559987f82cd0925cddee9/pmb/helpers/other.py#L48