- Amazingly, I think I implemented ni-synch partial order reduction. It
still needs some careful analysis though.
This commit is contained in:
parent
60b02eea0e
commit
4f1c9ecb48
@ -416,6 +416,7 @@ commEvent (int event, Tac tc)
|
|||||||
}
|
}
|
||||||
// Assert: label is unique, add claimlist info
|
// Assert: label is unique, add claimlist info
|
||||||
cl = memAlloc (sizeof (struct claimlist));
|
cl = memAlloc (sizeof (struct claimlist));
|
||||||
|
cl->type = claim;
|
||||||
cl->label = label;
|
cl->label = label;
|
||||||
cl->rolename = fromrole;
|
cl->rolename = fromrole;
|
||||||
cl->count = 0;
|
cl->count = 0;
|
||||||
@ -1041,6 +1042,21 @@ compute_prec_sets (const System sys)
|
|||||||
}
|
}
|
||||||
r2++;
|
r2++;
|
||||||
}
|
}
|
||||||
|
// For ni-synch, the preceding label sets are added to the synchronising_labels sets.
|
||||||
|
if (cl->type == CLAIM_Nisynch)
|
||||||
|
{
|
||||||
|
Termlist tl_scan;
|
||||||
|
|
||||||
|
tl_scan = cl->prec;
|
||||||
|
while (tl_scan != NULL)
|
||||||
|
{
|
||||||
|
if (!inTermlist (sys->synchronising_labels, tl_scan->term))
|
||||||
|
{
|
||||||
|
sys->synchronising_labels = termlistAdd (sys->synchronising_labels, tl_scan->term);
|
||||||
|
}
|
||||||
|
tl_scan = tl_scan->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check for empty stuff
|
// Check for empty stuff
|
||||||
//@todo This is for debugging, mainly.
|
//@todo This is for debugging, mainly.
|
||||||
if (cl->prec == NULL)
|
if (cl->prec == NULL)
|
||||||
@ -1064,6 +1080,13 @@ compute_prec_sets (const System sys)
|
|||||||
*/
|
*/
|
||||||
memFree (eventlabels, size * sizeof(Term));
|
memFree (eventlabels, size * sizeof(Term));
|
||||||
memFree (prec, size * size * sizeof(int));
|
memFree (prec, size * size * sizeof(int));
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf ("Synchronising labels set: ");
|
||||||
|
termlistPrint (sys->synchronising_labels);
|
||||||
|
printf ("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Preprocess after system compilation
|
//! Preprocess after system compilation
|
||||||
|
@ -231,6 +231,45 @@ Roledef removeIrrelevant (const System sys, const int run, Roledef rd)
|
|||||||
return rdkill;
|
return rdkill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Unblock any waiting sends of my type.
|
||||||
|
/**
|
||||||
|
* Note that the caller must ensure that rd->forbidden is restored afterwards.
|
||||||
|
*\sa tryChoiceSend()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
unblock_synchronising_labels (const System sys, const int run, const Roledef rd)
|
||||||
|
{
|
||||||
|
if (rd->type != READ || rd->internal)
|
||||||
|
return;
|
||||||
|
if (!inTermlist (sys->synchronising_labels, rd->label))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// This read possibly unblocks other sends
|
||||||
|
int run_scan;
|
||||||
|
|
||||||
|
for (run_scan = 0; run_scan < sys->maxruns; run_scan++)
|
||||||
|
{
|
||||||
|
if (run_scan != run)
|
||||||
|
{
|
||||||
|
Roledef rd_scan;
|
||||||
|
|
||||||
|
rd_scan = sys->runs[run_scan].index;
|
||||||
|
if (rd_scan != NULL &&
|
||||||
|
rd_scan->type == SEND &&
|
||||||
|
rd_scan->forbidden != NULL &&
|
||||||
|
isTermEqual (rd_scan->label, rd->label) &&
|
||||||
|
isTermEqual (rd_scan->message, rd->message) &&
|
||||||
|
isTermEqual (rd_scan->from, rd->from) &&
|
||||||
|
isTermEqual (rd_scan->to, rd->to))
|
||||||
|
{
|
||||||
|
rd_scan->forbidden = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//! Explores the system state given by the next step of a run.
|
//! Explores the system state given by the next step of a run.
|
||||||
/** Grandiose naming scheme (c) sjors dubya.
|
/** Grandiose naming scheme (c) sjors dubya.
|
||||||
*
|
*
|
||||||
@ -251,6 +290,7 @@ explorify (const System sys, const int run)
|
|||||||
int flag;
|
int flag;
|
||||||
int myStep;
|
int myStep;
|
||||||
Roledef roleCap, roleCapPart;
|
Roledef roleCap, roleCapPart;
|
||||||
|
Knowledge forbiddenBuffer;
|
||||||
|
|
||||||
rd = runPointerGet (sys, run);
|
rd = runPointerGet (sys, run);
|
||||||
myStep = sys->runs[run].step;
|
myStep = sys->runs[run].step;
|
||||||
@ -263,6 +303,15 @@ explorify (const System sys, const int run)
|
|||||||
|
|
||||||
flag = 0;
|
flag = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* --------------------------------------------
|
||||||
|
* Is the event really enabled?
|
||||||
|
* Typically, a read event is only instantiated
|
||||||
|
* at this point, so we can only now do some
|
||||||
|
* instantiation related determinings.
|
||||||
|
* --------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special checks after (implicit) choose events; always first in run reads.
|
* Special checks after (implicit) choose events; always first in run reads.
|
||||||
*/
|
*/
|
||||||
@ -459,13 +508,27 @@ explorify (const System sys, const int run)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apparently, all is well, and we can explore further */
|
/**
|
||||||
flag = 0;
|
* --------------------------------------------
|
||||||
|
* Now we assume the event is indeed enabled !
|
||||||
|
* --------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* (Possibly) do some local damage */
|
||||||
|
// Unblock any sends
|
||||||
|
forbiddenBuffer = rd->forbidden;
|
||||||
|
if (sys->synchronising_labels != NULL)
|
||||||
|
{
|
||||||
|
unblock_synchronising_labels (sys, run, rd);
|
||||||
|
}
|
||||||
|
// Cap roles
|
||||||
if (roleCap != NULL)
|
if (roleCap != NULL)
|
||||||
{
|
{
|
||||||
roleCapPart = roleCap->next;
|
roleCapPart = roleCap->next;
|
||||||
roleCap->next = NULL;
|
roleCap->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* And explore the resulting system */
|
||||||
if (executeStep (sys, run))
|
if (executeStep (sys, run))
|
||||||
{
|
{
|
||||||
/* traverse the system after the step */
|
/* traverse the system after the step */
|
||||||
@ -477,6 +540,8 @@ explorify (const System sys, const int run)
|
|||||||
sys->step--;
|
sys->step--;
|
||||||
indentSet (sys->step);
|
indentSet (sys->step);
|
||||||
|
|
||||||
|
/* restore local damage */
|
||||||
|
rd->forbidden = forbiddenBuffer;
|
||||||
if (roleCap != NULL)
|
if (roleCap != NULL)
|
||||||
{
|
{
|
||||||
roleCap->next = roleCapPart;
|
roleCap->next = roleCapPart;
|
||||||
@ -484,11 +549,13 @@ explorify (const System sys, const int run)
|
|||||||
return 1; // The event was indeed enabled (irrespective of traverse!)
|
return 1; // The event was indeed enabled (irrespective of traverse!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! Simple nondeterministic traversal.
|
||||||
|
|
||||||
__inline__ int
|
__inline__ int
|
||||||
traverseSimple (const System sys)
|
traverseSimple (const System sys)
|
||||||
{
|
{
|
||||||
/* simple nondeterministic traversal */
|
|
||||||
|
|
||||||
int run;
|
int run;
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
|
|
||||||
@ -563,6 +630,43 @@ traverseNonReads (const System sys)
|
|||||||
return traverseSimple (sys);
|
return traverseSimple (sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Execute a send
|
||||||
|
/**
|
||||||
|
*\sa unblock_synchronising_labels()
|
||||||
|
*/
|
||||||
|
|
||||||
|
__inline__ int
|
||||||
|
tryChoiceSend (const System sys, const int run, const Roledef rd)
|
||||||
|
{
|
||||||
|
int flag;
|
||||||
|
|
||||||
|
flag = 0;
|
||||||
|
if (rd->forbidden == NULL)
|
||||||
|
{
|
||||||
|
/* this is allowed. So we either try it, or we try it later (if blocking) */
|
||||||
|
/* Note that a send in executetry will always succeed. */
|
||||||
|
/* 1. Simply try */
|
||||||
|
flag = executeTry (sys, run);
|
||||||
|
/* 2. Postpone if synchonisable */
|
||||||
|
if (inTermlist (sys->synchronising_labels, rd->label))
|
||||||
|
{
|
||||||
|
/* This is supposed to be blocked, so we do so */
|
||||||
|
/* It will possibly be unblocked by a corresponding read event,
|
||||||
|
* the actual code would be in explorify, post instantiation of the read event.
|
||||||
|
*/
|
||||||
|
if (sys->clp)
|
||||||
|
{
|
||||||
|
block_clp (sys, run);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block_basic (sys, run);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
//! Execute a read in the knowledge postponing way, on which the partial order reduction for secrecy depends.
|
//! Execute a read in the knowledge postponing way, on which the partial order reduction for secrecy depends.
|
||||||
|
|
||||||
__inline__ int
|
__inline__ int
|
||||||
@ -623,10 +727,13 @@ tryChoiceRoledef (const System sys, const int run, const Roledef rd)
|
|||||||
switch (rd->type)
|
switch (rd->type)
|
||||||
{
|
{
|
||||||
case CLAIM:
|
case CLAIM:
|
||||||
case SEND:
|
|
||||||
flag = executeTry (sys, run);
|
flag = executeTry (sys, run);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SEND:
|
||||||
|
flag = tryChoiceSend (sys, run, rd);
|
||||||
|
break;
|
||||||
|
|
||||||
case READ:
|
case READ:
|
||||||
flag = tryChoiceRead (sys, run, rd);
|
flag = tryChoiceRead (sys, run, rd);
|
||||||
break;
|
break;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
//! The container for the claim info list
|
//! The container for the claim info list
|
||||||
struct claimlist
|
struct claimlist
|
||||||
{
|
{
|
||||||
|
//! The type of claim
|
||||||
|
Term type;
|
||||||
//! The term element for this node.
|
//! The term element for this node.
|
||||||
Term label;
|
Term label;
|
||||||
//! The name of the role in which it occurs.
|
//! The name of the role in which it occurs.
|
||||||
@ -66,6 +68,9 @@ struct roledef
|
|||||||
* Substructure for reads
|
* Substructure for reads
|
||||||
*/
|
*/
|
||||||
//! Illegal injections for this event.
|
//! Illegal injections for this event.
|
||||||
|
/**
|
||||||
|
* For send this means that the send is allowed if it is NULL, otherwise it is blocked.
|
||||||
|
*/
|
||||||
Knowledge forbidden;
|
Knowledge forbidden;
|
||||||
//! knowledge transitions counter.
|
//! knowledge transitions counter.
|
||||||
int knowPhase;
|
int knowPhase;
|
||||||
|
@ -80,6 +80,7 @@ systemInit ()
|
|||||||
sys->variables = NULL;
|
sys->variables = NULL;
|
||||||
sys->untrusted = NULL;
|
sys->untrusted = NULL;
|
||||||
sys->secrets = NULL; // list of claimed secrets
|
sys->secrets = NULL; // list of claimed secrets
|
||||||
|
sys->synchronising_labels = NULL;
|
||||||
sys->attack = NULL;
|
sys->attack = NULL;
|
||||||
/* no protocols => no protocol preprocessed */
|
/* no protocols => no protocol preprocessed */
|
||||||
sys->rolecount = 0;
|
sys->rolecount = 0;
|
||||||
|
@ -105,6 +105,7 @@ struct system
|
|||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
Termlist secrets; //!< Integrate secrets list into system.
|
Termlist secrets; //!< Integrate secrets list into system.
|
||||||
|
Termlist synchronising_labels; //!< List of labels that might synchronise.
|
||||||
int shortestattack; //!< Length of shortest attack trace.
|
int shortestattack; //!< Length of shortest attack trace.
|
||||||
|
|
||||||
/* switches */
|
/* switches */
|
||||||
|
Loading…
Reference in New Issue
Block a user