balena-io-modules/mountutils

Curious about how does balena etcher get permission to unmount disks?

ForestJohnson opened this issue · 4 comments

Hello, forgive my ignorance as I am primarily a web developer and not as familiar with Node.js C++ modules. However I believe that really these things should be documented for "the rest of us".


I am developing an application using https://github.com/balena-io-modules/etcher-sdk

when I run

    MOUNTUTILS_DEBUG=1 npm start

and my code runs

    etcherSDK.multiWrite.decompressThenFlash({...})

then I see in the log

    [mountutils] Reading /proc/mounts
    [mountutils] Mount point /dev/sdc2 belongs to drive /dev/sdc
    [mountutils] Mount point /dev/sdc1 belongs to drive /dev/sdc
    [mountutils] Closing /proc/mounts
    [mountutils] Unmounting /media/forest/rootfs...
    [mountutils] Unmount MNT_EXPIRE /media/forest/rootfs: EAGAIN
    [mountutils] Unmount MNT_EXPIRE /media/forest/rootfs failed: Operation not permitted
    [mountutils] Unmount MNT_DETACH /media/forest/rootfs failed: Operation not permitted
    [mountutils] Unmount MNT_FORCE /media/forest/rootfs failed: Operation not permitted
    [mountutils] Unmounting /media/forest/boot...
    [mountutils] Unmount MNT_EXPIRE /media/forest/boot: EAGAIN
    [mountutils] Unmount MNT_EXPIRE /media/forest/boot failed: Operation not permitted
    [mountutils] Unmount MNT_DETACH /media/forest/boot failed: Operation not permitted
    [mountutils] Unmount MNT_FORCE /media/forest/boot failed: Operation not permitted
    [mountutils] Unmount complete

and onFail() gets called with "Unmount failed". This seems weird to me because according to the C code it should return "Unmount failed, access denied" when its a permissions issue: https://github.com/balena-io-modules/mountutils/blob/master/src/worker-unmount.cpp#L28

I am curious how does this work in production for balena etcher? currently I am just debugging on linux but of course I want this to work cross platform later on... how to get permission to unmount disks should be documented on https://github.com/balena-io-modules/etcher-sdk or https://github.com/balena-io-modules/mountutils!

is something like CAP_NET but for unmounting disks in linux ? (a way to allow a process to unmount disks even though its not running as root) or a way to trigger a "please enter your admin password to elevate privilege" prompt for a process ??

OK so I'm a dummy, I thought I remembered that Etcher worked in Linux without asking for admin password but now I am starting to learn, it looks like on linux it spawns a privileged process:

auth

and I am suspicious that this is related: https://github.com/balena-io/etcher/blob/master/afterPack.js

This looks related, how it reaches inside the AppImage on linux to spawn a sub-process

https://github.com/balena-io/etcher/blob/master/lib/gui/app/modules/image-writer.ts#L95

function writerArgv(): string[] {
	let entryPoint = path.join(
		electron.remote.app.getAppPath(),
		'generated',
		'child-writer.js',
	);
	// AppImages run over FUSE, so the files inside the mount point
	// can only be accessed by the user that mounted the AppImage.
	// This means we can't re-spawn Etcher as root from the same
	// mount-point, and as a workaround, we re-mount the original
	// AppImage as root.
	if (os.platform() === 'linux' && process.env.APPIMAGE && process.env.APPDIR) {
		entryPoint = entryPoint.replace(process.env.APPDIR, '');
		return [
			process.env.APPIMAGE,
			'-e',
			`require(\`\${process.env.APPDIR}${entryPoint}\`)`,
		];
	} else {
		return [process.argv[0], entryPoint];
	}
}