summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEzra Peisach <epeisach@mit.edu>1995-05-30 14:48:59 +0000
committerEzra Peisach <epeisach@mit.edu>1995-05-30 14:48:59 +0000
commit4961f247a203adb5826f4a9bfa067e8d97829dc6 (patch)
treea9a1af926d500fe273be8be3f2c2da499301c991 /src
parent28ec4e65423c14605e0f2d0150b12ba684e8fd6e (diff)
downloadkrb5-4961f247a203adb5826f4a9bfa067e8d97829dc6.tar.gz
krb5-4961f247a203adb5826f4a9bfa067e8d97829dc6.tar.xz
krb5-4961f247a203adb5826f4a9bfa067e8d97829dc6.zip
If the size field of a struct datum != size field of DBT, you need to copy
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
Diffstat (limited to 'src')
-rw-r--r--src/util/berk_db/hash/ChangeLog9
-rw-r--r--src/util/berk_db/hash/configure.in37
-rw-r--r--src/util/berk_db/hash/krb5_ndbm.c58
3 files changed, 104 insertions, 0 deletions
diff --git a/src/util/berk_db/hash/ChangeLog b/src/util/berk_db/hash/ChangeLog
new file mode 100644
index 0000000000..e1bd2c4fe2
--- /dev/null
+++ b/src/util/berk_db/hash/ChangeLog
@@ -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.
+
diff --git a/src/util/berk_db/hash/configure.in b/src/util/berk_db/hash/configure.in
index bac927b856..2d49046afb 100644
--- a/src/util/berk_db/hash/configure.in
+++ b/src/util/berk_db/hash/configure.in
@@ -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)])
diff --git a/src/util/berk_db/hash/krb5_ndbm.c b/src/util/berk_db/hash/krb5_ndbm.c
index 7baa0321ce..92e97fa8fd 100644
--- a/src/util/berk_db/hash/krb5_ndbm.c
+++ b/src/util/berk_db/hash/krb5_ndbm.c
@@ -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