CVE-2017-6903 (published 2017-03-14T22:59Z)

In ioquake3 before 2017-03-14, the auto-downloading feature has insufficient content restrictions. This also affects Quake III Arena, OpenArena, OpenJK, iortcw, and other id Tech 3 (aka Quake 3 engine) forks. A malicious auto-downloaded file can trigger loading of crafted auto-downloaded files as native code DLLs. A malicious auto-downloaded file can contain configuration defaults that override the user's. Executable bytecode in a malicious auto-downloaded file can set configuration variables to values that will result in unwanted native code DLLs being loaded, resulting in sandbox escape.

Severity: HIGH
CVSS v2 base score: 9.3 (AV:N/AC:M/Au:N/C:C/I:C/A:C)
CVSS v3 base score: 7.8, HIGH (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/JACoders/OpenJK
commit_details: repo_url: https://github.com/JACoders/OpenJK
author: Ensiform
author_date: 2017-03-13 22:20:58-05:00
msg: Shared: Merge ioquake/ioq3@376267d534476a875d8b9228149c4ee18b74a4fd

Don't load .pk3s as .dlls, and don't load user config files from .pk3s.
repository: repo_url: https://github.com/JACoders/OpenJK
repo_name: JACoders/OpenJK
description: Community effort to maintain and improve Jedi Academy (SP & MP) + Jedi Outcast (SP only) released by Raven Software
repo_language: C++
owner: JACoders
file_changes: filename: cl_main.cpp
change_type: ModificationType.MODIFY
diff: @@ -1084,7 +1084,7 @@ void CL_InitRef( void ) {
 	GetRefAPI_t	GetRefAPI;
 
 	Com_Printf( "----- Initializing Renderer ----\n" );
-    cl_renderer = Cvar_Get( "cl_renderer", DEFAULT_RENDER_LIBRARY, CVAR_ARCHIVE|CVAR_LATCH );
+    cl_renderer = Cvar_Get( "cl_renderer", DEFAULT_RENDER_LIBRARY, CVAR_ARCHIVE|CVAR_LATCH|CVAR_PROTECTED );
 
 	Com_sprintf( dllName, sizeof( dllName ), "%s_" ARCH_STRING DLL_EXT, cl_renderer->string );
 

programming_language: C++
filename: files.cpp
change_type: ModificationType.MODIFY
diff: @@ -1258,6 +1258,7 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 	long			hash;
 	//unz_s			*zfi;
 	//void			*temp;
+	bool			isUserConfig = false;
 
 	hash = 0;
 
@@ -1291,6 +1292,8 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 		return -1;
 	}
 
+	isUserConfig = !Q_stricmp( filename, "autoexec_sp.cfg" ) || !Q_stricmp( filename, Q3CONFIG_NAME );
+
 	//
 	// search through the path, one element at a time
 	//
@@ -1316,6 +1319,11 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 			}
 			// is the element a pak file?
 			if ( search->pack && search->pack->hashTable[hash] ) {
+				// autoexec_sp.cfg and openjk_sp.cfg can only be loaded outside of pk3 files.
+				if ( isUserConfig ) {
+					continue;
+				}
+
 				// look through all the pak file elements
 				pak = search->pack;
 				pakFile = pak->hashTable[hash];

programming_language: Shell
filename: cl_main.cpp
change_type: ModificationType.MODIFY
diff: @@ -2364,7 +2364,7 @@ void CL_InitRef( void ) {
 
 	Com_Printf( "----- Initializing Renderer ----\n" );
 
-	cl_renderer = Cvar_Get( "cl_renderer", DEFAULT_RENDER_LIBRARY, CVAR_ARCHIVE|CVAR_LATCH, "Which renderer library to use" );
+	cl_renderer = Cvar_Get( "cl_renderer", DEFAULT_RENDER_LIBRARY, CVAR_ARCHIVE|CVAR_LATCH|CVAR_PROTECTED, "Which renderer library to use" );
 
 	Com_sprintf( dllName, sizeof( dllName ), "%s_" ARCH_STRING DLL_EXT, cl_renderer->string );
 

programming_language: C++
filename: files.cpp
change_type: ModificationType.MODIFY
diff: @@ -1267,6 +1267,7 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 	//unz_s			*zfi;
 	//void			*temp;
 	int				l;
+	bool			isUserConfig = false;
 
 	hash = 0;
 
@@ -1300,6 +1301,8 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 		return -1;
 	}
 
+	isUserConfig = !Q_stricmp( filename, "autoexec.cfg" ) || !Q_stricmp( filename, Q3CONFIG_CFG );
+
 	//
 	// search through the path, one element at a time
 	//
@@ -1330,6 +1333,11 @@ long FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean unique
 					continue;
 				}
 
