This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch for new nss_db/db-open



Running make check for glibc 2.2 I got a segmentation fault for
nss/test-netdb.c.  The problem was that /etc/nsswitch.conf has:
services:       db files

But the db file /var/db... doesn't exist on my system.  We need to
check if the db_open call is successfull before other functions are
accessed.  A patch is appended (a lot is just reformatting).  The
patch also fixes a memory leak for this case and cleans up the
function.

Andreas

2000-01-04  Andreas Jaeger  <aj@suse.de>

	* nss/nss_db/db-open.c (internal_setent): Check for db_open for
	success, fix a memory leak and clean up function.

============================================================
Index: nss/nss_db/db-open.c
--- nss/nss_db/db-open.c	2000/01/02 08:39:05	1.2
+++ nss/nss_db/db-open.c	2000/01/04 09:39:23
@@ -118,7 +118,10 @@
   enum nss_status status = NSS_STATUS_SUCCESS;
   int err;
   void *db;
+  int fd;
+  int result;
 
+
   if (*dbp == NULL)
     {
       if (libdb_db_open == NULL)
@@ -138,77 +141,71 @@
       err = DL_CALL_FCT (libdb_db_open,
 			 (file, DB_BTREE, DB_RDONLY, 0, NULL, NULL, &db));
 
+      if (err != 0)
+	{
+	  __set_errno (err);
+	  *dbp = NULL;
+	  return err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+	}
+      
       /* Construct the object we pass up.  */
       *dbp = (NSS_DB *) malloc (sizeof (NSS_DB));
-      if (*dbp != NULL)
+      if (*dbp == NULL)
+	return NSS_STATUS_UNAVAIL;
+	  
+      (*dbp)->db = db;
+
+      /* The functions are at different positions for the different
+	 versions.  Sigh.  */
+      switch (libdb_version)
 	{
-	  (*dbp)->db = db;
-
-	  /* The functions are at different positions for the different
-	     versions.  Sigh.  */
-	  switch (libdb_version)
-	    {
-	    case db24:
-	      (*dbp)->close =
-		(int (*) (void *, uint32_t)) ((struct db24 *) db)->close;
-	      (*dbp)->fd =
-		(int (*) (void *, int *)) ((struct db24 *) db)->fd;
-	      (*dbp)->get =
-		(int (*) (void *, void *, void *, void *, uint32_t))
-		((struct db24 *) db)->get;
-	      break;
-	    case db27:
-	      (*dbp)->close =
-		(int (*) (void *, uint32_t)) ((struct db27 *) db)->close;
-	      (*dbp)->fd =
-		(int (*) (void *, int *)) ((struct db27 *) db)->fd;
-	      (*dbp)->get =
-		(int (*) (void *, void *, void *, void *, uint32_t))
-		((struct db27 *) db)->get;
-	      break;
-	    default:
-	      abort ();
-	    }
+	case db24:
+	  (*dbp)->close =
+	    (int (*) (void *, uint32_t)) ((struct db24 *) db)->close;
+	  (*dbp)->fd =
+	    (int (*) (void *, int *)) ((struct db24 *) db)->fd;
+	  (*dbp)->get =
+	    (int (*) (void *, void *, void *, void *, uint32_t))
+	    ((struct db24 *) db)->get;
+	  break;
+	case db27:
+	  (*dbp)->close =
+	    (int (*) (void *, uint32_t)) ((struct db27 *) db)->close;
+	  (*dbp)->fd =
+	    (int (*) (void *, int *)) ((struct db27 *) db)->fd;
+	  (*dbp)->get =
+	    (int (*) (void *, void *, void *, void *, uint32_t))
+	    ((struct db27 *) db)->get;
+	  break;
+	default:
+	  abort ();
 	}
 
+      /* We have to make sure the file is `closed on exec'.  */
+      err = DL_CALL_FCT ((*dbp)->fd, (db, &fd));
       if (err != 0)
 	{
 	  __set_errno (err);
-	  *dbp = NULL;
-	  status = err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+	  result = -1;
 	}
       else
 	{
-	  /* We have to make sure the file is `closed on exec'.  */
-	  int fd;
-	  int result;
+	  int flags = result = fcntl (fd, F_GETFD, 0);
 
-	  err = DL_CALL_FCT ((*dbp)->fd, (db, &fd));
-	  if (err != 0)
-	    {
-	      __set_errno (err);
-	      result = -1;
-	    }
-	  else
-	    {
-	      int flags = result = fcntl (fd, F_GETFD, 0);
-
-	      if (result >= 0)
-		{
-		  flags |= FD_CLOEXEC;
-		  result = fcntl (fd, F_SETFD, flags);
-		}
-	    }
-	  if (result < 0)
+	  if (result >= 0)
 	    {
-	      /* Something went wrong.  Close the stream and return a
-		 failure.  */
-	      DL_CALL_FCT ((*dbp)->close, (db, 0));
-	      status = NSS_STATUS_UNAVAIL;
+	      flags |= FD_CLOEXEC;
+	      result = fcntl (fd, F_SETFD, flags);
 	    }
-
-	  if (result < 0)
-	    *dbp = NULL;
+	}
+      if (result < 0)
+	{
+	  /* Something went wrong.  Close the stream and return a
+	     failure.  */
+	  DL_CALL_FCT ((*dbp)->close, (db, 0));
+	  status = NSS_STATUS_UNAVAIL;
+	  free (*dbp);
+	  *dbp = NULL;
 	}
     }
 

-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.rhein-neckar.de

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]