If the size field of a struct datum != size field of DBT, you need to copy
authorEzra Peisach <epeisach@mit.edu>
Tue, 30 May 1995 14:48:59 +0000 (14:48 +0000)
committerEzra Peisach <epeisach@mit.edu>
Tue, 30 May 1995 14:48:59 +0000 (14:48 +0000)
the information from one structure to the other without casting as you wind
up with stack garbage. (DEC alpha OSF)

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5913 dc483132-0cff-0310-8789-dd5450dbe970

src/util/berk_db/hash/ChangeLog [new file with mode: 0644]
src/util/berk_db/hash/configure.in
src/util/berk_db/hash/krb5_ndbm.c

diff --git a/src/util/berk_db/hash/ChangeLog b/src/util/berk_db/hash/ChangeLog
new file mode 100644 (file)
index 0000000..e1bd2c4
--- /dev/null
@@ -0,0 +1,9 @@
+Tue May 30 09:53:05 1995  Ezra Peisach  (epeisach@kangaroo.mit.edu)
+
+       * krb5_ndbm.c: If the size field of datum and DBT do not match,
+               then passing structures subject to stack garbage. Copy
+               instaead. 
+
+       * configure.in: Determine the size of the datum and DBT size
+               fields. 
+
index bac927b856d878fe37f324136a45c76d9a95ff5b..2d49046afb7ac3b070cb87b219983584851c0cf5 100644 (file)
@@ -9,6 +9,43 @@ AC_PROG_RANLIB
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
 AC_CHECK_SIZEOF(long)
+
+dnl Determine the size of datum and DBT size fields. If they are not the same
+dnl then the elements need to be copied.
+AC_MSG_CHECKING(size of datum.dsize)
+AC_CACHE_VAL(ac_cv_sizeof_datum_dsize,
+[AC_TRY_RUN([#include <stdio.h>
+#include <ndbm.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  datum k;
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(k.dsize));
+  exit(0);
+}], ac_cv_sizeof_datum_dsize=`cat conftestval`)])dnl
+AC_MSG_RESULT($ac_cv_sizeof_datum_dsize)
+AC_DEFINE_UNQUOTED(SIZEOF_DATUM_DSIZE, $ac_cv_sizeof_datum_dsize)
+
+AC_MSG_CHECKING(size of DBT.size)
+AC_CACHE_VAL(ac_cv_sizeof_dbt_size,
+[AC_TRY_RUN([#include <stdio.h>
+#include <sys/types.h>
+typedef struct {
+       void    *data;                  /* data */
+       size_t   size;                  /* data length */
+} DBT;
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  DBT k;
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(k.size));
+  exit(0);
+}], ac_cv_sizeof_dbt_size=`cat conftestval`)])dnl
+AC_MSG_RESULT($ac_cv_sizeof_dbt_size)
+AC_DEFINE_UNQUOTED(SIZEOF_DBT_SIZE, $ac_cv_sizeof_dbt_size)
+
 AC_HAVE_FUNCS(mktemp mkstemp)
 CHECK_SIGNALS
 SubdirLibraryRule([$(OBJS)])
index 7baa0321cec926aacc1d1cb9c317ea5c03409063..92e97fa8fd46bc9492d287eb8e9cdbf68ee23410 100644 (file)
@@ -79,6 +79,22 @@ static char sccsid[] = "@(#)ndbm.c   8.4 (Berkeley) 7/21/94";
 #include <ndbm.h>
 #include "hash.h"
 
+/* If the two size fields are not equal, then casting between structures will 
+   result in stack garbage being transfered. Has been observed for DEC Alpha
+   OSF, but will handle the general case.
+*/
+
+#ifndef SIZEOF_DBT_SIZE
+#define SIZEOF_DBT_SIZE 4
+#endif
+#ifndef SIZEOF_DATUM_DSIZE
+#define SIZEOF_DATUM_DSIZE 4
+#endif
+
+#if SIZEOF_DBT_SIZE != SIZEOF_DATUM_DSIZE
+#define NEED_COPY
+#endif
+
 /*
  * For Kerberos, we make some generalizations about kdb records.  We assume
  * that records are on average KRB5_DBENT_ASIZE in length.
@@ -137,8 +153,17 @@ db_dbm_fetch(db, key)
 {
        datum retval;
        int status;
+#ifdef NEED_COPY
+       DBT k, r;
 
+       k.data = key.dptr;
+       k.size = key.dsize;
+       status = (db->get)(db, &k, &r, 0);
+       retval.dptr = r.data;
+       retval.dsize = r.size;
+#else
        status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+#endif
        if (status) {
                retval.dptr = NULL;
                retval.dsize = 0;
@@ -157,8 +182,15 @@ db_dbm_firstkey(db)
 {
        int status;
        datum retdata, retkey;
+#ifdef NEED_COPY
+       DBT k, r;
 
+       status = (db->seq)(db, &k, &r, R_FIRST);
+       retkey.dptr = k.data;
+       retkey.dsize = k.size;
+#else
        status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+#endif
        if (status)
                retkey.dptr = NULL;
        return (retkey);
@@ -175,8 +207,15 @@ db_dbm_nextkey(db)
 {
        int status;
        datum retdata, retkey;
+#ifdef NEED_COPY
+       DBT k, r;
 
+       status = (db->seq)(db, &k, &r, R_NEXT);
+       retkey.dptr = k.data;
+       retkey.dsize = k.size;
+#else
        status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+#endif
        if (status)
                retkey.dptr = NULL;
        return (retkey);
@@ -192,8 +231,16 @@ db_dbm_delete(db, key)
        datum key;
 {
        int status;
+#ifdef NEED_COPY
+       DBT k;
+
+       k.data = key.dptr;
+       k.size = key.dsize;
+       status = (db->del)(db, &k, 0);
+#else
 
        status = (db->del)(db, (DBT *)&key, 0);
+#endif
        if (status)
                return (-1);
        else
@@ -212,8 +259,19 @@ db_dbm_store(db, key, content, flags)
        datum key, content;
        int flags;
 {
+#ifdef NEED_COPY
+       DBT k, c;
+
+       k.data = key.dptr;
+       k.size = key.dsize;
+       c.data = content.dptr;
+       c.size = content.dsize;
+       return ((db->put)(db, &k, &c,
+           (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
+#else
        return ((db->put)(db, (DBT *)&key, (DBT *)&content,
            (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
+#endif
 }
 
 extern int