+				// autoexec.cfg and openjk.cfg can only be loaded outside of pk3 files.
+				if ( isUserConfig ) {
+					continue;
+				}
+
 				// look through all the pak file elements
 				pak = search->pack;
 				pakFile = pak->hashTable[hash];

programming_language: Shell
filename: sys_main.cpp
change_type: ModificationType.MODIFY
diff: @@ -298,6 +298,13 @@ void *Sys_LoadDll( const char *name, qboolean useSystemLib )
 {
 	void *dllhandle = NULL;
 
+	// Don't load any DLLs that end with the pk3 extension
+	if ( COM_CompareExtension( name, ".pk3" ) )
+	{
+		Com_Printf( S_COLOR_YELLOW "WARNING: Rejecting DLL named \"%s\"", name );
+		return NULL;
+	}
+
 	if ( useSystemLib )
 	{
 		Com_Printf( "Trying to load \"%s\"...\n", name );

programming_language: C++
repo_url: https://github.com/iortcw/iortcw
commit_details: repo_url: https://github.com/iortcw/iortcw
author: MAN-AT-ARMS
author_date: 2017-03-13 19:37:39-04:00
msg: All: Don't load .pk3s as .dlls, and don't load user config files from .pk3s
repository: repo_url: https://github.com/iortcw/iortcw
repo_name: iortcw/iortcw
description: Merge of ioquake3 features and fixes into RTCW code bases
repo_language: C
owner: iortcw
file_changes: filename: cl_main.c
change_type: ModificationType.MODIFY
diff: @@ -3674,7 +3674,7 @@ void CL_InitRef( void ) {
 	Com_Printf( "----- Initializing Renderer ----\n" );
 
 #ifdef USE_RENDERER_DLOPEN
-	cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH);
+	cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED);
 
 	Com_sprintf(dllName, sizeof(dllName), "renderer_mp_%s_" ARCH_STRING DLL_EXT, cl_renderer->string);
 
@@ -4014,7 +4014,7 @@ void CL_Init( void ) {
 
 	cl_allowDownload = Cvar_Get( "cl_allowDownload", "1", CVAR_ARCHIVE );
 #ifdef USE_CURL_DLOPEN
-	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE);
+	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE | CVAR_PROTECTED);
 #endif
 
 	// init autoswitch so the ui will have it correctly even

programming_language: C
filename: files.c
change_type: ModificationType.MODIFY
diff: @@ -1424,12 +1424,18 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF
 {
 	searchpath_t *search;
 	long len;
+	qboolean isLocalConfig;
 
 	if(!fs_searchpaths)
 		Com_Error(ERR_FATAL, "Filesystem call made without initialization");
 
+	isLocalConfig = !strcmp(filename, "autoexec.cfg") || !strcmp(filename, Q3CONFIG_CFG);
 	for(search = fs_searchpaths; search; search = search->next)
 	{
+		// autoexec.cfg and wolfconfig_mp.cfg can only be loaded outside of pk3 files.
+		if (isLocalConfig && search->pack)
+			continue;
+
 	        len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE, qfalse);
 	        
 	        if(file == NULL)

programming_language: TeX
filename: sys_main.c
change_type: ModificationType.MODIFY
diff: @@ -499,6 +499,13 @@ from executable path, then fs_basepath.
 void *Sys_LoadDll(const char *name, qboolean useSystemLib)
 {
 	void *dllhandle;
+
+	// Don't load any DLLs that end with the pk3 extension
+	if (COM_CompareExtension(name, ".pk3"))
+	{
+		Com_Printf("Rejecting DLL named \"%s\"", name);
+		return NULL;
+	}
 	
 	if(useSystemLib)
 		Com_Printf("Trying to load \"%s\"...\n", name);

programming_language: C
filename: cl_main.c
change_type: ModificationType.MODIFY
diff: @@ -3348,7 +3348,7 @@ void CL_InitRef( void ) {
 	Com_Printf( "----- Initializing Renderer ----\n" );
 
 #ifdef USE_RENDERER_DLOPEN
-	cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH);
+	cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED);
 
 	Com_sprintf(dllName, sizeof(dllName), "renderer_sp_%s_" ARCH_STRING DLL_EXT, cl_renderer->string);
 
@@ -3690,7 +3690,7 @@ void CL_Init( void ) {
 
 	cl_allowDownload = Cvar_Get( "cl_allowDownload", "0", CVAR_ARCHIVE );
 #ifdef USE_CURL_DLOPEN
-	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE);
+	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE | CVAR_PROTECTED);
 #endif
 
 	// init autoswitch so the ui will have it correctly even

