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:
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];
}
}
Here is the rest of the story, how it spawns a privileged sub process differently depending on the OS:
https://github.com/balena-io/etcher/blob/master/lib/gui/app/modules/image-writer.ts#L216
https://github.com/balena-io/etcher/blob/master/lib/shared/permissions.ts#L154