Skip to content
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

Can't execute files from ext4-formatted SDcard #3423

Closed
samee opened this issue Sep 22, 2017 · 12 comments
Closed

Can't execute files from ext4-formatted SDcard #3423

samee opened this issue Sep 22, 2017 · 12 comments
Labels

Comments

@samee
Copy link

samee commented Sep 22, 2017

$ sudo edit-chroot -all
name: xenial
encrypted: no
Entering /mnt/stateful_partition/crouton/chroots/xenial...
crouton: version 1-20170901092920~master:0216f9d1
release: xenial
architecture: armhf
targets: cli-extra
host: version 9592.96.0 (Official Build) stable-channel veyron_minnie 
kernel: Linux localhost 3.14.0 #1 SMP PREEMPT Sat Sep 16 09:49:31 PDT 2017 armv7l armv7l armv7l GNU/Linux
freon: yes
Unmounting /mnt/stateful_partition/crouton/chroots/xenial...

Please describe your issue:

Executable files don't work when they are on an ext4-formatted SD card. They work fine when I copy the executables off the SD-card into root filesystem.

If known, describe the steps to reproduce the issue:

I have an SD card plugged in and mounted:

$ mount -l
[...]
/dev/mmcblk1p1 on /media/removable/SD Card type ext4 (rw,nosuid,nodev,noexec,relatime,dirsync,seclabel,data=ordered)

It is usable from inside my chroot:

$ sudo startcli
Password: 
Entering /mnt/stateful_partition/crouton/chroots/xenial...
(xenial)samee@localhost:~$ cd /var/host/media/removable/SD\ Card/
(xenial)samee@localhost:/var/host/media/removable/SD Card$ echo Hello World > hello.txt
(xenial)samee@localhost:/var/host/media/removable/SD Card$ cat hello.txt
Hello World

I wanted to do some lightweight development using my Chromebook, but was running out of space. SD card was supposed to be the solution. But ran into this issue:

