yandex / odyssey

Scalable PostgreSQL connection pooler

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Format string bugs in od_logger_format

adrienstoffel opened this issue · comments

These are security bugs we discovered while auditing a client that uses Odyssey. Sorry if it is not appropriate to report it here but there doesn't seem to be a security contact/policy for this project. Although the bug can lead to an unauthenticated RCE, it's in a non-standard setting so it shouldn't affect many installations.

There are two format string bugs in logger.c:

__attribute__((hot)) static inline int
od_logger_format(od_logger_t *logger, od_logger_level_t level, char *context,
		 od_client_t *client, od_server_t *server, char *fmt,
		 va_list args, char *output, int output_len)
{
     // [...]
			/* user name */
			case 'u':
				if (client && client->startup.user.value_len) {
					len = od_snprintf(
						dst_pos, dst_end - dst_pos,
                                                // missing a "%s" here
						client->startup.user.value); // <-------- first format string,
					dst_pos += len;
					break;
				}
				len = od_snprintf(dst_pos, dst_end - dst_pos,
						  "none");
				dst_pos += len;
				break;
			/* database name */
			case 'd':
				if (client &&
				    client->startup.database.value_len) {
					len = od_snprintf(
						dst_pos, dst_end - dst_pos,
                                                // missing a "%s" here
						client->startup.database.value); // <-------- secondformat string
					dst_pos += len;
					break;
				}
				len = od_snprintf(dst_pos, dst_end - dst_pos,
						  "none");
				dst_pos += len;
				break;

By default the configuration has the following log format directive: log_format "%p %t %l [%i %s] (%c) %m\n". The format string bugs occur whenever the %d (database name) or %u (username) formats are used. Note that log_format itself is a custom format string that is processed by od_logger_format, but it is not the one under attacker control which is the subject of this bug (in od_snprintf).

The database and username are extracted from the startup options during authentication and thus under attacker control. Using format specifiers like %n it becomes possible to overwrite arbitrary memory, which can lead to remote code execution.

To fix the issue you could add a %s format in the calls to od_snprintf(), which will prevent having attacker-controlled input as a format string.

Yes, this looks like a security bug. Thank you for letting us know! Would you like to send a PR with a fix? The design of the fix looks goot to me. Probably, we should file a CVE for this.

Do we need to file a CVE here? So far we don't have a version with the fix...

I don't really care about a CVE for this. It would be more relevant if the log setting that introduces the bug was default or widespread, but I don't think it is.

+1, makes sense.
Thank you!