1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
From 7b377456f95d2ec3ead40f4fb74ea620191f88c8 Mon Sep 17 00:00:00 2001
From: Michal Srb <msrb@suse.com>
Date: Thu, 26 Oct 2017 09:48:13 +0200
Subject: Open files with O_NOFOLLOW. (CVE-2017-16611)
A non-privileged X client can instruct X server running under root to open any
file by creating own directory with "fonts.dir", "fonts.alias" or any font file
being a symbolic link to any other file in the system. X server will then open
it. This can be issue with special files such as /dev/watchdog.
Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
diff --git a/src/fontfile/dirfile.c b/src/fontfile/dirfile.c
index 04cfa40..2802980 100644
--- a/src/fontfile/dirfile.c
+++ b/src/fontfile/dirfile.c
@@ -42,6 +42,7 @@ in this Software without prior written authorization from The Open Group.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <errno.h>
#include <limits.h>
@@ -61,8 +62,9 @@ FontFileReadDirectory (const char *directory, FontDirectoryPtr *pdir)
char dir_file[MAXFONTFILENAMELEN];
char dir_path[MAXFONTFILENAMELEN];
char *ptr;
- FILE *file;
- int count,
+ FILE *file = 0;
+ int file_fd,
+ count,
num_fonts,
status;
struct stat statb;
@@ -92,7 +94,14 @@ FontFileReadDirectory (const char *directory, FontDirectoryPtr *pdir)
if (dir_file[strlen(dir_file) - 1] != '/')
strcat(dir_file, "/");
strcat(dir_file, FontDirFile);
+#ifndef WIN32
+ file_fd = open(dir_file, O_RDONLY | O_NOFOLLOW);
+ if (file_fd >= 0) {
+ file = fdopen(file_fd, "rt");
+ }
+#else
file = fopen(dir_file, "rt");
+#endif
if (file) {
#ifndef WIN32
if (fstat (fileno(file), &statb) == -1)
@@ -262,7 +271,8 @@ ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
char alias[MAXFONTNAMELEN];
char font_name[MAXFONTNAMELEN];
char alias_file[MAXFONTFILENAMELEN];
- FILE *file;
+ int file_fd;
+ FILE *file = 0;
FontDirectoryPtr dir;
int token;
char *lexToken;
@@ -280,7 +290,16 @@ ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir)
strcat(alias_file, "/");
strcat(alias_file, FontAliasFile);
}
+
+#ifndef WIN32
+ file_fd = open(alias_file, O_RDONLY | O_NOFOLLOW);
+ if (file_fd >= 0) {
+ file = fdopen(file_fd, "rt");
+ }
+#else
file = fopen(alias_file, "rt");
+#endif
+
if (!file)
return ((errno == ENOENT) ? Successful : BadFontPath);
if (!dir)
diff --git a/src/fontfile/fileio.c b/src/fontfile/fileio.c
index 074ebcb..05374b4 100644
--- a/src/fontfile/fileio.c
+++ b/src/fontfile/fileio.c
@@ -40,6 +40,9 @@ in this Software without prior written authorization from The Open Group.
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 0
+#endif
FontFilePtr
FontFileOpen (const char *name)
@@ -48,7 +51,7 @@ FontFileOpen (const char *name)
int len;
BufFilePtr raw, cooked;
- fd = open (name, O_BINARY|O_CLOEXEC);
+ fd = open (name, O_BINARY|O_CLOEXEC|O_NOFOLLOW);
if (fd < 0)
return 0;
raw = BufFileOpenRead (fd);
--
cgit v0.10.2
|