Setting Linux Capabilities in Yocto ext4 Image - linux

I intend to set some capabilities on binaries included in a Yocto image using "setcap". For some reason the solutions mentioned here did not work for me:
Linux capabilities with yocto
. I have checked that by running "getcap" on my binary within the rootfs creation directory:
getcap ${IMAGE_ROOTFS}/usr/bin/mybinary
does not return anything. Nor do I find the capabilities in the final running sdcard image.
Next I tried the approach using IMAGE_PREPROCESS_COMMAND. I wrapped up setcap commands in small shell functions such as:
my_setcap_function() {
sudo setcap cap_ipc_owner+ep ${IMAGE_ROOTFS}/usr/bin/mybinary
}
and append the function names to IMAGE_PREPROCESS_COMMAND. This works to the extent that now running getcap on my binary within the {IMAGE_ROOTFS} directory does show the correct caps set. However I still do not get the capabilities in the final running sdcard image.
Also if I mount the rootfs ext4 (which is used to create the final sdcard image) on a directory using -o loop, I do not see the capabilities on my binary.
It seems to me that the capabilitiess somehow get lost when the ext4 is created using mkfs.ext4.
I had to attach sudo to setcap because otherwise it complains saying "unable to set CAP_SETFCAP effective capability: Operation not permitted". Although my understanding was that IMAGE_PREPROCESS_COMMAND commands are run using fakeroot so this sudo should not be required.
So, to summarize my question:
How can I get the capabilities on the sdcard image made using ext4 rootfs image?
I want to use a way that does not require using "sudo".
I am using Yocto Krogoth and currently cannot upgrade that.

Did you really test it on the final image or in the rootfs folder from the yocto build?
I run getcap on the files in the rootfs folder, and there where nothing set.
Because yocto uses pseudo lib to intercept chown, chmod calls, track them in a sqlite db (uses LD_PRELOAD for interception).
So this attributes are not set for the files in the "rootfs" folder, however added at image/rootfs creation.
you can use setcap in recipe, you have to add
DEPENDS = "libcap-native"
in your recipe.

Related

How to run custom program in initramfs

I have built initramfs which I want to use for setting up dm-verity. For testing purposes I don't switch_root and after boot it stays in initramfs. However I need the tool veritysetup. I have it precompiled and copied to /usr/sbin on initramfs, but when I run it on the platform it says - /bin/sh: /usr/sbin/veritysetup: not found. Any ideas how to make it execute?
Yes, I have done this.
For a hint let me first give a simple clue first.
For veritysetup command to work in your initramfs you also need to copy all the dependent libraries (same architecture) to your libs folder inside initramfs.

Yocto Custom Layer run Tune2fs on do_rootfs after mkfs.ext4

I'm using Yocto on Ubuntu 18.04 with the Warrior Branch of Meta-Tegra in order to try to integrate the RAUC Open Source project for Linux Firmware Updates.
I've learned that U-Boot has issues writing to EXT4 partitions ( to update the U-Boot Env ) if the EXT4 filesystem it is writing to has the metadata_csum attribute. Linux cannot mount the Root Filesystem if that attribute is enabled and U-Boot writes at all to it.
Here are some posts on that:
https://patchwork.ozlabs.org/patch/818337/
http://u-boot.10912.n7.nabble.com/PATCH-1-1-fs-ext4-do-not-write-on-filesystem-with-metadata-csum-feature-td362715.html
I proved that this is the case by mounting the resulting SDCARD image from Yocto on Ubuntu and running the following command to disable metadata_csum:
sudo tune2fs -O ^metadata_csum /dev/sdb1
tune2fs 1.44.1 (24-Mar-2018)
Disabling checksums could take some time.
Proceed anyway (or wait 5 seconds to proceed) ? (y,N) y
After running that command - U-Boot can read/write at will from U-Boot space and Linux can mount the Root File System.
I am trying to figure out how to disable the checksums with Tune2fs on Ubuntu at image creation time with Yocto. Where/How can I add this so that the image has checksums disabled at image creation time from Yocto?
I briefly looked over meta-tegra and I think it uses the ext4 root filesystem image created through image_class.bcclass. You can add parameters to the mkfs.ext4 thorugh EXTRA_IMAGECMD. It should be possible to just create the filesystem with metadata_csum disabled, instead of turning it off later.
Try
EXTRA_IMAGECMD_append = " -O ^metadata_csum"
in your local.conf

how to reset kernel while the device is booted up?

