[sane-devel] saned crashes by remote frontends

Henning Meier-Geinitz henning@meier-geinitz.de
Wed, 29 Jan 2003 19:20:59 +0100


Hi everyone,

There was a grave bug in saned that allows remote frontends to crash
saned under certain conditions:

- the remote computer is allowed to use saned
- there is no sane device detected
- the frontend calls for an empty backend name (e.g.
  scanimage --help -d net:somehost)
  
The bug (two missing breaks) is fixed in CVS and in the inofficial
snapshot on http://www.meier-geinitz.de/sane/snapshots/ . The fix will
be in version 1.0.10. I'll also attach a patch.

When all conditions above apply, saned hits a null pointer dereference
and crashes. I don't think it can be exploited to run code but maybe
an expert can comment on this.

I don't think that the risk of DoS is high either because saned will
be restarted by inetd for new sessions and there is no scanner anyway.

Just as a reminder: Don't use saned as root and make sure that only
computers from the intranet can access it.

Thanks to Lee Howard <faxguy@howardsilvan.com>, who was the only one
to findd this bug which is older than two years.

Bye,
  Henning

Index: frontend/saned.c
===================================================================
RCS file: /cvsroot/external/sane/sane-backends/frontend/saned.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -u -r1.18 -r1.19
--- frontend/saned.c	4 Jan 2003 15:24:13 -0000	1.18
+++ frontend/saned.c	29 Jan 2003 17:41:53 -0000	1.19
@@ -862,22 +862,27 @@
 	if (strlen(resource) == 0) {
 
 	  const SANE_Device **device_list;
-	  
+
+	  DBG(DBG_DBG, "process_request: (open) strlen(resource) == 0\n");
 	  free (resource);
 
 	  if ((i = sane_get_devices (&device_list, SANE_TRUE)) != 
 	      SANE_STATUS_GOOD) 
 	    {
+	      DBG(DBG_ERR, "process_request: (open) sane_get_devices failed\n");
 	      memset (&reply, 0, sizeof (reply));
 	      reply.status = i;
 	      sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
+	      break;
 	    }
 
 	  if ((device_list == NULL) || (device_list[0] == NULL)) 
 	    {
+	      DBG(DBG_ERR, "process_request: (open) device_list[0] == 0\n");
 	      memset (&reply, 0, sizeof (reply));
 	      reply.status = SANE_STATUS_INVAL;
 	      sanei_w_reply (w, (WireCodecFunc) sanei_w_open_reply, &reply);
+	      break;
 	    }
 
 	  resource = strdup (device_list[0]->name);