MOO-cows Mailing List Archive


patch for server-crashing bug in 1.8.0p5

The patch file at the end of this message fixes a memory corruption
bug that allowed any programmer to crash the server reliably (if
accidentally) in a few statements of innocent-looking code.  Under
certain circumstances, the resume() function, when passed a second
argument of E_NONE, would panic the server.

The fix here is simply to disallow E_NONE as a resumption value, in
both bf_resume() and its server-internal counterpart, resume_task().
(bf_resume() will raise E_INVARG if this is attempted; resume_task()
will write a message in the log and initiate a panic shutdown.)
Nothing in the stock server uses resume_task(); extension authors who
use it may want to make sure their code can't pass E_NONE.

I am not very happy with this solution, partly because I'd rather not
special-case E_NONE, but mostly because I don't like the semantics of
resume() when passed an error.  At the moment, if resume()'s second
argument is of type ERR, an exception is _raised_ in the resumed task;
if it is of any other type, the argument is _returned_ by the
task's suspend() call.

It seems to me that it should be possible to pass errors as values
with resume(), just as we can with return.  In a (near-)future version
of the server, I may change this so that any value passed to resume()
is returned as a value by suspend(); it would then require an explicit
action of some sort to raise an exception in a suspended task.

I should have an updated version of the server available via FTP as
soon as I work out some details.  (I plan to identify this version as
LambdaMOO 1.8.0p6, since it will contain only bug fixes.)  But you
should apply this patch rather than wait for the FTP version.

Thanks to Bill Carter for discovering and Eric Mercer for reporting
this bug.


P.S.  The first segment of this patch contains a separate bug fix
provided by Pavel on this mailing list a few months ago.

--------------------------------cut here---------------------------------
*** tasks.c	1996/04/08 01:03:04	2.8
--- tasks.c	1996/11/14 21:21:59
*** 210,215 ****
--- 210,216 ----
      tq->player = player;
+     tq->handler = 0;
      tq->connected = 0;
      tq->first_input = tq->first_bg = 0;
*** 879,884 ****
--- 880,888 ----
      Objid       progr = progr_of_cur_verb(the_vm);
      tqueue     *tq = find_tqueue(progr, 1);
+     if (value.type == TYPE_ERR && value.v.err == E_NONE)
+         panic("RESUME_TASK(): Bad value!");
      t->kind = TASK_SUSPENDED;
      t->t.suspended.the_vm = the_vm;
      t->t.suspended.start_time = 0; /* ready now */
*** 1806,1811 ****
--- 1810,1818 ----
      task      **tt;
      tqueue     *tq;
+     if (value.type == TYPE_ERR && value.v.err == E_NONE)
+         return E_INVARG;
      for (tt = &waiting_tasks; *tt; tt = &((*tt)->next)) {
  	task   *t = *tt;

Home | Subject Index | Thread Index