Blame 0002-cadecoder-only-try-to-set-settable-chattr-bits.patch

8ac090b
From b6ebd172912d298223990487f14460faf3e959df Mon Sep 17 00:00:00 2001
8ac090b
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
8ac090b
Date: Tue, 20 Jun 2017 15:21:07 -0400
8ac090b
Subject: [PATCH 2/4] cadecoder: only try to set settable chattr bits
8ac090b
MIME-Version: 1.0
8ac090b
Content-Type: text/plain; charset=UTF-8
8ac090b
Content-Transfer-Encoding: 8bit
8ac090b
8ac090b
It seems that after all, FS_IOC_GETFLAGS should take an int*.
8ac090b
It does not set the high bits in the long argument. By explicitly
8ac090b
initalizing it to 0, we avoid garbage there. I'm not sure how this
8ac090b
will play out on a big-endian system…
8ac090b
8ac090b
Independently, we shouldn't be trying to set bits like FS_EXTENT_FL,
8ac090b
which chattr(1) says "cannot be set by chattr", i.e. presumably also
8ac090b
not by us.
8ac090b
---
8ac090b
 src/cadecoder.c | 10 +++++++---
8ac090b
 1 file changed, 7 insertions(+), 3 deletions(-)
8ac090b
8ac090b
diff --git a/src/cadecoder.c b/src/cadecoder.c
8ac090b
index d3167348fa..d65938e839 100644
8ac090b
--- a/src/cadecoder.c
8ac090b
+++ b/src/cadecoder.c
8ac090b
@@ -3642,18 +3642,22 @@ static int ca_decoder_finalize_child(CaDecoder *d, CaDecoderNode *n, CaDecoderNo
8ac090b
         }
8ac090b
 
8ac090b
         if ((d->feature_flags & CA_FORMAT_WITH_CHATTR) != 0 && child->fd >= 0) {
8ac090b
-                long new_attr, old_attr;
8ac090b
+                long new_attr,
8ac090b
+                     old_attr = 0; /* Initialize, 'cuz ioctl() does not set the high bits. */;
8ac090b
 
8ac090b
                 new_attr = ca_feature_flags_to_chattr(read_le64(&child->entry->flags) & d->feature_flags);
8ac090b
+                assert((new_attr & ~FS_FL_USER_MODIFIABLE) == 0);
8ac090b
 
8ac090b
                 if (ioctl(child->fd, FS_IOC_GETFLAGS, &old_attr) < 0) {
8ac090b
 
8ac090b
                         if (new_attr != 0 || !IN_SET(errno, ENOTTY, ENOSYS, EBADF, EOPNOTSUPP))
8ac090b
                                 return -errno;
8ac090b
 
8ac090b
-                } else if (old_attr != new_attr) {
8ac090b
+                } else if ((old_attr & FS_FL_USER_MODIFIABLE) != new_attr) {
8ac090b
+                        long final_attr;
8ac090b
 
8ac090b
-                        if (ioctl(child->fd, FS_IOC_SETFLAGS, &new_attr) < 0)
8ac090b
+                        final_attr = (old_attr & !FS_FL_USER_MODIFIABLE) | new_attr;
8ac090b
+                        if (ioctl(child->fd, FS_IOC_SETFLAGS, &final_attr) < 0)
8ac090b
                                 return -errno;
8ac090b
                 }
8ac090b
         }
8ac090b
-- 
8ac090b
2.13.0
8ac090b