LG Update Blocker
A webOS homebrew app that gets rid of the "a new software version is available" popup LG shows on every boot — without touching the firmware itself, and fully reversible.
Built for a rooted LG CX (webOS 5), but nothing in it is model specific: it only ever probes for things and acts on what it actually finds on your TV.
Why the popup keeps coming back
The Homebrew Channel's own Block system updates toggle only writes four
hostnames into /etc/hosts at boot. That is not enough in practice:
- it misses several update hostnames (
nsu,*-ssl, the CDN aliases), - it does nothing about a firmware image the TV already downloaded — a staged update keeps prompting even when the update servers are unreachable,
- it leaves the auto-update settings and the update services alone.
This app covers all of that, and re-applies everything on each boot (webOS
resets /, /tmp and the mount namespace on every start).
Protection layers
| Layer | What it does | Default |
|---|---|---|
| Block LG update servers | Points snu/su/nsu.lge.com, their TLS variants, the -dev fallbacks and the CDN aliases at 127.0.0.1 in /etc/hosts |
on |
| Delete staged firmware | Wipes the update image staged in /mnt/lg/cmn_data/swupdate |
on |
| Lock the staging folder | Bind-mounts an empty read-only directory over it, so nothing can be staged again | off |
| Turn off auto-update settings | Reads every com.webos.settingsservice category, switches off each update-related key it finds, and remembers the original values |
on |
| Stop update services at boot | Stops the update-related upstart jobs discovered in /etc/init (advanced) |
off |
Every layer is undone by Remove protection, which also restores the settings from the backup it made.
Requirements
- A rooted webOS TV with the Homebrew Channel installed and its root status showing ok.
- The app's own service needs root. On first launch it asks the Homebrew
Channel to elevate it (
elevateService, falling back to runningelevate-servicethroughexec), then restarts itself. The header badge turns green when it worked.
Install
Through the Homebrew Channel (repository)
Add the repository once — Homebrew Channel → Settings → Add repository:
https://github.com/<owner>/<repo>/releases/latest/download/apps.json
The app then shows up in the Homebrew Channel list, and every new release you tag is picked up automatically (that URL always points at the newest release).
Manually
Download the .ipk from the release and:
ares-install com.rkievits.lgupdateblocker_1.0.0_all.ipk
ares-launch com.rkievits.lgupdateblocker
Using it
Navigate with ▲▼, select with OK, leave with BACK.
- Check the layers you want (the defaults are a good start).
- Apply protection — the log pane shows exactly what was changed.
- Reboot and confirm the popup is gone.
Other buttons: Purge staged update (wipe a downloaded image right now),
Remove protection (undo everything), Refresh status, and
Diagnostics (dumps OS info, mounts, discovered settings, the tail of
/etc/hosts and the boot-hook log — handy for a bug report).
What it touches
| Path | Purpose |
|---|---|
/etc/hosts |
Blocked hostnames, between # >>> lg-update-blocker >>> markers. Bind-mounted from /tmp/lgupdateblocker-hosts because / is read-only |
/var/lib/webosbrew/init.d/lgupdateblocker |
Boot hook, run by the Homebrew Channel startup script; re-applies the enabled layers |
/var/lib/webosbrew/lgupdateblocker/ |
config.json, hosts.txt, settings-backup.json, boot.log |
/mnt/lg/cmn_data/swupdate |
Staged firmware, emptied (and optionally locked) |
Nothing is written to system partitions, and no LG binaries are patched or replaced.
Troubleshooting
- Badge says "no root" — open the Homebrew Channel, verify Root status is
ok, then relaunch this app. If the Homebrew Channel itself is unelevated, fix that first (its Settings screen has a button for it). - Popup still appears after a reboot — run Diagnostics and look at the boot-hook log at the bottom. It records, per boot, whether the hosts entries were added, what was purged and which jobs were stopped.
- Belt and braces — a hosts file only helps if the TV uses DNS. Blocking
snu.lge.com,su.lge.comandnsu.lge.comon your router or Pi-hole as well is the one measure that also survives a factory reset. - Forced app updates (the "You must update this app to launch it"
dialog) are a different mechanism — that is what
LG App Update Blocker
is for. This app deliberately leaves the
lgtvsdp.comhosts alone, since blocking those also breaks the store and several other services.
Building
No bundler, no runtime dependencies — tools/build.js copies app/ and
service/ into build/ and substitutes the app id and version.
npm install # only the ares CLI
npm run dist # build + package + manifest, output in dist/
npm run deploy # ares-install the resulting ipk
Releasing
.github/workflows/release.yml builds on every push. Tag a commit v<version>
(matching version in package.json) and the workflow additionally publishes a
release containing:
com.rkievits.lgupdateblocker_<version>_all.ipkcom.rkievits.lgupdateblocker.manifest.json— Homebrew Channel manifest, with the absolute ipk URL, its sha256 and sizeapps.json— the one-package repository index used by the repository URL abovedescription.html— the long description shown in the Homebrew Channel
The app id lives in exactly one place: the name field of package.json.
Change it there and everything (appinfo, service name, Luna URIs, manifest)
follows.
License
MIT
