Skip to content

segfault in mmap object when using __index__ method that closes the mmap #103987

Description

@cfbolz

The following (artificial) code segfaults CPython (I tried a bunch of versions, including git main) on my x86 Ubuntu Linux 22.10:

import mmap

with open("abcds", "w+") as f:
    f.write("foobar")
    f.flush()

    class X(object):
        def __index__(self):
            m.close()
            return 1

    m = mmap.mmap(f.fileno(), 6, access=mmap.ACCESS_READ)

    print(m[1])
    print(m[X()])

The problem is this code in mmapmodule.c

static PyObject *
mmap_subscript(mmap_object *self, PyObject *item)
{
    CHECK_VALID(NULL);
    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            return NULL;
        if (i < 0)
            i += self->size;
        if (i < 0 || i >= self->size) {
            PyErr_SetString(PyExc_IndexError,
                "mmap index out of range");
            return NULL;
        }
        return PyLong_FromLong(Py_CHARMASK(self->data[i]));
...

the CHECK_VALID(NULL) call which checks whether the mmap object is closed happens before the PyNumber_AsSsize_t call which closes the object (and similarly for the slice handling which happens further down).

Linked PRs

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Apr 29, 2023
  2. sobolevn commented on Apr 29, 2023

    @sobolevn
    Member

    Yes, adding CHECK_VALID(NULL); right after Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); seems like a reasonale check.

    @cfbolz would you like to send a PR? :)

  3. cfbolz commented on Apr 29, 2023

    @cfbolz
    ContributorAuthor

    heh, in principle yes, but I am currently busy doing an equivalent fix in pypy ;-)

  4. Agent-Hellboy commented on Apr 29, 2023

    @Agent-Hellboy
    Contributor

    Hi @sobolevn I can create a PR, I guess it's a one-line change , I don't know whether we need to modify some test or not

  5. sobolevn commented on Apr 29, 2023

    @sobolevn
    Member

    @Agent-Hellboy yes, adding regression tests for crashes is a must :)

  6. Agent-Hellboy commented on Apr 29, 2023

    @Agent-Hellboy
    Contributor

    okay, Thanks, let me explore
    I guess this is the expected output

    Traceback (most recent call last):
      File "/home/proshan/play_python/my_cpython/cpython/b.py", line 15, in <module>
        print(m[X()])
              ~^^^^^
    ValueError: mmap closed or invalid
    
  7. sobolevn commented on Apr 29, 2023

    @sobolevn
    Member

    Yes, looks correct to me

  8. cfbolz commented on Apr 29, 2023

    @cfbolz
    ContributorAuthor

    that's what I went with too. there's an interesting corner case with this kind of code:

    ...
    m = mmap.mmap(...)
    m.close()
    m["abc"]

    should this give a TypeError because of the invalid index type? or an error that the mmap is closed (as it does now)? if the latter, you would have to check twice whether the mmap is closed.

  9. sobolevn commented on Apr 29, 2023

    @sobolevn
    Member

    or an error that the mmap is closed (as it does now)?

    I think that's the case, because other exceptions might break users' code (unlikely, but possible).

  10. added a commit that references this issue on Apr 29, 2023
  11. added
    3.11only security fixes
    3.12only security fixes
    3.13only security fixes
    on May 12, 2023
  12. added a commit that references this issue on May 12, 2023
  13. added a commit that references this issue on May 20, 2023
  14. added a commit that references this issue on May 20, 2023
  15. added a commit that references this issue on May 20, 2023
  16. added a commit that references this issue on May 20, 2023
  17. sobolevn commented on Jun 8, 2023

    @sobolevn
    Member

    Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixes3.12only security fixes3.13only security fixesextension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions