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