From ef463f82b364e4d192ed2b89b32067cec3a06de9 Mon Sep 17 00:00:00 2001 From: throwaway96 <68320646+throwaway96@users.noreply.github.com> Date: Sun, 3 Mar 2024 17:19:44 -0500 Subject: [PATCH 1/2] service.ts: make runningAsRoot a constant --- services/service.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/services/service.ts b/services/service.ts index 1b3931f..e92c48a 100644 --- a/services/service.ts +++ b/services/service.ts @@ -48,9 +48,12 @@ const availableFlags = { blockUpdates: 'webosbrew_block_updates', } as Record; -function runningAsRoot(): boolean { +const runningAsRoot: boolean = (() => { + if (typeof process.getuid === 'undefined') { + throw new Error('process.getuid() is missing'); + } return process.getuid() === 0; -} +})(); function asyncCall>(srv: Service, uri: string, args: Record): Promise { return new Promise((resolve, reject) => { @@ -120,7 +123,7 @@ function hashString(data: string, algorithm: string): string { * Elevates a package by name. */ async function elevateService(pkg: string): Promise { - if (runningAsRoot()) { + if (runningAsRoot) { console.info('Elevating service...'); await asyncExecFile(path.join(__dirname, 'elevate-service'), [pkg]); } else { @@ -325,7 +328,7 @@ function runService() { service.activityManager.idleTimeout = 30; function getInstallerService(): Service { - if (runningAsRoot()) { + if (runningAsRoot) { return service; } return serviceRemote as Service; @@ -396,7 +399,7 @@ function runService() { // If reelevation fails for some reason the service should still be // reelevated on reboot on devices with persistent autostart hooks (since // we launch elevate-service in startup.sh script) - if (runningAsRoot() && pkginfo && pkginfo.Package === kHomebrewChannelPackageId) { + if (runningAsRoot && pkginfo && pkginfo.Package === kHomebrewChannelPackageId) { message.respond({ statusText: 'Self-update…' }); await createToast('Performing self-update...', service); @@ -484,7 +487,7 @@ function runService() { */ service.register( 'checkRoot', - tryRespond(async () => ({ returnValue: runningAsRoot() })), + tryRespond(async () => ({ returnValue: runningAsRoot })), ); /** @@ -493,7 +496,7 @@ function runService() { service.register( 'updateStartupScript', tryRespond(async () => { - if (!runningAsRoot()) { + if (!runningAsRoot) { return { returnValue: true, statusText: 'Not running as root.' }; } @@ -666,7 +669,7 @@ function runService() { service.register( 'autostart', tryRespond(async (message) => { - if (!runningAsRoot()) { + if (!runningAsRoot) { return { message: 'Not running as root.', returnValue: true }; } if (await asyncExists('/tmp/webosbrew_startup')) { From 7d58dcaa80f5e3cb6c4f29b386a7f5b48a4fcd71 Mon Sep 17 00:00:00 2001 From: throwaway96 <68320646+throwaway96@users.noreply.github.com> Date: Wed, 28 Feb 2024 22:42:51 -0500 Subject: [PATCH 2/2] service.ts: add /elevateService method --- services/service.ts | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/services/service.ts b/services/service.ts index e92c48a..40b1541 100644 --- a/services/service.ts +++ b/services/service.ts @@ -122,13 +122,15 @@ function hashString(data: string, algorithm: string): string { /** * Elevates a package by name. */ -async function elevateService(pkg: string): Promise { - if (runningAsRoot) { - console.info('Elevating service...'); - await asyncExecFile(path.join(__dirname, 'elevate-service'), [pkg]); - } else { +async function elevateService(pkg: string): Promise { + if (!runningAsRoot) { console.error('Trying to elevate service without running as root. Skipping.'); + return false; } + + console.info('Elevating service...'); + await asyncExecFile(path.join(__dirname, 'elevate-service'), [pkg]); + return true; } /** @@ -706,6 +708,35 @@ function runService() { return { returnValue: true }; }), ); + + /** + * Elevates the service specified by "id". + */ + type ElevateServicePayload = { id: string }; + service.register( + 'elevateService', + tryRespond(async (message: Message) => { + if (!('id' in message.payload)) { + throw new Error('missing "id"'); + } else if (typeof message.payload['id'] !== 'string') { + throw new Error('"id" is not a string'); + } else if (message.payload['id'] === '') { + throw new Error('"id" is empty'); + } + + if (!runningAsRoot) { + throw new Error('not running as root'); + } + + const payload = message.payload as ElevateServicePayload; + + const status = await elevateService(payload.id); + + if (!status) { + throw new Error('elevateService() failed'); + } + }), + ); } if (process.argv[2] === 'self-update') {