Hi,
When adding a new image, the installer copies /config into the new image with:
copytree(f'{DIR_CONFIG}/', target_config_dir, symlinks=True,
copy_function=copy_preserve_owner, dirs_exist_ok=True)copytree() keeps permissions but not ownership, and copy_preserve_owner() (T5883) only restores the owner of regular files. As a result, in th
new image's copy (/usr/lib/live/mount/persistence/boot/<image>/rw/opt/vyatta/etc/config):
- directories are owned by root, with group vyattacfg inherited from the setgid /config;
- regular files keep their owner but lose their group (it becomes vyattacfg), and chown() clears their setuid/setgid bits;
- symlinks are owned by root.
Reinstalling over a previous installation (copy_previous_installation_data()) has the same problem, since it uses plain copytree().
Impact
After rebooting into the new image, any service running as a non-root user that writes under /config breaks. A typical case is container
volumes under /config/containers/ that belong to the container user. On a production router, 1,032 entries changed ownership during an upgrade
and five containers could no longer write to their volumes until ownership was restored by hand.
Steps to reproduce
- On an installed system:
sudo install -d -o 4000 -g 4000 -m 2750 /config/containers/test-run echo x | sudo tee /config/test-group.txt; sudo chown 1003:100 /config/test-group.txt sudo ln -s /config/containers/test-run /config/test-link; sudo chown -h 4000:4000 /config/test-link
add system image <another image>
then answer yes to copying the configuration.
- Compare `stat -c '%u:%g %a %n'` for these paths in /config and in /usr/lib/live/mount/persistence/boot/<new image>/rw/opt/vyatta/etc/config/.
Observed (2026.09.30-1921 installed, upgraded to 2026.09.30-0907):
| Path | /config | Copy in the new image |
| containers/test-run | 4000:4000 2750 | 0:102 2750 |
| containers/test-run/test.pid | 4000:4000 644 | 4000:102 644 |
| test-group.txt | 1003:100 640 | 1003:102 640 |
| scripts/test-sgid | 0:100 2755 | 0:102 755 |
| test-link | 4000:4000 | 0:102 |
| dhcp (stock directory) | 100:102 2750 | 0:102 2750 |
Expected
The copy keeps the owner, group and mode of every entry.
Proposed fix
After each copytree() of the configuration, copy owner, group and mode from the source entry to the target entry (lchown, then chmod for
non-symlinks, since chown clears setuid/setgid). On the same test with this fix, there are 0 differences. A PR will follow.
Best,