Skip to content

Commit 21c00ae

Browse files
committed
do not apply POSIX file attributes through symbolic links
1 parent 04c93c1 commit 21c00ae

5 files changed

Lines changed: 121 additions & 1 deletion

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core.appender.rolling.action;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
21+
22+
import java.nio.charset.StandardCharsets;
23+
import java.nio.file.Files;
24+
import java.nio.file.Path;
25+
import java.nio.file.attribute.PosixFilePermissions;
26+
import org.apache.logging.log4j.core.config.Configuration;
27+
import org.apache.logging.log4j.core.test.BasicConfigurationFactory;
28+
import org.apache.logging.log4j.core.util.FileUtils;
29+
import org.junit.jupiter.api.BeforeAll;
30+
import org.junit.jupiter.api.Test;
31+
import org.junit.jupiter.api.io.TempDir;
32+
33+
/**
34+
* Tests the {@code PosixViewAttributeAction} class.
35+
*/
36+
class PosixViewAttributeActionTest {
37+
38+
@BeforeAll
39+
static void beforeClass() {
40+
assumeTrue(FileUtils.isFilePosixAttributeViewSupported());
41+
}
42+
43+
@Test
44+
void testSymbolicLinksAreNotFollowed(@TempDir final Path tempDir) throws Exception {
45+
// A file outside the scanned directory, that the action must not touch.
46+
final Path outsider = tempDir.resolve("outsider.txt");
47+
Files.write(outsider, "secret".getBytes(StandardCharsets.UTF_8));
48+
Files.setPosixFilePermissions(outsider, PosixFilePermissions.fromString("rw-------"));
49+
50+
final Path baseDir = Files.createDirectory(tempDir.resolve("logs"));
51+
final Path regularFile = baseDir.resolve("app-1.log");
52+
Files.write(regularFile, "log".getBytes(StandardCharsets.UTF_8));
53+
Files.setPosixFilePermissions(regularFile, PosixFilePermissions.fromString("rw-------"));
54+
Files.createSymbolicLink(baseDir.resolve("app-2.log"), outsider);
55+
56+
final Configuration config = new BasicConfigurationFactory().new BasicConfiguration();
57+
final PosixViewAttributeAction action = PosixViewAttributeAction.newBuilder()
58+
.setBasePath(baseDir.toString())
59+
.setFollowLinks(false)
60+
.setMaxDepth(1)
61+
.setPathConditions(PathCondition.EMPTY_ARRAY)
62+
.setConfiguration(config)
63+
.setFilePermissionsString("rw-rw-rw-")
64+
.build();
65+
66+
action.execute();
67+
68+
assertEquals(
69+
"rw-rw-rw-",
70+
PosixFilePermissions.toString(Files.getPosixFilePermissions(regularFile)),
71+
"regular file should have been updated");
72+
assertEquals(
73+
"rw-------",
74+
PosixFilePermissions.toString(Files.getPosixFilePermissions(outsider)),
75+
"symbolic link target should have been left alone");
76+
}
77+
}

log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
import static org.junit.jupiter.api.Assertions.assertFalse;
2121
import static org.junit.jupiter.api.Assertions.assertThrows;
2222
import static org.junit.jupiter.api.Assertions.assertTrue;
23+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2324

2425
import java.io.File;
2526
import java.io.IOException;
2627
import java.net.URI;
2728
import java.nio.file.Files;
29+
import java.nio.file.Path;
30+
import java.nio.file.attribute.PosixFilePermissions;
2831
import java.util.ArrayList;
2932
import java.util.List;
3033
import java.util.concurrent.atomic.AtomicBoolean;
@@ -87,6 +90,28 @@ void testFileFromUriWithSpacesAndPlusCharactersInName() throws Exception {
8790
assertTrue(file.exists(), "file exists");
8891
}
8992

93+
@Test
94+
void testDefineFilePosixAttributeViewDoesNotFollowSymbolicLinks(@TempDir final Path tempDir) throws Exception {
95+
assumeTrue(FileUtils.isFilePosixAttributeViewSupported());
96+
97+
final Path target = tempDir.resolve("target.txt");
98+
Files.createFile(target);
99+
Files.setPosixFilePermissions(target, PosixFilePermissions.fromString("rw-------"));
100+
final Path link = tempDir.resolve("link.txt");
101+
Files.createSymbolicLink(link, target);
102+
103+
try {
104+
FileUtils.defineFilePosixAttributeView(link, PosixFilePermissions.fromString("rw-rw-rw-"), null, null);
105+
} catch (final IOException expected) {
106+
// POSIX has no way to change the permissions of the link itself
107+
}
108+
109+
assertEquals(
110+
"rw-------",
111+
PosixFilePermissions.toString(Files.getPosixFilePermissions(target)),
112+
"link target should have been left alone");
113+
}
114+
90115
@Nested
91116
class TestMkdir {
92117
@TempDir

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ protected FileVisitor<Path> createFileVisitor(final Path basePath, final List<Pa
369369
return new SimpleFileVisitor<Path>() {
370370
@Override
371371
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
372+
if (attrs.isSymbolicLink()) {
373+
LOGGER.trace("Not defining POSIX attribute on symbolic link {}", file);
374+
return FileVisitResult.CONTINUE;
375+
}
372376
for (final PathCondition pathFilter : conditions) {
373377
final Path relative = basePath.relativize(file);
374378
if (!pathFilter.accept(basePath, relative, attrs)) {

log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.nio.file.FileAlreadyExistsException;
2525
import java.nio.file.FileSystems;
2626
import java.nio.file.Files;
27+
import java.nio.file.LinkOption;
2728
import java.nio.file.Path;
2829
import java.nio.file.attribute.GroupPrincipal;
2930
import java.nio.file.attribute.PosixFileAttributeView;
@@ -146,6 +147,10 @@ public static void makeParentDirs(final File file) throws IOException {
146147

147148
/**
148149
* Define file POSIX attribute view on a path/file.
150+
* <p>
151+
* Symbolic links are never followed: if {@code path} is a link, the attributes of the link itself are
152+
* modified and its target is left untouched.
153+
* </p>
149154
*
150155
* @param path Target path
151156
* @param filePermissions Permissions to apply
@@ -159,7 +164,8 @@ public static void defineFilePosixAttributeView(
159164
final String fileOwner,
160165
final String fileGroup)
161166
throws IOException {
162-
final PosixFileAttributeView view = Files.getFileAttributeView(path, PosixFileAttributeView.class);
167+
final PosixFileAttributeView view =
168+
Files.getFileAttributeView(path, PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
163169
if (view != null) {
164170
final UserPrincipalLookupService lookupService =
165171
FileSystems.getDefault().getUserPrincipalLookupService();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="https://logging.apache.org/xml/ns"
4+
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
5+
type="fixed">
6+
<issue id="4229" link="https://github.com/apache/logging-log4j2/pull/4229"/>
7+
<description format="asciidoc">Stop `PosixViewAttribute` from applying permissions and ownership through symbolic links</description>
8+
</entry>

0 commit comments

Comments
 (0)