Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6a6f2d9

Browse files
committed
When using C-string lookup keys in a dynahash.c hash table, use strncpy()
not memcpy() to copy the offered key into the hash table during HASH_ENTER. This avoids possible core dump if the passed key is located very near the end of memory. Per report from Stefan Kaltenbrunner.
1 parent a8d1075 commit 6a6f2d9

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

src/backend/utils/hash/dynahash.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.61 2005/05/29 04:23:06 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.62 2005/06/18 20:51:30 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -167,6 +167,16 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
167167
else
168168
hashp->match = memcmp;
169169

170+
/*
171+
* Similarly, the key-copying function defaults to strncpy() or memcpy().
172+
*/
173+
if (flags & HASH_KEYCOPY)
174+
hashp->keycopy = info->keycopy;
175+
else if (hashp->hash == string_hash)
176+
hashp->keycopy = (HashCopyFunc) strncpy;
177+
else
178+
hashp->keycopy = memcpy;
179+
170180
if (flags & HASH_ALLOC)
171181
hashp->alloc = info->alloc;
172182
else
@@ -650,7 +660,7 @@ hash_search(HTAB *hashp,
650660

651661
/* copy key into record */
652662
currBucket->hashvalue = hashvalue;
653-
memcpy(ELEMENTKEY(currBucket), keyPtr, hctl->keysize);
663+
hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize);
654664

655665
/* caller is expected to fill the data field on return */
656666

src/include/utils/hsearch.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.37 2005/06/08 23:02:05 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.38 2005/06/18 20:51:30 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -16,14 +16,25 @@
1616

1717

1818
/*
19-
* Hash and comparison functions must have these signatures. Comparison
20-
* functions return zero for match, nonzero for no match. (The comparison
21-
* function definition is designed to allow memcmp() and strncmp() to be
22-
* used directly as key comparison functions.)
19+
* Hash functions must have this signature.
2320
*/
2421
typedef uint32 (*HashValueFunc) (const void *key, Size keysize);
22+
23+
/*
24+
* Key comparison functions must have this signature. Comparison functions
25+
* return zero for match, nonzero for no match. (The comparison function
26+
* definition is designed to allow memcmp() and strncmp() to be used directly
27+
* as key comparison functions.)
28+
*/
2529
typedef int (*HashCompareFunc) (const void *key1, const void *key2,
26-
Size keysize);
30+
Size keysize);
31+
32+
/*
33+
* Key copying functions must have this signature. The return value is not
34+
* used. (The definition is set up to allow memcpy() and strncpy() to be
35+
* used directly.)
36+
*/
37+
typedef void *(*HashCopyFunc) (void *dest, const void *src, Size keysize);
2738

2839
/*
2940
* Space allocation function for a hashtable --- designed to match malloc().
@@ -103,6 +114,7 @@ typedef struct HTAB
103114
HASHSEGMENT *dir; /* directory of segment starts */
104115
HashValueFunc hash; /* hash function */
105116
HashCompareFunc match; /* key comparison function */
117+
HashCopyFunc keycopy; /* key copying function */
106118
HashAllocFunc alloc; /* memory allocator */
107119
MemoryContext hcxt; /* memory context if default allocator
108120
* used */
@@ -123,6 +135,7 @@ typedef struct HASHCTL
123135
Size entrysize; /* total user element size in bytes */
124136
HashValueFunc hash; /* hash function */
125137
HashCompareFunc match; /* key comparison function */
138+
HashCopyFunc keycopy; /* key copying function */
126139
HashAllocFunc alloc; /* memory allocator */
127140
HASHSEGMENT *dir; /* directory of segment starts */
128141
HASHHDR *hctl; /* location of header in shared mem */
@@ -140,6 +153,7 @@ typedef struct HASHCTL
140153
#define HASH_ALLOC 0x100 /* Set memory allocator */
141154
#define HASH_CONTEXT 0x200 /* Set explicit memory context */
142155
#define HASH_COMPARE 0x400 /* Set user defined comparison function */
156+
#define HASH_KEYCOPY 0x800 /* Set user defined key-copying function */
143157

144158

145159
/* max_dsize value to indicate expansible directory */

0 commit comments

Comments
 (0)