Sophie

Sophie

distrib > Mageia > 1 > i586 > media > core-updates-src > by-pkgid > afe76a9ef95a1b7e6257bc39819e7f31 > files > 19

x11-server-1.10.1-1.2.mga1.src.rpm

Description: extreme backport of upstream log format fixes (CVE-2012-2118).
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/996250
Origin: http://patchwork.freedesktop.org/patch/10001/

diff -uNrp xorg-server-1.10.1.log/hw/xfree86/common/xf86Helper.c xorg-server-1.10.1/hw/xfree86/common/xf86Helper.c
--- xorg-server-1.10.1.log/hw/xfree86/common/xf86Helper.c	2011-04-15 20:58:31.000000000 -0400
+++ xorg-server-1.10.1/hw/xfree86/common/xf86Helper.c	2012-10-16 15:28:07.463756730 -0400
@@ -1136,25 +1136,13 @@ void
 xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
 		va_list args)
 {
-    char *tmpFormat;
-
     /* Prefix the scrnIndex name to the format string. */
     if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
-	xf86Screens[scrnIndex]->name) {
-	tmpFormat = malloc(strlen(format) +
-			   strlen(xf86Screens[scrnIndex]->name) +
-			   PREFIX_SIZE + 1);
-	if (!tmpFormat)
-	    return;
-
-	snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
-		 xf86Screens[scrnIndex]->name, scrnIndex);
-
-	strcat(tmpFormat, format);
-	LogVMessageVerb(type, verb, tmpFormat, args);
-	free(tmpFormat);
-    } else
-	LogVMessageVerb(type, verb, format, args);
+        xf86Screens[scrnIndex]->name)
+        LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
+                          xf86Screens[scrnIndex]->name, scrnIndex);
+    else
+        LogVMessageVerb(type, verb, format, args);
 }
 #undef PREFIX_SIZE
 
@@ -1187,15 +1175,18 @@ void
 xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
 		 va_list args)
 {
-    char *msg;
+    const char *driverName = NULL;
+    const char *deviceName = NULL;
 
-    if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format)
-	== -1) {
-	LogVMessageVerb(type, verb, "%s", args);
-    } else {
-	LogVMessageVerb(type, verb, msg, args);
-	free(msg);
+    /* Prefix driver and device names to formatted message. */
+    if (dev) {
+        deviceName = dev->name;
+        if (dev->drv)
+            driverName = dev->drv->driverName;
     }
+
+    LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName,
+                      deviceName);
 }
 
 /* Print input driver message, with verbose level specified directly */
diff -uNrp xorg-server-1.10.1.log/include/os.h xorg-server-1.10.1/include/os.h
--- xorg-server-1.10.1.log/include/os.h	2011-02-24 22:27:28.000000000 -0500
+++ xorg-server-1.10.1/include/os.h	2012-10-16 15:28:07.463756730 -0400
@@ -504,6 +504,7 @@ typedef enum {
     X_INFO,			/* Informational message */
     X_NONE,			/* No prefix */
     X_NOT_IMPLEMENTED,		/* Not implemented */
+    X_DEBUG,            /* Debug message */
     X_UNKNOWN = -1		/* unknown -- this must always be last */
 } MessageType;
 
@@ -518,6 +519,20 @@ extern _X_EXPORT void LogMessageVerb(Mes
 			   ...) _X_ATTRIBUTE_PRINTF(3,4);
 extern _X_EXPORT void LogMessage(MessageType type, const char *format, ...)
 			_X_ATTRIBUTE_PRINTF(2,3);
+
+extern _X_EXPORT void
+LogVHdrMessageVerb(MessageType type, int verb,
+                   const char *msg_format, va_list msg_args,
+                   const char *hdr_format, va_list hdr_args)
+_X_ATTRIBUTE_PRINTF(3, 0)
+_X_ATTRIBUTE_PRINTF(5, 0);
+extern _X_EXPORT void
+LogHdrMessageVerb(MessageType type, int verb,
+                  const char *msg_format, va_list msg_args,
+                  const char *hdr_format, ...)
+_X_ATTRIBUTE_PRINTF(3, 0)
+_X_ATTRIBUTE_PRINTF(5, 6);
+
 extern _X_EXPORT void FreeAuditTimer(void);
 extern _X_EXPORT void AuditF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2);
 extern _X_EXPORT void VAuditF(const char *f, va_list args);
diff -uNrp xorg-server-1.10.1.log/include/Xprintf.h xorg-server-1.10.1/include/Xprintf.h
--- xorg-server-1.10.1.log/include/Xprintf.h	2011-02-24 22:27:28.000000000 -0500
+++ xorg-server-1.10.1/include/Xprintf.h	2012-10-16 15:28:07.463756730 -0400
@@ -66,4 +66,16 @@ extern _X_EXPORT int XNFvasprintf (char
 # define vasprintf Xvasprintf
 #endif
 
+/*
+ * These functions provide a portable implementation of the linux kernel
+ * scnprintf & vscnprintf routines that return the number of bytes actually
+ * copied during a snprintf, (excluding the final '\0').
+ */
+extern _X_EXPORT int
+Xscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, ...)
+_X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT int
+Xvscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, va_list va)
+_X_ATTRIBUTE_PRINTF(3,0);
+
 #endif /* XPRINTF_H */
