MDEV-36248 Connect crashes server because of duplicate 'free()' in GetUser

If connect engineis not able to allocate connect_work_space memory for
GetUser() it will call free() twice with the same value (g).

g was freed first in user_connect::user_init() which calls PlugExit() on
errors and then again in ~user_connect() which also calls PlugExit().

Fixed by setting g to 0 in user_init() after calling PlugExit()
This code was tested 'by hand' by setting connect.work_space=600G

Other things:
- Removed some very old not relevant comments in touched code
- Added comments to clarify how some memory was freed
- Fixed indentation in changed functions.
This commit is contained in:
Monty 2025-03-09 14:34:54 +02:00
parent 64a1458847
commit eef94c9d46
2 changed files with 12 additions and 15 deletions

View File

@ -92,11 +92,11 @@ void CntEndDB(PGLOBAL g)
free(dbuserp);
if (trace(1))
htrc("CntEndDB: Freeing Dup\n");
if (trace(1))
htrc("CntEndDB: Freeing Dup\n");
g->Activityp->Aptr = NULL;
} // endif dbuserp
g->Activityp->Aptr = NULL; // Free PlgGetUser() data
} // endif dbuserp
} // end of CntEndDB

View File

@ -101,9 +101,6 @@ bool user_connect::user_init()
PACTIVITY ap= NULL;
PDBUSER dup= NULL;
// Areasize= 64M because of VEC tables. Should be parameterisable
//g= PlugInit(NULL, 67108864);
//g= PlugInit(NULL, 134217728); // 128M was because of old embedded tests
g= PlugInit(NULL, (size_t)worksize);
// Check whether the initialization is complete
@ -113,12 +110,13 @@ bool user_connect::user_init()
printf("%s\n", g->Message);
(void) PlugExit(g);
g= 0;
if (dup)
free(dup);
if (dup)
free(dup);
return true;
} // endif g->
} // endif g->
dup->Catalog= new MYCAT(NULL);
@ -128,17 +126,16 @@ bool user_connect::user_init()
g->Activityp= ap;
g->Activityp->Aptr= dup;
pthread_mutex_lock(&usrmut);
pthread_mutex_lock(&usrmut);
next= to_users;
to_users= this;
if (next)
next->previous= this;
count = 1;
pthread_mutex_unlock(&usrmut);
last_query_id= thdp->query_id;
count = 1;
pthread_mutex_unlock(&usrmut);
last_query_id= thdp->query_id;
return false;
} // end of user_init