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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user