Subject: bug#27269: Sed --in-place is messing NTFS file permissions

From: Assaf Gordon <[email-masked]>
Date: Wed, 15 Nov 2017 03:43:30 -0700

Hello,

On 2017-11-15 02:23 AM, Assaf Gordon wrote:
> On 2017-06-06 08:45 PM, Maiko Cezar Rodrigues Costa wrote:
>> Hi, I've a problem with sed when using the --in-place option in a mounted
>> NTFS partition;
> 
> I can reproduce this and I believe it is a regression in sed-4.4 that 
> happens when an ntfs partition is mounted with "-o permissions".

The above statement is incorrect.
It is not a regression in sed-4.4 compared to sed-4.2 but a different 
issue relating to ACL support during compilation ("./configure 
--disable-acl").

If ACL support is included, NTFS permissions DO NOT work.
If ACL support is NOT included, NTFS permissions DO work.

What confused me before is that on Debian/Ubuntu systems
the default sed (/bin/sed) is compiled without ACL
and using it "just worked", while compiling from source code
did include ACL and it never worked.

Current Work around:
1. Use the system's default sed (e.g /bin/sed) which is likely compiled 
without ACL, or
2. Build sed with "./configure --disable-acl".
This of course will lose the ability to copy other ACLs on non-NTFS file 
systems.

----

Technical reason:
1.
If "./configure" finds the header file <sys/acl.h>, ACL support is included.

2.
Another way to test ACL support is by checking if the sed binary
requires the acl shared library:

     $ ldd /bin/sed | grep acl
     $ ldd ~/projects/sed/sed/sed | grep acl
         libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1

3.
If ACL support is compiled in sed, using "--in-place"
leads to the following syscalls:

   fchown(4, 1000, 1000)                   = 0
   fgetxattr(3, "system.posix_acl_access", "", 132) = 0
   fstat(3, {st_mode=S_IFREG|0664, st_size=6, ...}) = 0
   fsetxattr(4, "system.posix_acl_access", "\2\0\0\0\37....", 28, 0) = 0
   close(3)                                = 0
   close(4)                                = 0
   rename("world", "world.bak")            = 0
   rename("./sedcrOmKi", "world")          = 0

4.
If ACL support is not compiled in sed, using "--in-place"
leads to the following syscalls:

   fchown(4, 1000, 1000)                   = 0
   fchmod(4, 0100664)                      = 0
   close(3)                                = 0
   close(4)                                = 0
   rename("world", "world.bak")            = 0
   rename("./sednDUqpF", "world")          = 0

One can perhaps infer that fsetxattr/fgetxattr do not work on NTFS
mounts, but also don't fail with ENOTSUP.

----

Code flow:
sed's execute.c calls gnulib's "copy_acl" [1].
copy_acl calls qcopy_acl [2].
qcopy_acl calls set_permissions [3]
set_permissions uses the USE_ACL #define to either call "set_acls"
or call chmod/fchmod directly [4].

[1] https://opengrok.housegordon.com/source/xref/sed/sed/execute.c#677
[2] https://opengrok.housegordon.com/source/xref/gnulib/lib/copy-acl.c#43
[3] https://opengrok.housegordon.com/source/xref/gnulib/lib/qcopy-acl.c#39
[4] 
https://opengrok.housegordon.com/source/xref/gnulib/lib/set-permissions.c#776

----

Is this a bug?
and if so, is it in sed or gnulib or libacl ?
Not sure about this.

Jim and all,
What do you think?

regards,
  - assaf