From 28b7ec3bed2294c82d7051862115d10b50e8b6b3 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 31 Jul 2017 20:31:28 -0700 Subject: [PATCH] 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 --- .../springframework/boot/ApplicationPid.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/spring-boot/src/main/java/org/springframework/boot/ApplicationPid.java b/spring-boot/src/main/java/org/springframework/boot/ApplicationPid.java index 7115118f89..bc8bf44f60 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ApplicationPid.java +++ b/spring-boot/src/main/java/org/springframework/boot/ApplicationPid.java @@ -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 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; + } + } + }