diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-03-28 09:26:07 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-03-28 09:26:07 +0000 |
commit | 7af7b27228a6ad875297e1e22813ea8161cd4bc8 (patch) | |
tree | f3d29efe0a5e8c3d66953b5e8fe17f1c1be4b79f /ext | |
parent | 7357f524beb54ce64c5669afa39e6c68a72cea9b (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.c | 20 | ||||
-rw-r--r-- | ext/sdbm/init.c | 1 |
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)); |