[Bug] zipfs unintentionally ignores umask/permissions
Osipov, Michael
michael.osipov at siemens.com
Mon Aug 19 15:39:51 UTC 2019
Folks,
please evaluate this bug. I am astounded that this hasn't been
reported/fixed before.
We create ZIP (zipfs provider) files with a default umask of 027. Those
files are read via NFS and CIFS with Unix group permissions from other
processes, may be on Windows or HP-UX (Tomcat).
Consider the following code:
> public class ZipTest {
>
> public static void main(String[] args) throws IOException {
>
> String zipSuffix = args[0];
>
> Map<String, String> env = new HashMap<>();
> env.put("create", "true");
>
> Path zipPath = Paths.get("zipfs-" + zipSuffix);
>
> if (Files.exists(zipPath))
> Files.delete(zipPath);
>
> try (FileSystem fs = FileSystems
> .newFileSystem(URI.create("jar:" + zipPath.toUri().toASCIIString()), env)) {
> for (int i = 1; i < args.length; i++) {
> Path srcPath = Paths.get(args[i]);
> Path dstPath = fs.getPath(args[i]);
> Files.copy(srcPath, dstPath);
> }
> }
>
> zipPath = Paths.get("zipos-" + zipSuffix);
>
> if (Files.exists(zipPath))
> Files.delete(zipPath);
>
> try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipPath))) {
> for (int i = 1; i < args.length; i++) {
> zos.putNextEntry(new ZipEntry(args[i]));
> Files.copy(Paths.get(args[i]), zos);
> zos.closeEntry();
> }
> }
>
> }
>
> }
Tests performed on:
> $ uname -a
> FreeBSD deblndw011x.ad001.siemens.net 12.0-STABLE FreeBSD 12.0-STABLE #10 r350672: Wed Aug 7 10:14:20 CEST 2019
> root at deblndw011x.ad001.siemens.net:/usr/obj/usr/src/amd64.amd64/sys/DEBLNDW011X amd64
> $ java -version
> openjdk version "1.8.0_222"
> OpenJDK Runtime Environment (build 1.8.0_222-b10)
> OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
and
> $ uname -a
> HP-UX deblndw0 B.11.31 U ia64 HP-UX
> $ java -version
> java version "1.8.0.17-hp-ux"
> Java(TM) SE Runtime Environment (build 1.8.0.17-hp-ux-b1)
> Java HotSpot(TM) Server VM (build 25.17-b1, mixed mode)
and here is the faulty result on HP-UX, similar case for FreeBSD:
> java -jar zip-test.jar toll.zip toll.pdf
> $ ll *toll.zip
> -rwx------ 1 osipovmi cad 1128 2019-08-19 17:16 zipfs-toll.zip*
> -rw-r----- 1 osipovmi cad 1118 2019-08-19 17:16 zipos-toll.zip
The umask is completely ignored by the zipfs provider. Running through
tusc on HP-UX or truss on FreeBSD:
> open("/net/home/osipovmi/zipfstmp4577367104205101212.tmp", O_WRONLY|O_CREAT|O_EXCL|0x800, 0700) = 18
> rename("/net/home/osipovmi/zipfstmp4577367104205101212.tmp", "/net/home/osipovmi/zipfs-toll.zip") = 0
FreeBSD respectively:
> openat(AT_FDCWD,"/net/home/osipovmi/zipfstmp4205922272998633281.tmp",O_WRONLY|O_CREAT|O_EXCL,0600)
> rename("/net/home/osipovmi/zipfstmp4205922272998633281.tmp","/net/home/osipovmi/zipfs-toll.zip")
Syscall outputs are here:
http://home.apache.org/~michaelo/java/zip-test.tar.gz
The bug im subtile, but obviously here:
https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/aa318070b27849f1fe00d14684b2a40f7b29bf79/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java#L1089-L1097
and
https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/aa318070b27849f1fe00d14684b2a40f7b29bf79/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java#L1297
which is:
> Files.move(tmpFile, zfpath, REPLACE_EXISTING);
by using:
https://github.com/AdoptOpenJDK/openjdk-jdk8u/blob/aa318070b27849f1fe00d14684b2a40f7b29bf79/jdk/src/share/classes/java/nio/file/TempFileHelper.java#L68-L74
Note that this also happens when the file is already there. The
permissions are *not* retained and this causes here a lot of grief.
zip(1) does not suffer from this nor does ZipOutputStream as you can see.
I'd expect that reading the attributes from zfpath, moving and then
settings them is a good option.
Regards,
Michael
More information about the core-libs-dev
mailing list