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
r...@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

Reply via email to