From: msweet Date: Fri, 23 Oct 2015 21:17:33 +0000 (+0000) Subject: Escape strings in error_log output () X-Git-Tag: v2.2b1~170 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=59189c00d265f2fa9787807a235a67d5962e853b;p=thirdparty%2Fcups.git Escape strings in error_log output () git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12925 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/CHANGES-2.1.txt b/CHANGES-2.1.txt index 41de655a48..f2f5c1e66f 100644 --- a/CHANGES-2.1.txt +++ b/CHANGES-2.1.txt @@ -6,7 +6,7 @@ CHANGES IN CUPS V2.1.1 - Security hardening fixes (, , , , , - ) + , ) - The cupsGetPPD* functions did not work with IPP printers (STR #4725) - Some older HP LaserJet printers need a delayed close when printing using the libusb-based USB backend (STR #4549) diff --git a/cups/debug.c b/cups/debug.c index ed1852d843..3ee3a19007 100644 --- a/cups/debug.c +++ b/cups/debug.c @@ -3,7 +3,7 @@ * * Debugging functions for CUPS. * - * Copyright 2008-2014 by Apple Inc. + * Copyright 2008-2015 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -82,14 +82,258 @@ debug_thread_id(void) /* - * 'debug_vsnprintf()' - Format a string into a fixed size buffer. + * '_cups_debug_printf()' - Write a formatted line to the log. + */ + +void DLLExport +_cups_debug_printf(const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + struct timeval curtime; /* Current time */ + char buffer[2048]; /* Output buffer */ + ssize_t bytes; /* Number of bytes in buffer */ + int level; /* Log level in message */ + + + /* + * See if we need to do any logging... + */ + + if (!debug_init) + _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"), + getenv("CUPS_DEBUG_FILTER"), 0); + + if (_cups_debug_fd < 0) + return; + + /* + * Filter as needed... + */ + + if (isdigit(format[0])) + level = *format++ - '0'; + else + level = 0; + + if (level > _cups_debug_level) + return; + + if (debug_filter) + { + int result; /* Filter result */ + + _cupsMutexLock(&debug_init_mutex); + result = regexec(debug_filter, format, 0, NULL, 0); + _cupsMutexUnlock(&debug_init_mutex); + + if (result) + return; + } + + /* + * Format the message... + */ + + gettimeofday(&curtime, NULL); + snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d ", + debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24), + (int)((curtime.tv_sec / 60) % 60), + (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000)); + + va_start(ap, format); + bytes = _cups_safe_vsnprintf(buffer + 19, sizeof(buffer) - 20, format, ap) + 19; + va_end(ap); + + if ((size_t)bytes >= (sizeof(buffer) - 1)) + { + buffer[sizeof(buffer) - 2] = '\n'; + bytes = sizeof(buffer) - 1; + } + else if (buffer[bytes - 1] != '\n') + { + buffer[bytes++] = '\n'; + buffer[bytes] = '\0'; + } + + /* + * Write it out... + */ + + _cupsMutexLock(&debug_log_mutex); + write(_cups_debug_fd, buffer, (size_t)bytes); + _cupsMutexUnlock(&debug_log_mutex); +} + + +/* + * '_cups_debug_puts()' - Write a single line to the log. + */ + +void DLLExport +_cups_debug_puts(const char *s) /* I - String to output */ +{ + struct timeval curtime; /* Current time */ + char buffer[2048]; /* Output buffer */ + ssize_t bytes; /* Number of bytes in buffer */ + int level; /* Log level in message */ + + + /* + * See if we need to do any logging... + */ + + if (!debug_init) + _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"), + getenv("CUPS_DEBUG_FILTER"), 0); + + if (_cups_debug_fd < 0) + return; + + /* + * Filter as needed... + */ + + if (isdigit(s[0])) + level = *s++ - '0'; + else + level = 0; + + if (level > _cups_debug_level) + return; + + if (debug_filter) + { + int result; /* Filter result */ + + _cupsMutexLock(&debug_init_mutex); + result = regexec(debug_filter, s, 0, NULL, 0); + _cupsMutexUnlock(&debug_init_mutex); + + if (result) + return; + } + + /* + * Format the message... + */ + + gettimeofday(&curtime, NULL); + bytes = snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d %s", + debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24), + (int)((curtime.tv_sec / 60) % 60), + (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000), + s); + + if ((size_t)bytes >= (sizeof(buffer) - 1)) + { + buffer[sizeof(buffer) - 2] = '\n'; + bytes = sizeof(buffer) - 1; + } + else if (buffer[bytes - 1] != '\n') + { + buffer[bytes++] = '\n'; + buffer[bytes] = '\0'; + } + + /* + * Write it out... + */ + + _cupsMutexLock(&debug_log_mutex); + write(_cups_debug_fd, buffer, (size_t)bytes); + _cupsMutexUnlock(&debug_log_mutex); +} + + +/* + * '_cups_debug_set()' - Enable or disable debug logging. + */ + +void DLLExport +_cups_debug_set(const char *logfile, /* I - Log file or NULL */ + const char *level, /* I - Log level or NULL */ + const char *filter, /* I - Filter string or NULL */ + int force) /* I - Force initialization */ +{ + _cupsMutexLock(&debug_init_mutex); + + if (!debug_init || force) + { + /* + * Restore debug settings to defaults... + */ + + if (_cups_debug_fd != -1) + { + close(_cups_debug_fd); + _cups_debug_fd = -1; + } + + if (debug_filter) + { + regfree((regex_t *)debug_filter); + debug_filter = NULL; + } + + _cups_debug_level = 1; + + /* + * Open logs, set log levels, etc. + */ + + if (!logfile) + _cups_debug_fd = -1; + else if (!strcmp(logfile, "-")) + _cups_debug_fd = 2; + else + { + char buffer[1024]; /* Filename buffer */ + + snprintf(buffer, sizeof(buffer), logfile, getpid()); + + if (buffer[0] == '+') + _cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644); + else + _cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644); + } + + if (level) + _cups_debug_level = atoi(level); + + if (filter) + { + if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL) + fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not " + "filtered!\n", stderr); + else if (regcomp(debug_filter, filter, REG_EXTENDED)) + { + fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not " + "filtered!\n", stderr); + free(debug_filter); + debug_filter = NULL; + } + } + + debug_init = 1; + } + + _cupsMutexUnlock(&debug_init_mutex); +} +#endif /* DEBUG */ + + +/* + * '_cups_safe_vsnprintf()' - Format a string into a fixed size buffer, + * quoting special characters. */ -static ssize_t /* O - Number of bytes formatted */ -debug_vsnprintf(char *buffer, /* O - Output buffer */ - size_t bufsize, /* O - Size of output buffer */ - const char *format, /* I - printf-style format string */ - va_list ap) /* I - Pointer to additional arguments */ +ssize_t /* O - Number of bytes formatted */ +_cups_safe_vsnprintf( + char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - printf-style format string */ + va_list ap) /* I - Pointer to additional arguments */ { char *bufptr, /* Pointer to position in buffer */ *bufend, /* Pointer to end of buffer */ @@ -400,248 +644,6 @@ debug_vsnprintf(char *buffer, /* O - Output buffer */ } -/* - * '_cups_debug_printf()' - Write a formatted line to the log. - */ - -void DLLExport -_cups_debug_printf(const char *format, /* I - Printf-style format string */ - ...) /* I - Additional arguments as needed */ -{ - va_list ap; /* Pointer to arguments */ - struct timeval curtime; /* Current time */ - char buffer[2048]; /* Output buffer */ - ssize_t bytes; /* Number of bytes in buffer */ - int level; /* Log level in message */ - - - /* - * See if we need to do any logging... - */ - - if (!debug_init) - _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"), - getenv("CUPS_DEBUG_FILTER"), 0); - - if (_cups_debug_fd < 0) - return; - - /* - * Filter as needed... - */ - - if (isdigit(format[0])) - level = *format++ - '0'; - else - level = 0; - - if (level > _cups_debug_level) - return; - - if (debug_filter) - { - int result; /* Filter result */ - - _cupsMutexLock(&debug_init_mutex); - result = regexec(debug_filter, format, 0, NULL, 0); - _cupsMutexUnlock(&debug_init_mutex); - - if (result) - return; - } - - /* - * Format the message... - */ - - gettimeofday(&curtime, NULL); - snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d ", - debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24), - (int)((curtime.tv_sec / 60) % 60), - (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000)); - - va_start(ap, format); - bytes = debug_vsnprintf(buffer + 19, sizeof(buffer) - 20, format, ap) + 19; - va_end(ap); - - if ((size_t)bytes >= (sizeof(buffer) - 1)) - { - buffer[sizeof(buffer) - 2] = '\n'; - bytes = sizeof(buffer) - 1; - } - else if (buffer[bytes - 1] != '\n') - { - buffer[bytes++] = '\n'; - buffer[bytes] = '\0'; - } - - /* - * Write it out... - */ - - _cupsMutexLock(&debug_log_mutex); - write(_cups_debug_fd, buffer, (size_t)bytes); - _cupsMutexUnlock(&debug_log_mutex); -} - - -/* - * '_cups_debug_puts()' - Write a single line to the log. - */ - -void DLLExport -_cups_debug_puts(const char *s) /* I - String to output */ -{ - struct timeval curtime; /* Current time */ - char buffer[2048]; /* Output buffer */ - ssize_t bytes; /* Number of bytes in buffer */ - int level; /* Log level in message */ - - - /* - * See if we need to do any logging... - */ - - if (!debug_init) - _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"), - getenv("CUPS_DEBUG_FILTER"), 0); - - if (_cups_debug_fd < 0) - return; - - /* - * Filter as needed... - */ - - if (isdigit(s[0])) - level = *s++ - '0'; - else - level = 0; - - if (level > _cups_debug_level) - return; - - if (debug_filter) - { - int result; /* Filter result */ - - _cupsMutexLock(&debug_init_mutex); - result = regexec(debug_filter, s, 0, NULL, 0); - _cupsMutexUnlock(&debug_init_mutex); - - if (result) - return; - } - - /* - * Format the message... - */ - - gettimeofday(&curtime, NULL); - bytes = snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d %s", - debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24), - (int)((curtime.tv_sec / 60) % 60), - (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000), - s); - - if ((size_t)bytes >= (sizeof(buffer) - 1)) - { - buffer[sizeof(buffer) - 2] = '\n'; - bytes = sizeof(buffer) - 1; - } - else if (buffer[bytes - 1] != '\n') - { - buffer[bytes++] = '\n'; - buffer[bytes] = '\0'; - } - - /* - * Write it out... - */ - - _cupsMutexLock(&debug_log_mutex); - write(_cups_debug_fd, buffer, (size_t)bytes); - _cupsMutexUnlock(&debug_log_mutex); -} - - -/* - * '_cups_debug_set()' - Enable or disable debug logging. - */ - -void DLLExport -_cups_debug_set(const char *logfile, /* I - Log file or NULL */ - const char *level, /* I - Log level or NULL */ - const char *filter, /* I - Filter string or NULL */ - int force) /* I - Force initialization */ -{ - _cupsMutexLock(&debug_init_mutex); - - if (!debug_init || force) - { - /* - * Restore debug settings to defaults... - */ - - if (_cups_debug_fd != -1) - { - close(_cups_debug_fd); - _cups_debug_fd = -1; - } - - if (debug_filter) - { - regfree((regex_t *)debug_filter); - debug_filter = NULL; - } - - _cups_debug_level = 1; - - /* - * Open logs, set log levels, etc. - */ - - if (!logfile) - _cups_debug_fd = -1; - else if (!strcmp(logfile, "-")) - _cups_debug_fd = 2; - else - { - char buffer[1024]; /* Filename buffer */ - - snprintf(buffer, sizeof(buffer), logfile, getpid()); - - if (buffer[0] == '+') - _cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644); - else - _cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644); - } - - if (level) - _cups_debug_level = atoi(level); - - if (filter) - { - if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL) - fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not " - "filtered!\n", stderr); - else if (regcomp(debug_filter, filter, REG_EXTENDED)) - { - fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not " - "filtered!\n", stderr); - free(debug_filter); - debug_filter = NULL; - } - } - - debug_init = 1; - } - - _cupsMutexUnlock(&debug_init_mutex); -} -#endif /* DEBUG */ - - /* * End of "$Id$". */ diff --git a/cups/string-private.h b/cups/string-private.h index 1a02be1cf6..845bfc9d2c 100644 --- a/cups/string-private.h +++ b/cups/string-private.h @@ -3,7 +3,7 @@ * * Private string definitions for CUPS. * - * Copyright 2007-2014 by Apple Inc. + * Copyright 2007-2015 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -147,6 +147,7 @@ extern int _cups_toupper(int ch); * Prototypes... */ +extern ssize_t _cups_safe_vsnprintf(char *, size_t, const char *, va_list); extern void _cups_strcpy(char *dst, const char *src); # ifndef HAVE_STRDUP diff --git a/scheduler/log.c b/scheduler/log.c index fce8797c84..b48b7a740c 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -1476,7 +1476,7 @@ format_log_line(const char *message, /* I - Printf-style format string */ * Format the log message... */ - len = vsnprintf(log_line, log_linesize, message, ap); + len = _cups_safe_vsnprintf(log_line, log_linesize, message, ap); /* * Resize the buffer as needed... @@ -1486,7 +1486,6 @@ format_log_line(const char *message, /* I - Printf-style format string */ { char *temp; /* Temporary string pointer */ - len ++; if (len < 8192)