142 lines
3.4 KiB
Text
142 lines
3.4 KiB
Text
$NetBSD: patch-bd,v 1.5 2010/07/13 10:59:43 sbd Exp $
|
|
|
|
Incorporate str3510.patch from
|
|
http://www.cups.org/str.php?L3510
|
|
"cups overwrites files as root in a directory with non-root write permission"
|
|
|
|
--- cups/file.c.orig 2009-05-14 21:18:35.000000000 +0000
|
|
+++ cups/file.c
|
|
@@ -59,6 +59,7 @@
|
|
*/
|
|
|
|
#include "file-private.h"
|
|
+#include <sys/stat.h>
|
|
|
|
|
|
/*
|
|
@@ -69,6 +70,7 @@
|
|
static ssize_t cups_compress(cups_file_t *fp, const char *buf, size_t bytes);
|
|
#endif /* HAVE_LIBZ */
|
|
static ssize_t cups_fill(cups_file_t *fp);
|
|
+static int cups_open(const char *filename, int mode);
|
|
static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes);
|
|
static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes);
|
|
|
|
@@ -827,7 +829,8 @@ cupsFileOpen(const char *filename, /* I
|
|
switch (*mode)
|
|
{
|
|
case 'a' : /* Append file */
|
|
- fd = open(filename, O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY, 0666);
|
|
+ fd = cups_open(filename,
|
|
+ O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY);
|
|
break;
|
|
|
|
case 'r' : /* Read file */
|
|
@@ -835,7 +838,17 @@ cupsFileOpen(const char *filename, /* I
|
|
break;
|
|
|
|
case 'w' : /* Write file */
|
|
- fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_LARGEFILE | O_BINARY, 0666);
|
|
+ fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
|
|
+ if (fd < 0 && errno == ENOENT)
|
|
+ {
|
|
+ fd = cups_open(filename,
|
|
+ O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE | O_BINARY);
|
|
+ if (fd < 0 && errno == EEXIST)
|
|
+ fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
|
|
+ }
|
|
+
|
|
+ if (fd >= 0)
|
|
+ ftruncate(fd, 0);
|
|
break;
|
|
|
|
case 's' : /* Read/write socket */
|
|
@@ -2207,6 +2220,88 @@ cups_fill(cups_file_t *fp) /* I - CUPS
|
|
return (bytes);
|
|
}
|
|
|
|
+/*
|
|
+ * 'cups_open()' - Safely open a file for writing.
|
|
+ *
|
|
+ * We don't allow appending to directories or files that are hard-linked or
|
|
+ * symlinked.
|
|
+ */
|
|
+
|
|
+static int /* O - File descriptor or -1 otherwise */
|
|
+cups_open(const char *filename, /* I - Filename */
|
|
+ int mode) /* I - Open mode */
|
|
+{
|
|
+ int fd; /* File descriptor */
|
|
+ struct stat fileinfo; /* File information */
|
|
+#ifndef WIN32
|
|
+ struct stat linkinfo; /* Link information */
|
|
+#endif /* !WIN32 */
|
|
+
|
|
+
|
|
+ /*
|
|
+ * Open the file...
|
|
+ */
|
|
+
|
|
+ if ((fd = open(filename, mode, 0666)) < 0)
|
|
+ return (-1);
|
|
+
|
|
+ /*
|
|
+ * Then verify that the file descriptor doesn't point to a directory or hard-
|
|
+ * linked file.
|
|
+ */
|
|
+
|
|
+ if (fstat(fd, &fileinfo))
|
|
+ {
|
|
+ close(fd);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (fileinfo.st_nlink != 1)
|
|
+ {
|
|
+ close(fd);
|
|
+ errno = EPERM;
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (S_ISDIR(fileinfo.st_mode))
|
|
+ {
|
|
+ close(fd);
|
|
+ errno = EISDIR;
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+#ifndef WIN32
|
|
+ /*
|
|
+ * Then use lstat to determine whether the filename is a symlink...
|
|
+ */
|
|
+
|
|
+ if (lstat(filename, &linkinfo))
|
|
+ {
|
|
+ close(fd);
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ if (S_ISLNK(linkinfo.st_mode) ||
|
|
+ fileinfo.st_dev != linkinfo.st_dev ||
|
|
+ fileinfo.st_ino != linkinfo.st_ino ||
|
|
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__DragonFly__)
|
|
+ fileinfo.st_gen != linkinfo.st_gen ||
|
|
+#endif
|
|
+ fileinfo.st_nlink != linkinfo.st_nlink ||
|
|
+ fileinfo.st_mode != linkinfo.st_mode)
|
|
+ {
|
|
+ /*
|
|
+ * Yes, don't allow!
|
|
+ */
|
|
+
|
|
+ close(fd);
|
|
+ errno = EPERM;
|
|
+ return (-1);
|
|
+ }
|
|
+#endif /* !WIN32 */
|
|
+
|
|
+ return (fd);
|
|
+}
|
|
|
|
/*
|
|
* 'cups_read()' - Read from a file descriptor.
|