Ubus Issues & Potential Security Problems

I have encountered two issues, related to ubus, that I am not sure how to resolve.

All of my images use uci-defaults scripts, for configuration. However, I am no longer able to control services from those scripts, because the ubus calls fail; such calls only succeed some time after uci-defaults complete. Is there any way around this problem or do I just have to run all the underlying commands myself? I am concerned that the inner workings of the services are a moving target that I will forever be having issues with. Alternatively, is there any guarantee that services will not be active until uci-defaults complete? I believe I tested this, long ago, and there was no such guarantee. That lead to a major security hole; the devices are running an insecure config, while uci-defaults are executing.

The other issue is that the sysupgrade command always ends with a non-zero exit status, because it tries to send messages while ubus is shutting down and they fail. This makes it impossible to (programmatically) determine whether the sysupgrade is commencing or the command itself failed.

Any input on these two problems would be greatly appreciated!

This is quite diffuse description.
What service and this post becomes quite hard if you don't share what you have in the uci-default file.

And what version of OpenWrt?

Having lot of "fun" regarding sysupgrade on various openwrt versions, I decided to keep it stupid simple: Not to rely on any assumed functionality, i.e. shutting down wifi, dismounting block storage etc. but to do everything myself, before calling sysupgrade. ubus I avoid as much as possible. I am managing services from within uci-defaults by old means, like manipulating /etc/config/service directly. Or editing /etc/init.d/service or "rm /etc/rc.d/Sservice" .
Such simple and stupid methods work very well, also for firmware updates OTA, of course.

1 Like

My apologies; I should have been more detailed. I am running 22.03 snapshot, on a NanoPi R4S. I didn't have the service problem, just a few weeks ago, on snapshot. However, the sysupgrade issue has existed for a long time and I have encountered it on other devices as well (eg. Netgear GS308T). I never encountered the sysupgrade ubus issue on 19, with an Archer C7, but that had a different problem; the SSH connection would terminate before sysupgrade exited.

Below is an example of the service issue. This was executed in /etc/uci-defaults/01_test.

+ /etc/init.d/network stop
Command failed: Not found
Command failed: ubus call service delete { "name": "network" } (Not found)

Below is an example of the sysupgrade issue.

Fri Jan 18 08:55:29 UTC 2013 upgrade: Reading partition table from bootdisk...
Fri Jan 18 08:55:29 UTC 2013 upgrade: Reading partition table from image...
Fri Jan 18 08:55:29 UTC 2013 upgrade: Commencing upgrade. Closing all shell sessions.
Command failed: ubus call system sysupgrade { "prefix": "\/tmp\/root", "path": "\/tmp\/sysupgrade-image", "backup": "\/tmp\/sysupgrade.tgz", "command": "\/lib\/upgrade\/do_stage2", "options": { "save_partitions": 1 } } (Connection failed

I did some investigation and it seems like the network is never started, when uci-defaults runs. I could have sworn it wasn't like that in the past, but perhaps my memory is failing me. I added some logging to the boot() function, in various /etc/init.d scripts. For example, inside /etc/init.d/boot, I put the lines below.

echo 'boot boot' >> /test
cat /sys/class/net/eth1/operstate >> /test || echo 'eth1 unavailable' >> /test
sleep 15
echo 'boot continue' >> /order
cat /sys/class/net/eth1/operstate >> /test || echo 'eth1 unavailable' >> /test

Below are the results.

sysfixtime boot
boot boot
eth1 unavailable
boot continue
eth1 unavailable
log boot
dropbear boot
firewall boot

Is it safe to assume that the device cannot be accessed in any way, while uci-defaults are being applied? That would allow me to eliminate all the hacks I've implemented that attempt to make sure the device cannot be compromised, during in-place sysupgrades, due to the vulnerable initial config.

On a separate note, it seems that the firewall is able to start after the network is brought up. Shouldn't it be the other way around, to avoid leaking traffic?

The uci-defaults scripts are processed before the nerwork service is started. The script responsible for triggering /etc/uci-defaults is /etc/init.d/boot with start priority 10. There's very few services with a lower priority, none of them network related. So in short yes, you can assume that no service offering network access (including the network setup itself) is started yet.

There are some special core services like ubusd which are launched directly by procd on boot, but those do not tend to rely on any uci settings.

The firewall is triggered by hotplug actions, the first ifup of an interface should already start it. The init script serves as fallback. In all common setups, the firewall is already started once the script executes.

3 Likes

That is great news. This will make my images significantly simpler. I have a follow up question though.

If I disable the network service, in a uci-defaults script, is that sufficient to guarantee that the device won't be accessible after uci-defaults completes?

The reason I ask is because I want to make sure the network does not turn on, unless all of my custom scripts execute successfully. To do that, I have a script in uci-defaults that will only exit successfully if all the scripts in another folder succeed. The first script in that folder disables the network and the last script enables it, which guarantees that the device is not accessible until everything is set up.

It should suffice, but it is redundant. The network service starts with priority 20, after /etc/init.d/boot (uci-defaults) at prio 10.

On OpenWrt, init scripts are processed one after another, there is no parallelism.

If a uci-defaults script fails, the device will continue booting and potentially run a bad config. That is the scenario I need to protect against, because my configs are complicated and the risk of errors is non-trivial. For that reason, it isn't redundant.

Thanks for all your help, though! You have made things far easier for me.

Are you absolutely shure ? Or are the scripts just started sequentially, according to their prio (which is my expirience) ?

I believe he is talking about the boot call, not start. See my earlier post; sleeping, on boot, delays the other scripts.

I believe start is called sequentially, but is non-blocking. That is what I imagine you are referencing.

Ok, I understand. You are correct.

If it is that important and that complex and you want to be absolutely sure you shouldn’t run uci-default at all. Or only to the smallest extent necessary to make a meaningful first time boot.

And then on a running system execute the complex setup script, then you will see first hand if the script works or not.