summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2023-01-13 08:57:27 +0200
committerMichal Domonkos <mdomonko@redhat.com>2023-03-13 15:32:25 +0100
commite10255a7427ba0bf1f509afe9f5a9f1ead23cd99 (patch)
treec7478eb79f568faf9ce359422612e779d9a2cd21
parent9513d3e7949dc302508028839dd43b52abf2439f (diff)
downloadrpm-e10255a7427ba0bf1f509afe9f5a9f1ead23cd99.tar.gz
Fix install of block and character special files (#2195, #2275)
While it's possible to open special files, they are, well, special and have "side-effects" also known as, ahem, semantics. Opening a device file in Unix means accessing that *device*, and FIFOs have their own semantics. In other words, for rpm's purposes, we should never EVER open these files as a part of the install / permission setting etc. Fix this major brainfart in 25a435e90844ea98fe5eb7bef22c1aecf3a9c033. OTOH this forces us back to the less secure path based operations for these files, which is what we were trying to avoid in the first place. There always was a tiny race between create + open for these (because there's no atomic way to create + open anything but regular files) but this opens up the window quite a bit. Nobody should be placing device nodes in user-owned directories but FIFO's may be a different story. We haven't had tests for device nodes because it requires privileges the test-suite usually doesn't have, not testing FIFOs I have no excuse for. Add that test now. Fixes: #2195, #2275 (backported from commit 28c92fd54c93371c3062664d8a938438a2be88d6)
-rw-r--r--lib/fsm.c4
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/data/SPECS/fifo.spec16
-rw-r--r--tests/rpmi.at15
4 files changed, 36 insertions, 2 deletions
diff --git a/lib/fsm.c b/lib/fsm.c
index 5e7c92722..5cfc497bc 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -1014,7 +1014,9 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfiles files,
rc = RPMERR_UNKNOWN_FILETYPE;
}
- if (!rc && fd == -1 && !S_ISLNK(fp->sb.st_mode)) {
+ /* Special files require path-based ops */
+ int mayopen = S_ISREG(fp->sb.st_mode) || S_ISDIR(fp->sb.st_mode);
+ if (!rc && fd == -1 && mayopen) {
/* Only follow safe symlinks, and never on temporary files */
fd = fsmOpenat(di.dirfd, fp->fpath,
fp->suffix ? AT_SYMLINK_NOFOLLOW : 0, 0);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 53c4d6946..71f73aba7 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -125,6 +125,7 @@ EXTRA_DIST += data/SPECS/hello-cd.spec
EXTRA_DIST += data/SPECS/verifyfiles.spec
EXTRA_DIST += data/SPECS/source_space.spec
EXTRA_DIST += data/SOURCES/source_space.tar.gz
+EXTRA_DIST += data/SPECS/fifo.spec
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pgp
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pub
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pgp
@@ -209,7 +210,7 @@ populate_testing: $(check_DATA)
for d in dev etc magic tmp var; do if [ ! -d testing/$${d} ]; then mkdir testing/$${d}; fi; done
for node in urandom stdin stderr stdout null full; do ln -s /dev/$${node} testing/dev/$${node}; done
for cf in hosts resolv.conf passwd shadow group gshadow mtab ; do [ -f /etc/$${cf} ] && ln -s /etc/$${cf} testing/etc/$${cf}; done
- for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
+ for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils xargs mknod; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
for d in /proc /sys /selinux /etc/selinux; do if [ -d $${d} ]; then ln -s $${d} testing/$${d}; fi; done
(cd testing/magic && file -C)
chmod -R u-w testing/
diff --git a/tests/data/SPECS/fifo.spec b/tests/data/SPECS/fifo.spec
new file mode 100644
index 000000000..20b30b243
--- /dev/null
+++ b/tests/data/SPECS/fifo.spec
@@ -0,0 +1,16 @@
+Name: fifo
+Version: 1.0
+Release: 1
+Group: Testing
+License: GPL
+Summary: Testing fifo behavior
+BuildArch: noarch
+
+%description
+%{summary}
+
+%install
+mknod ${RPM_BUILD_ROOT}/test-fifo p
+
+%files
+/test-fifo
diff --git a/tests/rpmi.at b/tests/rpmi.at
index db6c4d4a1..0ca84914c 100644
--- a/tests/rpmi.at
+++ b/tests/rpmi.at
@@ -1255,6 +1255,21 @@ runroot rpm -q --whatprovides /
[])
AT_CLEANUP
+AT_SETUP([rpm -U fifo])
+AT_KEYWORDS([install])
+AT_CHECK([
+RPMDB_INIT
+
+runroot rpmbuild -bb --quiet /data/SPECS/fifo.spec
+runroot rpm -U --ignoreos /build/RPMS/noarch/fifo-1.0-1.noarch.rpm
+runroot rpm -Vv --nouser --nogroup fifo
+],
+[0],
+[......... /test-fifo
+],
+[])
+AT_CLEANUP
+
AT_SETUP([rpm -U with Obsoletes])
AT_KEYWORDS([install])
AT_CHECK([