Check POSIX file permissions before writing PID

Update `ApplicationPid` to check POSIX file permissions in addition to
`File.canWrite()` before PID file. This helps to provided consistent
behavior, regardless of if the application is running as root or not.

Fixes gh-9922
pull/9641/merge
Phillip Webb 7 years ago
parent fd1dfbb247
commit 28b7ec3bed

@ -17,9 +17,13 @@
package org.springframework.boot;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Set;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@ -31,6 +35,10 @@ import org.springframework.util.ObjectUtils;
*/
public class ApplicationPid {
private static final PosixFilePermission[] WRITE_PERMISSIONS = {
PosixFilePermission.OWNER_WRITE, PosixFilePermission.GROUP_WRITE,
PosixFilePermission.OTHERS_WRITE };
private final String pid;
public ApplicationPid() {
@ -81,6 +89,7 @@ public class ApplicationPid {
public void write(File file) throws IOException {
Assert.state(this.pid != null, "No PID available");
createParentFolder(file);
assertCanWrite(file);
try (FileWriter writer = new FileWriter(file)) {
writer.append(this.pid);
}
@ -93,4 +102,27 @@ public class ApplicationPid {
}
}
private void assertCanWrite(File file) throws IOException {
if (!file.canWrite() || !canWritePosixFile(file)) {
throw new FileNotFoundException(file.toString() + " (permission denied)");
}
}
private boolean canWritePosixFile(File file) throws IOException {
try {
Set<PosixFilePermission> permissions = Files
.getPosixFilePermissions(file.toPath());
for (PosixFilePermission permission : WRITE_PERMISSIONS) {
if (permissions.contains(permission)) {
return true;
}
}
return false;
}
catch (UnsupportedOperationException ex) {
// Assume that we can
return true;
}
}
}

Loading…
Cancel
Save