Changeset: f303c8e3e070 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f303c8e3e070
Modified Files:
        monetdb5/mal/mal_client.c
        monetdb5/modules/mal/clients.c
        monetdb5/modules/mal/clients.h
        monetdb5/modules/mal/clients.mal
Branch: linear-hashing
Log Message:

Hold mal_contextLock while changing a property of another client. A race 
condition could happen where the user being set it's not the same one when the 
MAL call started


diffs (truncated from 478 to 300 lines):

diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -637,7 +637,6 @@ MCreadClient(Client c)
        return 1;
 }
 
-
 int
 MCvalid(Client tc)
 {
diff --git a/monetdb5/modules/mal/clients.c b/monetdb5/modules/mal/clients.c
--- a/monetdb5/modules/mal/clients.c
+++ b/monetdb5/modules/mal/clients.c
@@ -186,82 +186,91 @@ bailout:
 str
 CLTquit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int id;
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx;
        (void) mb;              /* fool compiler */
 
-       if ( pci->argc==2)
-               id = *getArgReference_int(stk,pci,1);
-       else id =cntxt->idx;
+       if ( pci->argc == 2 && cntxt->user == MAL_ADMIN)
+               idx = *getArgReference_int(stk,pci,1);
 
-       if ( id < 0 || id > MAL_MAXCLIENTS)
+       if ( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.quit", "Illegal session id");
-       if ( !(cntxt->user == MAL_ADMIN || mal_clients[id].user == cntxt->user) 
)
-               throw(MAL, "client.quit", INVCRED_ACCESS_DENIED);
 
        /* A user can only quite a session under the same id */
-       if ( cntxt->idx == mal_clients[id].idx)
-               mal_clients[id].mode = FINISHCLIENT;
-       else 
-               throw(MAL, "client.quit", INVCRED_ACCESS_DENIED);
-       return MAL_SUCCEED;
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT)
+               msg = createException(MAL,"clients.stop","Session not active 
anymore");
+       else
+               mal_clients[idx].mode = FINISHCLIENT;
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 /* Stopping a client in a softmanner by setting the time out marker */
 str
 CLTstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int id = *getArgReference_int(stk,pci,1);
+       int idx = cntxt->idx;
+       str msg = MAL_SUCCEED;
 
        (void) mb;
-       if ( id < 0 || id > MAL_MAXCLIENTS)
+       if (cntxt->user == MAL_ADMIN)
+               idx = *getArgReference_int(stk,pci,1);
+
+       if ( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.stop","Illegal session id");
-       if (cntxt->user == mal_clients[id].user || cntxt->user == MAL_ADMIN)
-               mal_clients[id].querytimeout = 1; /* stop client in one 
microsecond */
+       
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT)
+               msg = createException(MAL,"clients.stop","Session not active 
anymore");
+       else
+               mal_clients[idx].querytimeout = 1; /* stop client in one 
microsecond */
        /* this forces the designated client to stop at the next instruction */
-       return MAL_SUCCEED;
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 str
 CLTsetoptimizer(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int idx;
-       str opt;
+       int idx = cntxt->idx;
+       str opt, msg = MAL_SUCCEED;
 
        (void) mb;
-       if( pci->argc == 3){
+       if( pci->argc == 3 && cntxt->user == MAL_ADMIN){
                idx = *getArgReference_int(stk,pci,1);
                opt = *getArgReference_str(stk,pci,2);
        } else {
-               idx = cntxt->idx;
                opt = *getArgReference_str(stk,pci,1);
        }
 
        if( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.setoptimizer","Illegal session id");
+       if (strNil(opt))
+               throw(MAL,"clients.setoptimizer","Input string cannot be NULL");
+       if (strlen(opt) >= sizeof(mal_clients[idx].optimizer))
+               throw(MAL,"clients.setoptimizer","Input string is too large");
+
+       MT_lock_set(&mal_contextLock);
        if (mal_clients[idx].mode == FREECLIENT)
-               throw(MAL,"clients.setoptimizer","Session not active anymore");
-       if (cntxt->user == mal_clients[idx].user || cntxt->user == MAL_ADMIN){
-               if (strNil(opt))
-                       throw(MAL,"clients.setoptimizer","Input string cannot 
be NULL");
-               if (strlen(opt) >= sizeof(mal_clients[idx].optimizer))
-                       throw(MAL,"clients.setoptimizer","Input string is too 
large");
-               strcpy_len(mal_clients[idx].optimizer, opt,
-                          sizeof(mal_clients[idx].optimizer));
-       }
-       return MAL_SUCCEED;
+               msg = createException(MAL,"clients.setoptimizer","Session not 
active anymore");
+       else
+               strcpy_len(mal_clients[idx].optimizer, opt, 
sizeof(mal_clients[idx].optimizer));
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 str
 CLTsetworkerlimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int idx, limit;
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx, limit;
 
        (void) mb;
-       if(pci->argc == 3){
+       if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
                idx = *getArgReference_int(stk,pci,1);
                limit = *getArgReference_int(stk,pci,2);
        } else {
-               idx = cntxt->idx;
                limit = *getArgReference_int(stk,pci,1);
        }
 
@@ -271,128 +280,164 @@ CLTsetworkerlimit(Client cntxt, MalBlkPt
                throw(MAL, "clients.setworkerlimit","The number of workers 
cannot be NULL");
        if( limit < 0)
                throw(MAL, "clients.setworkerlimit","The number of workers 
cannot be negative");
+
+       MT_lock_set(&mal_contextLock);
        if (mal_clients[idx].mode == FREECLIENT)
-               throw(MAL,"clients.setworkerlimit","Session not active 
anymore");
-       if (cntxt->user == mal_clients[idx].user || cntxt->user == MAL_ADMIN){
+               msg = createException(MAL,"clients.setworkerlimit","Session not 
active anymore");
+       else
                mal_clients[idx].workerlimit = limit;
-       }
-       return MAL_SUCCEED;
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 str
 CLTsetmemorylimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int idx, limit;
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx, limit;
 
        (void) mb;
-       if(pci->argc == 3){
+       if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
                idx = *getArgReference_sht(stk,pci,1);
                limit = *getArgReference_int(stk,pci,2);
-       } else{
-               idx = cntxt->idx;
+       } else {
                limit = *getArgReference_int(stk,pci,1);
        }
 
        if( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.setmemorylimit","Illegal session id");
-       if (mal_clients[idx].mode == FREECLIENT)
-               throw(MAL,"clients.setmemorylimit","Session not active 
anymore");
        if( is_int_nil(limit))
                throw(MAL, "clients.setmemorylimit", "The memmory limit cannot 
be NULL");
        if( limit < 0)
                throw(MAL, "clients.setmemorylimit", "The memmory limit cannot 
be negative");
-       if (cntxt->user == mal_clients[idx].user || cntxt->user == MAL_ADMIN){
+
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT)
+               msg = createException(MAL,"clients.setmemorylimit","Session not 
active anymore");
+       else
                mal_clients[idx].memorylimit = limit;
-       }
-       return MAL_SUCCEED;
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 str
 CLTstopSession(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int idx;
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx;
 
-       (void) mb;
-       switch( getArgType(mb,pci,1)){
-       case TYPE_bte:
-               idx = *getArgReference_bte(stk,pci,1);
-               break;
-       case TYPE_sht:
-               idx = *getArgReference_sht(stk,pci,1);
-               break;
-       case TYPE_int:
-               idx = *getArgReference_int(stk,pci,1);
-               break;
-       default:
-               throw(MAL,"clients.stopSession","Unexpected index type");
+       if (cntxt->user == MAL_ADMIN) {
+               switch( getArgType(mb,pci,1)){
+               case TYPE_bte:
+                       idx = *getArgReference_bte(stk,pci,1);
+                       break;
+               case TYPE_sht:
+                       idx = *getArgReference_sht(stk,pci,1);
+                       break;
+               case TYPE_int:
+                       idx = *getArgReference_int(stk,pci,1);
+                       break;
+               default:
+                       throw(MAL,"clients.stopSession","Unexpected index 
type");
+               }
        }
        if( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.stopSession","Illegal session id");
-       if (mal_clients[idx].mode == FREECLIENT)
-               throw(MAL,"clients.stopSession","Session not active anymore");
-       if (cntxt->user == mal_clients[idx].user || cntxt->user == MAL_ADMIN){
+
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT) {
+               msg = createException(MAL,"clients.stopSession","Session not 
active anymore");
+       } else {
                mal_clients[idx].querytimeout = 1; /* stop client in one 
microsecond */
                mal_clients[idx].sessiontimeout = 1; /* stop client session */
        }
+       MT_lock_unset(&mal_contextLock);
        /* this forces the designated client to stop at the next instruction */
-       return MAL_SUCCEED;
+       return msg;
 }
 
 /* Queries can be temporarily suspended */
 str
 CLTsuspend(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       int id = *getArgReference_int(stk,pci,1);
-       (void) cntxt;
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx;
+       
+       if (cntxt->user == MAL_ADMIN)
+               idx = *getArgReference_int(stk,pci,1);
        (void) mb;
 
-       if ( id < 0 || id > MAL_MAXCLIENTS)
+       if( idx < 0 || idx > MAL_MAXCLIENTS)
                throw(MAL,"clients.suspend", "Illegal session id");
-       if ( !(cntxt->user == MAL_ADMIN || mal_clients[id].user == cntxt->user) 
)
-               throw(MAL, "client.suspend", INVCRED_ACCESS_DENIED);
-       return MCsuspendClient(id);
+
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT)
+               msg = createException(MAL,"clients.suspend","Session not active 
anymore");
+       else
+               msg = MCsuspendClient(idx);
+       MT_lock_unset(&mal_contextLock);
+       return msg;
 }
 
 str
-CLTwakeup(void *ret, int *id)
+CLTwakeup(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
-       (void) ret;     /* fool compiler */
-       return MCawakeClient(*id);
+       str msg = MAL_SUCCEED;
+       int idx = cntxt->idx;
+       
+       if (cntxt->user == MAL_ADMIN)
+               idx = *getArgReference_int(stk,pci,1);
+       (void) mb;
+
+       if( idx < 0 || idx > MAL_MAXCLIENTS)
+               throw(MAL,"clients.wakeup", "Illegal session id");
+
+       MT_lock_set(&mal_contextLock);
+       if (mal_clients[idx].mode == FREECLIENT)
+               msg = createException(MAL,"clients.wakeup","Session not active 
anymore");
+       else
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to