Package: dpkg
Version: 1.21.19
Tags: patch

Hello,

While working on a rather specific project in Ubuntu, we encountered
an issue with dpkg when trying to handle read-only directories. As we
had a read-only filesystem mounted on the system, we decided to use
dpkg's --path-exclude to willingly ignore directories on that
filesystem, as it is supported. Sadly, we saw that dpkg was still
erroring out while trying to "unable to clean up mess surrounding
(...)". After diving into the code, my colleagues noticed that the
code for checking for interrupted transactions performs a rename()
function call, but only expects ENOENT and ENOTDIR as 'expected'
errors. In case of a read-only directory the errno is EROFS.

One way would be to add EROFS to the set of expected errors in this
case, but Julian Klode made a point that we might, in some cases,
error out on a read-only filesystem indeed. Instead he proposed to
simply do a check for the .dpkg-tmp file before trying to perform the
rename. And this seems to work as expected.

Change is relatively low-risk. We will be pushing this to our Ubuntu
packages, but also wanted to make sure it ends up upstream! Can you
take a look at the patch and merge it in if all checks out?

Thank you!

Best regardsm

-- 
Ɓukasz 'sil2100' Zemczak
 Foundations Team
 Tools Squad Interim Engineering Manager
 [email protected]
 www.canonical.com
diff -Nru dpkg-1.21.19/src/main/archives.c dpkg-1.21.19/src/main/archives.c
--- dpkg-1.21.19/src/main/archives.c	2023-01-02 02:42:41.000000000 +0100
+++ dpkg-1.21.19/src/main/archives.c	2023-01-24 23:39:50.000000000 +0100
@@ -764,7 +764,7 @@
      * However, it's possible that we were in the middle of some other
      * backup/restore operation and were rudely interrupted.
      * So, we see if we have .dpkg-tmp, and if so we restore it. */
-    if (rename(fnametmpvb.buf,fnamevb.buf)) {
+    if (access(fnametmpvb.buf, F_OK) || rename(fnametmpvb.buf,fnamevb.buf)) {
       if (errno != ENOENT && errno != ENOTDIR)
         ohshite(_("unable to clean up mess surrounding '%.255s' before "
                   "installing another version"), ti->name);

Reply via email to