How to replace the contents of rootfs partition while the device is booted up?
I am using pine64 (1GB) with stripped debian version and struck in writing a factory reset script which will replace all files in the rootfs partition while the device is running? resident restore file could be tar or img file.
I have already tried two approaches
dd the partition from image to the partition on device.
sudo dd if=pine-debian.img skip=*start of rootfs partition* seek=*start of rootfs partition* of=/dev/mmcblk0
Extract the compressed content to the / directory.
sudo tar -C / -zxvf pine-debian.tar.gz
After both the approaches, the system can recognize any command, not even ls. Any help will be appreciated about how to solve this. how to replace fs content while the device is running?
Ideally, you should have two partitions each with a copy of the rootfs. You can write the partition that is currently not in use with dd, and then update the bootloader configuration to point to the just written partition as the root. swupdate supports such a dual-bank scenario, but it only has native support for U-Boot; if you use a different bootloader, you'll have to add a script to perform the swap.
If you really need to overwrite in-place, directly overwriting the partition is not possible because that filesystem is currently in use. Untarring will also fail because some files are currently in use - in particular libc. You could try to add the --unlink-first option to the untar command, but I'm not sure if that works.
Two other options:
Instead of overwriting the full rootfs, use Debian package upgrades. They have pre- and post-install scripts to make the upgrade safe.
Swap to a (temporary, small) in-RAM root filesystem to perform the upgrade. This root filesystem should just contain busybox and the script that performs the upgrade. You can either kill all processes and then do a pivot_root into the temporary rootfs, or you can use kexec --initrd=... to boot into the in-RAM root filesystem.

Install chromium to Linux disk image?

I'm sure this has been asked before but I have no clue what to search for
I am trying to create a custom Linux image (for the Raspberry Pi) - I am currently manipulating the filesystem of the .img but I've discovered it's not as simple as dropping in the binary :( if only...
What is the accepted way to "pre-install" a package on a disk image where you can only manipulate the filesystem and ideally not run it first? Am I best to boot up, install, and then create the image from that, or is there a way of doing it beforehand in the same way you can change configuration settings etc?
Usually, when I have to change something in a disk image, I do the following:
sudo mount --bind /proc /mnt/disk_image/proc
sudo mount --bind /sys /mnt/disk_image/sys
sudo mount --bind /dev /mnt/disk_image/dev
These action are needed as this folder are create during boot process, mounting them in your system image will emulate a full boot. Then, you can chroot on it safely:
sudo chroot /mnt/disk_image
You're now able to issue commands in the chroot environment:
sudo apt-get install chromium
Of course, change /mnt/disk_image to the path where you have mounted your filesystem. apt-get will only works on Debian based system, change it according to your distribution.
You could find problem connecting to the internet and it can be cause by DNS configuration. The best thing you can do, is to copy your /etc/resolv.conf file in the remote filesystem as this file is usually changed by dhcp and it's empty on chroot environment.
This is the only solution that gives you full access to the command line of the system you're trying to modify.
This is an untested idea:
The dpkg tool, which can install .deb packages, has a --root option which can set a different filesystem than the local / path.
From the man page:
--instdir=dir
Change default installation directory which refers to the
directory where packages are to be installed. instdir is
also the directory passed to chroot(2) before running
package’s installation scripts, which means that the
scripts see instdir as a root directory. (Defaults to /)
--root=dir
Changing root changes instdir to dir and admindir to
dir/var/lib/dpkg.
If you mount your image and pass its mountpoint as --root, it should work.
There are things like the Ubuntu Customization Kit which allow you to create your own version of the distro with your own packages.
Crunchbang even has a utility like this, which is the distro I have personally selected for experimenting with my Pi.

Can oprofile be made to use a directory other than /root/.oprofile?

We're trying to use oprofile to track down performance problems on a server cluster. However, the servers in question have a read-only file system, where /var/tmp is the only writeable directory.
OProfile wants to create two directories whenever it runs: /root/.oprofile and /var/lib/oprofile, but it can't, because the filesystem is read-only. I can use the --session-dir command line option to make it write its logs to elsewhere than /var/lib, but I can't find any such option to make it use some other directory than /root/.oprofile.
The filesystem is read-only because it is on nonwriteable media, not because of permissions -- ie, not even superuser can write to those directories. We can cook a new ROM image of the filesystem (which is how we installed oprofile, obviously), but there is no way for a runtime program to write to /root, whether it is superuser or not.
I tried creating a symlink in the ROM that points /root/.oprofile -> /var/tmp/oprofile, but apparently oprofile doesn't see this symlink as a directory, and fails when run:
redacted#redacted:~$ sudo opcontrol --no-vmlinux --start --session-dir=/var/tmp/oprofile/foo
mkdir: cannot create directory `/root/.oprofile': File exists
Couldn't mkdir -p /root/.oprofile
We must run our profilers on this particular system, because the performance issues we're trying to investigate don't manifest if we build and run the app on a development server. We can't just run our tests on a programmer's workstation and profile the app there, because the problem doesn't happen there.
Is there some way to configure oprofile so that it doesn't use /root ?
I guess it should be as simple as overriding the HOME environment variable:
HOME=/tmp/fakehome sudo -E opcontrol --no-vmlinux --start --session-dir=/var/tmp/oprofile/foo
If that doesn't work out, you could have a look at
unionfs
aufs
to create a writable overlay. You might even just mount tmpfs on /root,or something simple like that.
It turns out that this directory is hardcoded into the opcontrol bash script:
# location for daemon setup information
SETUP_DIR="/root/.oprofile"
SETUP_FILE="$SETUP_DIR/daemonrc"
Editing those lines seemed to get it working, more or less.

Resources