(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ cat myecho.c
#include <stdio.h>

int main(int argc, char* argv[]) {
  for(int i=1;i<argc;++i) printf("%s ", argv[i]);
  printf("\n");
}
(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ gcc myecho.c -o myecho
(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ ./myecho
-su: ./myecho: Permission denied
(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ cp myecho ~
(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ ~/myecho hi there
hi there 
(xenial)samee@localhost:/var/host/media/removable/SD Card/test$ ll
total 24
drwxrwxr-x. 2 samee samee 4096 Sep 21 23:33 ./
drwxrwxrwx. 7 root  root  4096 Sep 21 23:33 ../
-rwxrwxr-x. 1 samee samee 8228 Sep 21 23:33 myecho*
-rw-rw-r--. 1 samee samee  123 Sep 21 23:17 myecho.c

So the file executes when in the root filesystem, but not on the card. I can see the execute bit is properly set. Given the error su error message prefix, I feel like this has something to do with the crouton chroot, but not sure what.

If this is the intended default behavior, let me know what I can do to override it.

@samee
Copy link
Author

samee commented Sep 22, 2017

Clarification: the chroot itself does not live on an SD card. It's just a normal chroot, but has access to the card.

@samee
Copy link
Author

samee commented Sep 22, 2017

Found a partial solution in a similar issue: #1613

Executing sudo mount -o remount,exec /media/removable/SD\ Card/ before sudo startcli does help. But I'm wondering now if this is a property of the chroot, or ChromeOS mount policies. Is there any way I can change how SD cards get mounted in ChromeOS? I mean, I could hack it and add the remount line in the startcli script, but I'd rather not since I delete/reinstall chroots fairly frequently.

Note, the other approach in the linked issue does not work for me. Explicitly using sh is no different from just startcli in my case.

@samee
Copy link
Author

samee commented Sep 22, 2017

And, I just found out, the exec flags gets set back every now and then for no good reason. E.g., when during a long make command off sources on that sd card.

@urjaman
Copy link

urjaman commented Sep 27, 2017

afaik this is a ChromeOS safety feature (it's full of annoying safety features), but i dont know where to turn it off...

@DennisLfromGA
Copy link
Collaborator

@samee,

You may have to prefix your commands with 'sh' if the 'noexec' flag is set.

Hope this helps,
-DennisL

@urjaman
Copy link

urjaman commented Sep 28, 2017

That will help only with manually running shell scripts, not with actual executables on the device, or with actual scripting.

My suggestion is to just mount the fs a second time on a different mount point in the chroot, this way you can change (some, these noexec/dev/suid are included, more low level fs flags will just match the existing mount) of the mount flags for that mount point. (And i think ChromeOS should just not twiddle with a new mount like this, but I didnt do a long-term test so i cant test 100% sure yet.)

@kapilhp
Copy link

kapilhp commented Oct 18, 2017

urjaman's suggestion works!

One can do the following in /etc/rc.local (inside the crouton chroot):

mount --bind /media/removable/SD\ card /srv/mymnt
mount -o remount,exec /srv/mymnt

After that the executables in /srv/mymnt are actually executable without an "sh" or anything. To complete this solution just put /srv/mymnt in PATH in your .profile.

@samee
Copy link
Author

samee commented Oct 19, 2017

urjaman did not suggest remounting the same mount, but mount it again on a different mount point.

First, mounting it twice will likely just fail with "block device busy" but I'll try.

Second, I already tried remounting. It works for a while, but goes back after a few hours. It's not as useful for long-running builds, which keep getting interrupted.

And the sh trick doesn't work, because as urjaman said this is a large Makefile that executes other scripts. Changing them all isn't feasible.

@samee
Copy link
Author

samee commented Oct 19, 2017

But yeah, if somebody knows how to disable stuck safety features, that'd be awesome.

@kapilhp
Copy link

kapilhp commented Oct 19, 2017

You need to run both steps (Edit: inside the chroot):

mount --bind /media/removable/SD\ card /srv/mymnt
mount -o remount,exec /srv/mymnt

The first step mounts the device again at /srv/mymnt. The second one remounts this mount as an exec mount. As a result, your external storage gets mounted at a new mount point which is not controlled by ChromeOS and thus not reverted to a noexec mount.

I have tried this and it works!

@urjaman
Copy link

urjaman commented Oct 19, 2017

That's interesting, changing the exec on a bind mount doesnt propagate to the previous one? I didnt know that, if that works it seems actually cleaner than what I did, but I'll explain anyways.
N.B. Tested what this looks like: it seems the result is identical to what I was suggesting previously, even if the method is different (which hints that bind mounts and the ability to multiply mount the same device are just different sides of the same thing...)

I actually ended up once testing just by remounting the same device again (just mount ./dev/mmcblk1... /another/place) and that worked for the chroot, but the Files app got confused about the SD card (it disappeared? I've forgotten exactly what it did.)

Now that I ended up actually needing the sdcard as exec space, I made a different hack:

[ ! -e /dev/sdcard ] && mknod /dev/sdcard b 179 0 # mmcblk1 device node
mount -o rw,exec /dev/sdcard /home/urjaman/sdcard

This is pretty crude, but yeah made a new device node for mmcblk1 (yeah i have no partition tables on it) and used that to mount it in an another place... this way "mount" lists it as "/dev/sdcard" being mounted somewhere random, instead of /dev/mmcblk1 twice (which is what i think confused Files), and I havent had a problem with this so far.

@urjaman
Copy link

urjaman commented Nov 7, 2017

Just because someone asked for where the noexecery occurs, i found it i think:
https://chromium.googlesource.com/chromiumos/platform2/+/master/cros-disks/mount_options.cc#102

Always. No knobs. [REDACTED].

I suppose if you rebuild cros-disks without those lines and make the rootfs RW and replace it... and then repeat it for every update (thats why I havent done anything that would need rootfs changes, because that would need me making a re-change-the-rootfs script or something.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants