Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os.closerange() can be no-op in a seccomp sandbox #91416

Closed
izbyshev mannequin opened this issue Apr 8, 2022 · 6 comments
Closed

os.closerange() can be no-op in a seccomp sandbox #91416

izbyshev mannequin opened this issue Apr 8, 2022 · 6 comments
Assignees
Labels
3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@izbyshev
Copy link
Mannequin

izbyshev mannequin commented Apr 8, 2022

BPO 47260
Nosy @gpshead, @izbyshev, @miss-islington, @kevans91, @kevans91
PRs
  • bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox #32418
  • [3.10] bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418) #32420
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/izbyshev'
    closed_at = <Date 2022-04-08.17:43:44.271>
    created_at = <Date 2022-04-08.14:29:30.146>
    labels = ['type-bug', 'library', '3.10', '3.11']
    title = 'os.closerange() can be no-op in a seccomp sandbox'
    updated_at = <Date 2022-04-08.18:10:43.065>
    user = 'https://github.com/izbyshev'

    bugs.python.org fields:

    activity = <Date 2022-04-08.18:10:43.065>
    actor = 'miss-islington'
    assignee = 'izbyshev'
    closed = True
    closed_date = <Date 2022-04-08.17:43:44.271>
    closer = 'gregory.p.smith'
    components = ['Library (Lib)']
    creation = <Date 2022-04-08.14:29:30.146>
    creator = 'izbyshev'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 47260
    keywords = ['patch', '3.10regression']
    message_count = 6.0
    messages = ['416986', '416988', '416991', '416995', '416996', '416998']
    nosy_count = 5.0
    nosy_names = ['gregory.p.smith', 'izbyshev', 'miss-islington', 'kevans', 'kevans91']
    pr_nums = ['32418', '32420']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue47260'
    versions = ['Python 3.10', 'Python 3.11']

    @izbyshev
    Copy link
    Mannequin Author

    izbyshev mannequin commented Apr 8, 2022

    After bpo-40422 _Py_closerange() assumes that close_range() closes all file descriptors even if it returns an error (other than ENOSYS):

        if (close_range(first, last, 0) == 0 || errno != ENOSYS) {
            /* Any errors encountered while closing file descriptors are ignored;
             * ENOSYS means no kernel support, though,
             * so we'll fallback to the other methods. */
        }
        else
        /* fallbacks */

    This assumption can be wrong on Linux if a seccomp sandbox denies the underlying syscall, pretending that it returns EPERM or EACCES. In this case _Py_closerange() won't close any descriptors at all, which in the worst case can be a security issue.

    I propose to fix this by falling back to other methods in case of *any* close_range() error. Note that fallbacks will not be triggered on any problems with closing individual file descriptors because close_range() is documented to ignore such errors on both Linux[1] and FreeBSD[2].

    [1] https://man7.org/linux/man-pages/man2/close_range.2.html
    [2] https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2

    @izbyshev izbyshev mannequin added 3.10 only security fixes 3.11 only security fixes labels Apr 8, 2022
    @izbyshev izbyshev mannequin self-assigned this Apr 8, 2022
    @izbyshev izbyshev mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error 3.10 only security fixes 3.11 only security fixes labels Apr 8, 2022
    @izbyshev izbyshev mannequin self-assigned this Apr 8, 2022
    @izbyshev izbyshev mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Apr 8, 2022
    @kevans91
    Copy link
    Mannequin

    kevans91 mannequin commented Apr 8, 2022

    Sure, sounds good to me. The original theory (IIRC, I've slept many times since then :-)) was that we already know first/last are valid and there are no other defined errors, so 'other errors' must be because close_range has started percolating up something from closing individual files.

    It's been years now and that hasn't happened, even with more recent flag additions. I think it's safe to say it won't, and such a fallback upon error won't put us back into a bogus pre-close_range situation where we're needlessly close()ing a bunch of closed fds.

    @izbyshev
    Copy link
    Mannequin Author

    izbyshev mannequin commented Apr 8, 2022

    It's been years now and that hasn't happened, even with more recent flag additions. I think it's safe to say it won't, and such a fallback upon error won't put us back into a bogus pre-close_range situation where we're needlessly close()ing a bunch of closed fds.

    Yes, I also find it unlikely that close_range() will start reporting an error if it fails to close some fd, especially if not given some new flag. Such error reporting doesn't seem very useful to userspace because there is no way to associate the error with the fd.

    But even if such change happens, it will be just a performance regression, not a potential correctness/security issue.

    @gpshead
    Copy link
    Member

    gpshead commented Apr 8, 2022

    New changeset 1c8b3b5 by Alexey Izbyshev in branch 'main':
    bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418)
    1c8b3b5

    @gpshead
    Copy link
    Member

    gpshead commented Apr 8, 2022

    Good catch.

    @gpshead gpshead closed this as completed Apr 8, 2022
    @gpshead gpshead closed this as completed Apr 8, 2022
    @miss-islington
    Copy link
    Contributor

    New changeset 89697f7 by Miss Islington (bot) in branch '3.10':
    bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418)
    89697f7

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.10 only security fixes 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants