diff --git a/services/better-jail.ts b/services/better-jail.ts new file mode 100644 index 0000000..f4b5e40 --- /dev/null +++ b/services/better-jail.ts @@ -0,0 +1,6 @@ +import { asyncExecFile } from './adapter'; + +export async function buildBetterJail(id: string, appDir: string) { + // Populate the jail with `native` instead of `native_devmode`, to gain higher privileges + await asyncExecFile('jailer', ['-t', 'native', '-p', appDir, '-i', id, '/bin/true']); +} diff --git a/services/service.ts b/services/service.ts index 2160fce..2835ccf 100644 --- a/services/service.ts +++ b/services/service.ts @@ -13,6 +13,7 @@ import Service, { Message } from 'webos-service'; import { asyncStat, asyncExecFile, asyncPipeline, asyncUnlink, asyncWriteFile, asyncReadFile, asyncChmod, asyncMkdir } from './adapter'; import { fetchWrapper } from './fetch-wrapper'; +import { buildBetterJail } from './better-jail'; import rootAppInfo from '../appinfo.json'; import serviceInfo from './services.json'; @@ -406,12 +407,17 @@ function runService(): void { return serviceRemote as Service; } - async function getAppInfo(appId: string): Promise> { - const appList = await asyncCall<{ apps: { id: string }[] }>( - getInstallerService(), - 'luna://com.webos.applicationManager/dev/listApps', - {}, - ); + interface AppInfo { + id: string; + title: string; + type: string; + folderPath: string; + } + interface AppsList { + apps: AppInfo[]; + } + async function getAppInfo(appId: string): Promise { + const appList = await asyncCall(getInstallerService(), 'luna://com.webos.applicationManager/dev/listApps', {}); const appInfo = appList.apps.find((app) => app.id === appId); if (!appInfo) throw new Error(`Invalid appId, or unsupported application type: ${appId}`); return appInfo; @@ -491,7 +497,13 @@ function runService(): void { try { const appInfo = await getAppInfo(installedPackageId); - await createToast(`Application installed: ${appInfo['title']}`, service); + if (appInfo.type === 'native' && runningAsRoot) { + await createToast(`Updating jailer config for ${appInfo.title}…`, service); + await buildBetterJail(appInfo.id, appInfo.folderPath).catch((err) => { + console.warn('jailer execution failed:', err); + }); + } + await createToast(`Application installed: ${appInfo.title}`, service); } catch (err: unknown) { console.warn('appinfo fetch failed:', err); await createToast(`Application installed: ${installedPackageId}`, service);