summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Srb <msrb@suse.com>2017-10-26 09:48:13 +0200
committerMatthieu Herrb <matthieu@herrb.eu>2017-11-25 11:45:41 +0100
commit7b377456f95d2ec3ead40f4fb74ea620191f88c8 (patch)
tree490711446aa5e24235d047a6dbebd44aba0084f6
parentd82dfe25491c599f650b2ad868772c3b8e6ba7bc (diff)
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>
-rw-r--r--src/fontfile/dirfile.c25
-rw-r--r--src/fontfile/fileio.c5
2 files changed, 26 insertions, 4 deletions
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);