FS#69720 - [pacman] _alpm_access() is testing symlink target

Attached to Project: Pacman
Opened by tinywrkb (tinywrkb) - Saturday, 20 February 2021, 19:12 GMT
Last edited by Doug Newgard (Scimmia) - Sunday, 21 February 2021, 04:28 GMT
Task Type Bug Report
Category Packages: Core
Status Unconfirmed
Assigned To No-one
Architecture All
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No


My host system is read-only except for /var and /home (/etc -> /usr/etc).
When trying to upgrade packages in a different system root tree, with `# pacman --root`, pacman complains about files being read-only when it encounters absolute symlinks.

> error: cannot remove file '/run/os/update/rootfs/usr/lib/libGLX_indirect.so.0': Read-only file system

The fault seems to be due to _alpm_access() not checking if "file" is a symlink before calling "access(check_path, amode)".
I suggest that in the case of a symlink, instead of trying to test file permission and ending testing the target, check instead the folder permissions.

My c skills are pretty rusty but maybe something like the attached patch can solve this.
This task depends upon

Comment by Allan McRae (Allan) - Saturday, 20 February 2021, 23:33 GMT
Can you clarify where the symlink is in /run/os/update/rootfs/usr/lib/libGLX_indirect.so.0? What points to what?
Comment by tinywrkb (tinywrkb) - Sunday, 21 February 2021, 01:19 GMT
On my host, /usr is mounted as read-only.
I'm running pacman to update a non-host rootfs mounted to /run/os/update/rootfs, so I'm running a command like "# pacman --root /run/os/update/rootfs -Syu".

/run/os/update/rootfs/usr/lib/libGLX_indirect.so.0 is an absolute symbolic link pointing to /usr/lib/libGLX_mesa.so.0, so it's pointing to the host.

Pacman seems to follow the symlink to host and checks file permissions of /usr/lib/libGLX_mesa.so.0, so it complains about the symlink being read-only while in fact, the target file is read-only, and the folder /run/os/update/rootfs/usr/lib is writeable.
Comment by Emil (xexaxo) - Monday, 22 February 2021, 22:24 GMT
It seems very unlikely if libGLX_indirect.so is the only absolute symlink.
So I pulled some data from my system which has 1098 packages.

- 382 files (in /usr) are absolute symlinks, of which
- ~240 are due to zenity
- ~40 mixed bag in /usr/bin/*
- ~40 are due to hunspell-en_GB and hunspell-en_US
- ~30 mixed bag in /usr/share/licenses/*
- ~20 mixed bag in /usr/lib*
- ~10 are due to jre8-openjdk-headless

So issue is common, although reasonably self contained.
Thus theoretically, one could consider fixing the packages. Nevertheless, that doesn't "feel" like a proper solution.
Comment by Allan McRae (Allan) - Monday, 22 February 2021, 23:28 GMT
This is a bug, but I don't think the proposed solution is correct. There has got to be a way of checking permission of the actual symlink and not the file it points to...
Comment by morganamilo (morganamilo) - Thursday, 30 September 2021, 10:14 GMT
Symlinks don't have perms so looking at the perms of the parent dir is correct. (Though I hear for macos it's different)

Maybe a better solution is to use faccessat() with AT_SYMLINK_NOFOLLOW?