programming_language: C
filename: files.c
change_type: ModificationType.MODIFY
diff: @@ -1591,12 +1591,18 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF
 {
 	searchpath_t *search;
 	long len;
+	qboolean isLocalConfig;
 
 	if(!fs_searchpaths)
 		Com_Error(ERR_FATAL, "Filesystem call made without initialization");
 
+	isLocalConfig = !strcmp(filename, "autoexec.cfg") || !strcmp(filename, Q3CONFIG_CFG);
 	for(search = fs_searchpaths; search; search = search->next)
 	{
+		// autoexec.cfg and wolfconfig.cfg can only be loaded outside of pk3 files.
+		if (isLocalConfig && search->pack)
+			continue;
+
 		len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE, qfalse);
 
 		if(file == NULL)

programming_language: TeX
filename: sys_main.c
change_type: ModificationType.MODIFY
diff: @@ -499,6 +499,13 @@ from executable path, then fs_basepath.
 void *Sys_LoadDll(const char *name, qboolean useSystemLib)
 {
 	void *dllhandle;
+
+	// Don't load any DLLs that end with the pk3 extension
+	if (COM_CompareExtension(name, ".pk3"))
+	{
+		Com_Printf("Rejecting DLL named \"%s\"", name);
+		return NULL;
+	}
 	
 	if(useSystemLib)
 		Com_Printf("Trying to load \"%s\"...\n", name);

programming_language: C
repo_url: https://github.com/iortcw/iortcw
commit_details: repo_url: https://github.com/iortcw/iortcw
author: MAN-AT-ARMS
author_date: 2017-03-14 03:25:17-04:00
msg: All: Don't open .pk3 files as OpenAL drivers
repository: repo_url: https://github.com/iortcw/iortcw
repo_name: iortcw/iortcw
description: Merge of ioquake3 features and fixes into RTCW code bases
repo_language: C
owner: iortcw
file_changes: filename: snd_openal.c
change_type: ModificationType.MODIFY
diff: @@ -2618,11 +2618,17 @@ qboolean S_AL_Init( soundInterface_t *si )
 	s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT);
 	s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT);
 
-	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH );
+	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED );
 
 	s_alInputDevice = Cvar_Get( "s_alInputDevice", "", CVAR_ARCHIVE | CVAR_LATCH );
 	s_alDevice = Cvar_Get("s_alDevice", "", CVAR_ARCHIVE | CVAR_LATCH);
 
+	if ( COM_CompareExtension( s_alDriver->string, ".pk3" ) )
+	{
+		Com_Printf( "Rejecting DLL named \"%s\"", s_alDriver->string );
+		return qfalse;
+	}
+
 	// Load QAL
 	if( !QAL_Init( s_alDriver->string ) )
  	{

programming_language: C++
filename: snd_openal.c
change_type: ModificationType.MODIFY
diff: @@ -2675,11 +2675,17 @@ qboolean S_AL_Init( soundInterface_t *si )
 	s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_ARCHIVE);
 	s_alTalkAnims = Cvar_Get("s_alTalkAnims", "160", CVAR_ARCHIVE);
 
-	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH );
+	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED );
 
 	s_alInputDevice = Cvar_Get( "s_alInputDevice", "", CVAR_ARCHIVE | CVAR_LATCH );
 	s_alDevice = Cvar_Get("s_alDevice", "", CVAR_ARCHIVE | CVAR_LATCH);
 
