summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReini Urban <rurban@x-ray.at>2012-03-09 09:11:50 -0600
committerCraig A. Berry <craigberry@mac.com>2012-03-09 09:11:50 -0600
commitacdbe25bd91bf897e0cf373b91ab0814e21c4860 (patch)
tree3495e0a4a1c4d2d7bfcb19cc1575c5abec796009
parenta752ff79ee1321f459c659136b0f0e7e43e1f5ae (diff)
downloadperl-acdbe25bd91bf897e0cf373b91ab0814e21c4860.tar.gz
sdbm.c: fix off-by-one access to global ".dir"
Detected by clang -faddress-sanitizer. The bug came in 081f72ad6fa2b76e0b3cd9046371b2dbd9130114, where we started calculating lengths with sizeof on string constants instead of using strlen. Since string constants include the null byte, sizeof(".dir"), for example, is 5, but we've been copying 6 bytes. This patch resolves [perl #111586] and includes revisions by the committer.
-rw-r--r--ext/SDBM_File/sdbm/sdbm.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/ext/SDBM_File/sdbm/sdbm.c b/ext/SDBM_File/sdbm/sdbm.c
index c554e527ea..46be83e560 100644
--- a/ext/SDBM_File/sdbm/sdbm.c
+++ b/ext/SDBM_File/sdbm/sdbm.c
@@ -78,8 +78,8 @@ sdbm_open(register char *file, register int flags, register int mode)
register char *dirname;
register char *pagname;
size_t filelen;
- const size_t dirfext_len = sizeof(DIRFEXT "");
- const size_t pagfext_len = sizeof(PAGFEXT "");
+ const size_t dirfext_size = sizeof(DIRFEXT "");
+ const size_t pagfext_size = sizeof(PAGFEXT "");
if (file == NULL || !*file)
return errno = EINVAL, (DBM *) NULL;
@@ -88,17 +88,17 @@ sdbm_open(register char *file, register int flags, register int mode)
*/
filelen = strlen(file);
- if ((dirname = (char *) malloc(filelen + dirfext_len + 1
- + filelen + pagfext_len + 1)) == NULL)
+ if ((dirname = (char *) malloc(filelen + dirfext_size
+ + filelen + pagfext_size)) == NULL)
return errno = ENOMEM, (DBM *) NULL;
/*
* build the file names
*/
memcpy(dirname, file, filelen);
- memcpy(dirname + filelen, DIRFEXT, dirfext_len + 1);
- pagname = dirname + filelen + dirfext_len + 1;
+ memcpy(dirname + filelen, DIRFEXT, dirfext_size);
+ pagname = dirname + filelen + dirfext_size;
memcpy(pagname, file, filelen);
- memcpy(pagname + filelen, PAGFEXT, pagfext_len + 1);
+ memcpy(pagname + filelen, PAGFEXT, pagfext_size);
db = sdbm_prep(dirname, pagname, flags, mode);
free((char *) dirname);