diff -uNrp xorg-server-1.10.1.log/os/log.c xorg-server-1.10.1/os/log.c
--- xorg-server-1.10.1.log/os/log.c	2011-02-24 22:27:28.000000000 -0500
+++ xorg-server-1.10.1/os/log.c	2012-10-16 15:28:07.463756730 -0400
@@ -161,6 +161,12 @@ asm (".desc ___crashreporter_info__, 0x1
 #ifndef X_NOT_IMPLEMENTED_STRING
 #define X_NOT_IMPLEMENTED_STRING	"(NI)"
 #endif
+#ifndef X_DEBUG_STRING
+#define X_DEBUG_STRING          "(DB)"
+#endif
+#ifndef X_NONE_STRING
+#define X_NONE_STRING           ""
+#endif
 
 /*
  * LogInit is called to start logging to a file.  It is also called (with
@@ -217,7 +223,7 @@ LogInit(const char *fname, const char *b
      * needed.
      */
     if (saveBuffer && bufferSize > 0) {
-	free(saveBuffer);	/* Must be free(), not free() */
+	free(saveBuffer);
 	saveBuffer = NULL;
 	bufferSize = 0;
     }
@@ -257,36 +263,19 @@ LogSetParameter(LogParameter param, int
 }
 
 /* This function does the actual log message writes. */
-
-void
-LogVWrite(int verb, const char *f, va_list args)
+static void
+LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
 {
-    static char tmpBuffer[1024];
-    int len = 0;
     static Bool newline = TRUE;
 
-    if (newline) {
-	sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
-	len = strlen(tmpBuffer);
-	if (logFile)
-	    fwrite(tmpBuffer, len, 1, logFile);
-    }
-
-    /*
-     * Since a va_list can only be processed once, write the string to a
-     * buffer, and then write the buffer out to the appropriate output
-     * stream(s).
-     */
-    if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
-	vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
-	len = strlen(tmpBuffer);
-    }
-    newline = (tmpBuffer[len-1] == '\n');
-    if ((verb < 0 || logVerbosity >= verb) && len > 0)
-	fwrite(tmpBuffer, len, 1, stderr);
-    if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
+    if (verb < 0 || logVerbosity >= verb)
+        fwrite(buf, len, 1, stderr);
+    if (verb < 0 || logFileVerbosity >= verb) {
 	if (logFile) {
-	    fwrite(tmpBuffer, len, 1, logFile);
+            if (newline)
+                fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
+            newline = end_line;
+            fwrite(buf, len, 1, logFile);
 	    if (logFlush) {
 		fflush(logFile);
 #ifndef WIN32
@@ -303,13 +292,19 @@ LogVWrite(int verb, const char *f, va_li
 		    FatalError("realloc() failed while saving log messages\n");
 	    }
 	    bufferUnused -= len;
-	    memcpy(saveBuffer + bufferPos, tmpBuffer, len);
+            memcpy(saveBuffer + bufferPos, buf, len);
 	    bufferPos += len;
 	}
     }
 }
 
 void
+LogVWrite(int verb, const char *f, va_list args)
+{
+    return LogVMessageVerb(X_NONE, verb, f, args);
+}
+
+void
 LogWrite(int verb, const char *f, ...)
 {
     va_list args;
@@ -319,60 +314,75 @@ LogWrite(int verb, const char *f, ...)
     va_end(args);
 }
 
-void
-LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
+/* Returns the Message Type string to prepend to a logging message, or NULL
+ * if the message will be dropped due to insufficient verbosity. */
+static const char *
+LogMessageTypeVerbString(MessageType type, int verb)
 {
-    const char *s  = X_UNKNOWN_STRING;
-    char tmpBuf[1024];
+    if (type == X_ERROR)
+        verb = 0;
 
-    /* Ignore verbosity for X_ERROR */
-    if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
-	switch (type) {
-	case X_PROBED:
-	    s = X_PROBE_STRING;
-	    break;
-	case X_CONFIG:
-	    s = X_CONFIG_STRING;
-	    break;
-	case X_DEFAULT:
-	    s = X_DEFAULT_STRING;
-	    break;
-	case X_CMDLINE:
-	    s = X_CMDLINE_STRING;
-	    break;
-	case X_NOTICE:
-	    s = X_NOTICE_STRING;
-	    break;
-	case X_ERROR:
-	    s = X_ERROR_STRING;
-	    if (verb > 0)
-		verb = 0;
-	    break;
-	case X_WARNING:
-	    s = X_WARNING_STRING;
-	    break;
-	case X_INFO:
-	    s = X_INFO_STRING;
-	    break;
-	case X_NOT_IMPLEMENTED:
-	    s = X_NOT_IMPLEMENTED_STRING;
-	    break;
-	case X_UNKNOWN:
-	    s = X_UNKNOWN_STRING;
-	    break;
-	case X_NONE:
-	    s = NULL;
-	    break;
-	}
+    if (logVerbosity < verb && logFileVerbosity < verb)
+        return NULL;
 
-        /* if s is not NULL we need a space before format */
-        snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "",
-                                                   s ? " " : "",
-                                                   format);
-        LogVWrite(verb, tmpBuf, args);
+    switch (type) {
+    case X_PROBED:
+        return X_PROBE_STRING;
+    case X_CONFIG:
+        return X_CONFIG_STRING;
+    case X_DEFAULT:
+        return X_DEFAULT_STRING;
+    case X_CMDLINE:
+        return X_CMDLINE_STRING;
+    case X_NOTICE:
+        return X_NOTICE_STRING;
+    case X_ERROR:
+        return X_ERROR_STRING;
+    case X_WARNING:
+        return X_WARNING_STRING;
+    case X_INFO:
+        return X_INFO_STRING;
+    case X_NOT_IMPLEMENTED:
+        return X_NOT_IMPLEMENTED_STRING;
+    case X_UNKNOWN:
+        return X_UNKNOWN_STRING;
+    case X_NONE:
+        return X_NONE_STRING;
+    case X_DEBUG:
+        return X_DEBUG_STRING;
+    default:
+        return X_UNKNOWN_STRING;
     }
 }
 
+void
+LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
+{
+    const char *type_str;
+    char buf[1024];
+    const size_t size = sizeof(buf);
+    Bool newline;
+    size_t len = 0;
+
+    type_str = LogMessageTypeVerbString(type, verb);
+    if (!type_str)
+        return;
+
+    /* if type_str is not "", prepend it and ' ', to message */
+    if (type_str[0] != '\0')
+        len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+    if (size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, format, args);
+
+    /* Force '\n' at end of truncated line */
+    if (size - len == 1)
+        buf[len - 1] = '\n';
+
+    newline = (buf[len - 1] == '\n');
+    LogSWrite(verb, buf, len, newline);
+}
+
 /* Log message with verbosity level specified. */
 void
 LogMessageVerb(MessageType type, int verb, const char *format, ...)
@@ -396,6 +406,49 @@ LogMessage(MessageType type, const char
 }
 
 void
+LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
+                   va_list msg_args, const char *hdr_format, va_list hdr_args)
+{
+    const char *type_str;
+    char buf[1024];
+    const size_t size = sizeof(buf);
+    Bool newline;
+    size_t len = 0;
+
+    type_str = LogMessageTypeVerbString(type, verb);
+    if (!type_str)
+        return;
+
+    /* if type_str is not "", prepend it and ' ', to message */
+    if (type_str[0] != '\0')
+        len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+    if (hdr_format && size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args);
+
+    if (msg_format && size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args);
+
+    /* Force '\n' at end of truncated line */
+    if (size - len == 1)
+        buf[len - 1] = '\n';
+
+    newline = (buf[len - 1] == '\n');
+    LogSWrite(verb, buf, len, newline);
+}
+
+void
+LogHdrMessageVerb(MessageType type, int verb, const char *msg_format,
+                  va_list msg_args, const char *hdr_format, ...)
+{
+    va_list hdr_args;
+
+    va_start(hdr_args, hdr_format);
+    LogVHdrMessageVerb(type, verb, msg_format, msg_args, hdr_format, hdr_args);
+    va_end(hdr_args);
+}
+
+void
 AbortServer(void) _X_NORETURN;
 
 void
diff -uNrp xorg-server-1.10.1.log/os/xprintf.c xorg-server-1.10.1/os/xprintf.c
--- xorg-server-1.10.1.log/os/xprintf.c	2011-02-24 22:27:28.000000000 -0500
+++ xorg-server-1.10.1/os/xprintf.c	2012-10-16 15:28:07.463756730 -0400
@@ -182,6 +182,50 @@ XNFasprintf(char ** ret, const char * _X
     return size;
 }
 
+/**
+ * Varargs snprintf that returns the actual number of bytes (excluding final
+ * '\0') that were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param va      variable argument list
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int
+Xvscnprintf(char *s, int n, const char *format, va_list args)
+{
+    int x;
+    if (n == 0)
+        return 0;
+    x = vsnprintf(s, n , format, args);
+    return (x >= n) ? (n - 1) : x;
+}
+
+/**
+ * snprintf that returns the actual number of bytes (excluding final '\0') that
+ * were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param ...     arguments for specified format
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int Xscnprintf(char *s, int n, const char *format, ...)
+{
+    int x;
+    va_list ap;
+    va_start(ap, format);
+    x = Xvscnprintf(s, n, format, ap);
+    va_end(ap);
+    return x;
+}
+
 /* Old api, now deprecated, may be removed in the future */
 char *
 Xvprintf(const char *format, va_list va)