openwall / openwall/john

Integer overflows in *alloc() calls on 32-bit

Open
#4,865 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug maintenance/cleanup portability
Dominant language
C
Stars
13.6k
Forks
2.6k
PR merge metrics
No merged PRs in 30d

Description

malloc accepts a size_t argument, our own wrappers like mem_alloc and others in memory.[ch] do as well. On 32-bit platforms, size_t is typically 32-bit as well. However, we have calls that pass 64-bit values in there, which in some cases may actually exceed what fits in 32 bits. When this happens, we attempt allocating an incorrect (too small) amount of memory, which might succeed, followed by a write of potentially the larger amount of data (although this is also subject to potential truncation to size_t, in other calls).

For example, in zip2john.c we have:

                p->hash_data = mem_alloc(p->cmp_len + 1);
                if (fread(p->hash_data, 1, p->cmp_len, fp) != p->cmp_len) {

where:

        uint64_t      cmp_len, decomp_len;

since fread also accepts a size_t, for most values we don't actually have an out of bounds write into the memory here, and the under-read is detected through the != p->cmp_len check. However, for cmp_len of 0xffffffff, we do have the problem. (BTW, why do we even allocate the extra 1 byte here.)

We could want to introduce some way to reliably fail allocations of larger than 32-bit sizes when size_t is 32-bit.

Then, in fgetll() we have:

                new_cp = realloc(cp, len + increase);

I guess this can overflow a 32-bit size_t, too, and we need to pre-check for that.

There are probably more problematic cases like this.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the allocation wrappers in memory.[ch], then inspect the examples in zip2john.c and fgetll() for 64-bit values passed to size_t-sized allocation calls. Inventory the other problematic *alloc() cases and define completion as reliably detecting or preventing overflow and truncation on 32-bit platforms, with coverage for the identified cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.