+	if ( COM_CompareExtension( s_alDriver->string, ".pk3" ) )
+	{
+		Com_Printf( "Rejecting DLL named \"%s\"", s_alDriver->string );
+		return qfalse;
+	}
+
 	// Load QAL
 	if( !QAL_Init( s_alDriver->string ) )
  	{

programming_language: C++
repo_url: https://github.com/iortcw/iortcw
commit_details: repo_url: https://github.com/iortcw/iortcw
author: MAN-AT-ARMS
author_date: 2017-03-14 03:26:09-04:00
msg: All: Merge some file writing extension checks
repository: repo_url: https://github.com/iortcw/iortcw
repo_name: iortcw/iortcw
description: Merge of ioquake3 features and fixes into RTCW code bases
repo_language: C
owner: iortcw
file_changes: filename: cl_console.c
change_type: ModificationType.MODIFY
diff: @@ -227,6 +227,12 @@ void Con_Dump_f( void ) {
 	Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".txt" );
 
+	if (!COM_CompareExtension(filename, ".txt"))
+	{
+		Com_Printf("Con_Dump_f: Only the \".txt\" extension is supported by this command!\n");
+		return;
+	}
+
 	f = FS_FOpenFileWrite( filename );
 	if ( !f ) {
 		Com_Printf ("ERROR: couldn't open %s.\n", filename);

programming_language: C++
filename: common.c
change_type: ModificationType.MODIFY
diff: @@ -3058,6 +3058,12 @@ void Com_WriteConfig_f( void ) {
 		return;
 	}
 
+	if (!COM_CompareExtension(filename, ".cfg"))
+	{
+		Com_Printf("Com_WriteConfig_f: Only the \".cfg\" extension is supported by this command!\n");
+		return;
+	}
+
 	Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
 	Com_Printf( "Writing %s.\n", filename );

programming_language: C++
filename: cl_console.c
change_type: ModificationType.MODIFY
diff: @@ -219,6 +219,12 @@ void Con_Dump_f( void ) {
 	Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".txt" );
 
+	if (!COM_CompareExtension(filename, ".txt"))
+	{
+		Com_Printf("Con_Dump_f: Only the \".txt\" extension is supported by this command!\n");
+		return;
+	}
+
 	f = FS_FOpenFileWrite( filename );
 	if ( !f ) {
 		Com_Printf ("ERROR: couldn't open %s.\n", filename);

programming_language: C++
filename: common.c
change_type: ModificationType.MODIFY
diff: @@ -2601,6 +2601,12 @@ void Com_WriteConfig_f( void ) {
 		return;
 	}
 
+	if (!COM_CompareExtension(filename, ".cfg"))
+	{
+		Com_Printf("Com_WriteConfig_f: Only the \".cfg\" extension is supported by this command!\n");
+		return;
+	}
+
 	Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
 	Com_Printf( "Writing %s.\n", filename );

programming_language: C++
repo_url: https://github.com/ioquake/ioq3
commit_details: repo_url: https://github.com/ioquake/ioq3
author: SmileTheory
author_date: 2017-03-13 20:28:37-07:00
msg: Don't open .pk3 files as OpenAL drivers.
repository: repo_url: https://github.com/ioquake/ioq3
repo_name: ioquake/ioq3
description: The ioquake3 community effort to continue supporting/developing id's Quake III Arena
repo_language: C
owner: ioquake
file_changes: filename: snd_openal.c
change_type: ModificationType.MODIFY
diff: @@ -2512,11 +2512,17 @@ qboolean S_AL_Init( soundInterface_t *si )
 	s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT);
 	s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT);
 
-	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH );
+	s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED );
 
 	s_alInputDevice = Cvar_Get( "s_alInputDevice", "", CVAR_ARCHIVE | CVAR_LATCH );
 	s_alDevice = Cvar_Get("s_alDevice", "", CVAR_ARCHIVE | CVAR_LATCH);
 
