pkgsrc/print/cups/patches/patch-bd

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.