-
Story
-
Resolution: Unresolved
-
Major
-
rhel-10.0.beta
-
rhel-sst-cs-software-management
-
ssg_core_services
-
None
-
False
-
-
No
-
Red Hat Enterprise Linux
-
None
-
-
None
-
Automated
-
Release Note Not Required
-
None
— cloned from RHEL-28967 —
This issue is seen on customer RHEL8 systems, I can reproduce on RHEL9 systems as well (see reproducer below).
When installing a custom Relocatable package, the paths are unlinked first using unlinkat() syscalls.
If the package contains / in its %files list, this leads to getting a EBUSY failure, which didn't happen prior to fixing CVE-2021-35939 (on RHEL8, pre-CVE: rpm-4.14.3-26.el8).
From my point of view, having / in the %files list is kind of user error, because the node is already shipped by us (filesystem package), but it would be nice to harden the code to avoid the error (through skipping this specific node from being unlinked).
Reproducer
Install relocatable package reproducer-0.0.1-1.el8.x86_64.rpm as a user:
[user@vm-rhel9 ~]$ strace -fttTvyy -s 128 -o rpm.strace -- rpm -ivhU --reinstall --prefix $PWD/RPMROOTDIR --dbpath $PWD/RPMDB /tmp/reproducer-0.0.1-1.el9.x86_64.rpm
Verifying... ################################# [100%]
warning: Unable to get systemd shutdown inhibition lock: Permission denied
Preparing... ################################# [100%]
Updating / installing...
1:reproducer-0.0.1-1.el9 ################################# [100%]
error: unpacking of archive failed on file //: cpio: chmod failed - Device or resource busy
error: reproducer-0.0.1-1.el9.x86_64: install failed
Strace shows the issue on / node:
$ grep unlinkat rpm.strace 38285 10:58:44.159680 unlinkat(10</>, "foo;65f178d4", 0) = -1 ENOENT (No such file or directory) <0.000002> 38285 10:58:44.159691 unlinkat(10</>, "/", AT_REMOVEDIR) = -1 EBUSY (Device or resource busy) <0.000002>
Here above rpm tries to deletes its own node.
Related code is:
276 static int fsmRmdir(int dirfd, const char *path) 277 { 278 int rc = unlinkat(dirfd, path, AT_REMOVEDIR); <<<<< HERE 279 if (_fsm_debug) 280 rpmlog(RPMLOG_DEBUG, " %8s (%d %s) %s\n", __func__, 281 dirfd, path, (rc < 0 ? strerror(errno) : "")); 282 if (rc < 0) 283 switch (errno) { 284 case ENOENT: rc = RPMERR_ENOENT; break; 285 case ENOTEMPTY: rc = RPMERR_ENOTEMPTY; break; 286 default: rc = RPMERR_RMDIR_FAILED; break; 287 } 288 return rc; 289 }
I'm attaching the SPEC file to build the reproducer package if necessary.
- clones
-
RHEL-28967 Harden removal code of relocatable packages
- Closed