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:46:50 +0100
commit5ed8ac0e4f063825b8ecda48e9a111d3ce92e825 (patch)
tree0b836d558b8813796e5f54b6836d8adf6eb92039
parentf581c2346d025d5b15926db9e58f254173fb58dc (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 38ced75..661787a 100644
--- a/src/fontfile/dirfile.c
+++ b/src/fontfile/dirfile.c
@@ -41,6 +41,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>
@@ -60,8 +61,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;
@@ -91,7 +93,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)
@@ -261,7 +270,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;
@@ -279,7 +289,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 d44cecd..992873a 100644
--- a/src/fontfile/fileio.c
+++ b/src/fontfile/fileio.c
@@ -39,6 +39,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)
@@ -47,7 +50,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);