summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-28 09:26:07 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-28 09:26:07 +0000
commit7af7b27228a6ad875297e1e22813ea8161cd4bc8 (patch)
treef3d29efe0a5e8c3d66953b5e8fe17f1c1be4b79f /ext
parent7357f524beb54ce64c5669afa39e6c68a72cea9b (diff)
sdbm: check offset
* ext/sdbm/_sdbm.c (getpair, getnkey): check offset range. https://hackerone.com/reports/271096 * ext/sdbm/init.c (fsdbm_each_pair): raise if fetch failed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@62976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/sdbm/_sdbm.c20
-rw-r--r--ext/sdbm/init.c1
2 files changed, 16 insertions, 5 deletions
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
index 3a42b0e569..e8b7176ddc 100644
--- a/ext/sdbm/_sdbm.c
+++ b/ext/sdbm/_sdbm.c
@@ -721,8 +721,12 @@ getpair(char *pag, datum key)
if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
return nullitem;
- val.dptr = pag + GET_SHORT(ino,i + 1);
- val.dsize = GET_SHORT(ino,i) - GET_SHORT(ino,i + 1);
+ n = GET_SHORT(ino,i + 1);
+ if (n <= 0 || n > PBLKSIZ)
+ return nullitem;
+
+ val.dptr = pag + n;
+ val.dsize = GET_SHORT(ino,i) - n;
return val;
}
@@ -747,10 +751,16 @@ getnkey(char *pag, int num)
if (GET_SHORT(ino,0) == 0 || num > GET_SHORT(ino,0))
return nullitem;
- off = (num > 1) ? GET_SHORT(ino,num - 1) : PBLKSIZ;
+ off = PBLKSIZ;
+ if (num > 1 && ((off = GET_SHORT(ino,num - 1)) < 0 || off > PBLKSIZ))
+ return nullitem;
+
+ num = GET_SHORT(ino,num);
+ if (num < 0 || num > off)
+ return nullitem;
- key.dptr = pag + GET_SHORT(ino,num);
- key.dsize = off - GET_SHORT(ino,num);
+ key.dptr = pag + num;
+ key.dsize = off - num;
return key;
}
diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c
index f28eeb2f5e..4a738debd6 100644
--- a/ext/sdbm/init.c
+++ b/ext/sdbm/init.c
@@ -826,6 +826,7 @@ fsdbm_each_pair(VALUE obj)
GetDBM2(obj, dbmp, dbm);
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
val = sdbm_fetch(dbm, key);
+ if (!val.dptr) rb_raise(rb_eDBMError, "not found");
keystr = rb_external_str_new(key.dptr, key.dsize);
valstr = rb_external_str_new(val.dptr, val.dsize);
rb_yield(rb_assoc_new(keystr, valstr));