+	if ( COM_CompareExtension( s_alDriver->string, ".pk3" ) )
+	{
+		Com_Printf( "Rejecting DLL named \"%s\"", s_alDriver->string );
+		return qfalse;
+	}
+
 	// Load QAL
 	if( !QAL_Init( s_alDriver->string ) )
 	{

programming_language: C++
repo_url: https://github.com/ioquake/ioq3
commit_details: repo_url: https://github.com/ioquake/ioq3
author: SmileTheory
author_date: 2017-03-13 20:44:47-07:00
msg: Merge some file writing extension checks from OpenJK.

Thanks Ensiform.
https://github.com/JACoders/OpenJK/commit/05928a57f9e4aae15a3bd0
https://github.com/JACoders/OpenJK/commit/ef124fd0fc48af164581176
repository: repo_url: https://github.com/ioquake/ioq3
repo_name: ioquake/ioq3
description: The ioquake3 community effort to continue supporting/developing id's Quake III Arena
repo_language: C
owner: ioquake
file_changes: filename: cl_console.c
change_type: ModificationType.MODIFY
diff: @@ -191,6 +191,12 @@ void Con_Dump_f (void)
 	Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".txt" );
 
+	if (!COM_CompareExtension(filename, ".txt"))
+	{
+		Com_Printf("Con_Dump_f: Only the \".txt\" extension is supported by this command!\n");
+		return;
+	}
+
 	f = FS_FOpenFileWrite( filename );
 	if (!f)
 	{

programming_language: C
filename: common.c
change_type: ModificationType.MODIFY
diff: @@ -2975,6 +2975,13 @@ void Com_WriteConfig_f( void ) {
 		return;
 	}
 
+
+	if (!COM_CompareExtension(filename, ".cfg"))
+	{
+		Com_Printf("Com_WriteConfig_f: Only the \".cfg\" extension is supported by this command!\n");
+		return;
+	}
+
 	Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) );
 	COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
 	Com_Printf( "Writing %s.\n", filename );

programming_language: C++
repo_url: https://github.com/ioquake/ioq3
commit_details: repo_url: https://github.com/ioquake/ioq3
author: SmileTheory
author_date: 2017-03-13 14:14:00-07:00
msg: Don't load .pk3s as .dlls, and don't load user config files from .pk3s.
repository: repo_url: https://github.com/ioquake/ioq3
repo_name: ioquake/ioq3
description: The ioquake3 community effort to continue supporting/developing id's Quake III Arena
repo_language: C
owner: ioquake
file_changes: filename: cl_main.c
change_type: ModificationType.MODIFY
diff: @@ -3200,7 +3200,7 @@ void CL_InitRef( void ) {
 	Com_Printf( "----- Initializing Renderer ----\n" );
 
 #ifdef USE_RENDERER_DLOPEN
-	cl_renderer = Cvar_Get("cl_renderer", "opengl2", CVAR_ARCHIVE | CVAR_LATCH);
+	cl_renderer = Cvar_Get("cl_renderer", "opengl2", CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED);
 
 	Com_sprintf(dllName, sizeof(dllName), "renderer_%s_" ARCH_STRING DLL_EXT, cl_renderer->string);
 
@@ -3551,7 +3551,7 @@ void CL_Init( void ) {
 
 	cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE);
 #ifdef USE_CURL_DLOPEN
-	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE);
+	cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE | CVAR_PROTECTED);
 #endif
 
 	cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);

programming_language: C
filename: files.c
change_type: ModificationType.MODIFY
diff: @@ -1364,12 +1364,18 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF
 {
 	searchpath_t *search;
 	long len;
+	qboolean isLocalConfig;
 
 	if(!fs_searchpaths)
 		Com_Error(ERR_FATAL, "Filesystem call made without initialization");
 
+	isLocalConfig = !strcmp(filename, "autoexec.cfg") || !strcmp(filename, Q3CONFIG_CFG);
 	for(search = fs_searchpaths; search; search = search->next)
 	{
+		// autoexec.cfg and q3config.cfg can only be loaded outside of pk3 files.
+		if (isLocalConfig && search->pack)
+			continue;
+
 		len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE, qfalse);
 
 		if(file == NULL)

programming_language: Shell
filename: sys_main.c
change_type: ModificationType.MODIFY
diff: @@ -500,6 +500,13 @@ void *Sys_LoadDll(const char *name, qboolean useSystemLib)
 {
 	void *dllhandle;
 	
+	// Don't load any DLLs that end with the pk3 extension
+	if (COM_CompareExtension(name, ".pk3"))
+	{
+		Com_Printf("Rejecting DLL named \"%s\"", name);
+		return NULL;
+	}
+
 	if(useSystemLib)
 		Com_Printf("Trying to load \"%s\"...\n", name);
 	

programming_language: C