Skip to content

"open" audit event "mode" does not contain information for os.open calls #158916

Description

@johnkw

Bug report

This was originally reported in bug #116429 although it was not specifically pointed out there.

The "open" audit event "mode" does not contain information for os.open calls. It is always None. (This is unfortunate because I was hoping to run an audit report on all files being opened either for reading or for writing separately, and due to this limitation you can't do that.)

The https://docs.python.org/3/library/audit_events.html documentation states the mode field is there for os.open. Without some documentation note to the contrary, one would expect the field to exist and contain valid information.

CPython versions tested on:

3.16

Operating systems tested on:

No response

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Oct 6, 2026
  2. picnixz commented on Oct 6, 2026

    @picnixz
    Member

    Docs for os.open say:

    Raises an auditing event open with arguments path, mode, flags.

    If we are not forwarding the mode appropriately this indeed seems wrong. Can you check why? or are you interested in making a PR?

  3. johnkw commented on Oct 6, 2026

    @johnkw
    Author

    In my brief attempt to use the open audit event, in order to be useful it needs to return auditing data consistently across open() and os.open().

    If this bug report is treated as a code bug and not a documentation bug, then it seems like you'd want os.open() to report a mode which is abstracted based on the translation of the os.O_RDONLY, os.O_WRONLY... etc flags into a mode string like r, w, ....

    However just looking at that list I immediately notice that "b" and "t" have no meaning in os.open(). I just tested an open("bla","wb") call however, and it actually only triggers an audit event of:
    open ('bla', 'w', 524865)
    So it should probably be noted somewhere that "b" and "t" are stripped from the audit event (which is actually fine by me since they don't have a lot of use in terms of auditing what the program is actually doing).

    Another point of confusion here is the https://docs.python.org/3/builtins/functions.html#open documentation says:

    Raises an auditing event open with arguments path, mode, flags.

    But there are no flags at all in the open() call at all. What the audit even is currently using is the flags from the underlying os.open() that eventually gets called down below somewhere.

    I've never done any work on python internals, but this last part strikes me as especially strange here because if the audit event is using os.open() information already, it's odd that it wouldn't just get the mode correct there.

  4. picnixz commented on Oct 6, 2026

    @picnixz
    Member

    I am on mobile so I cannot check, but the audit event name has been shared by multiple functions so this can be easily missed

    Now, we use mode whether for the mode 'r' or the mode passed to os.open() (AFAIU the docs) It is not about flags being translated into a mode. os.open() accepts a mode param as well and a flags. So if we pass one, we should see it in the event. The meaning of mode for open/io.open() will however be different I think.

    What matters is to know if the one raising the audit event is open itself or the underlying call to io.open() for instance (and where in the stack).

    I think we can have inconsistent translations or we are raising the audit before we derive the appropriate flags.

    cc @vstinner

  5. johnkw commented on Oct 6, 2026

    @johnkw
    Author

    Well, ok it's technically true that os.open() and open() both have a function parameter called mode but the meanings are unrelated. The former specifies the ACL bits for the file system and is only applicable for file creation (and does nothing to the file handle), while the latter determines reading/writing/etc for the file handle.

    It would be helpful for the docs to also be more clear regarding which of those two completely different modes are being intended. It seemingly is always intended to reference only the open() mode.

    The os.open() use of mode could conceivably have some usefulness in auditing I suppose, but currently it seems to be entirely absent from the audit system. That would seem to warrant a separate issue tracker if someone wants that feature though.

  6. vstinner commented on Oct 6, 2026

    @vstinner
    Member

    Hum. I wrote a script:

    import sys
    import os
    def hook(event, args):
        if 'open' in event:
            print("EVENT", event, args)
    sys.addaudithook(hook)
    print(f"os.O_CLOEXEC = {os.O_CLOEXEC}")
    open(__file__).close()
    fd = os.open(__file__, os.O_RDONLY); os.close(fd)

    Output:

    os.O_CLOEXEC = 524288
    EVENT open ('/home/vstinner/python/main/x.py', 'r', 524288)
    EVENT open ('/home/vstinner/python/main/x.py', None, 524288)
    

    open() logs 'r' mode, whereas os.open() doesn't log the mode (left as None).

    os.open() documentation says:

    Raises an auditing event open with arguments path, mode, flags.

    I don't know how this audit event was designed. @zooba might know better about this.

  7. zooba commented on Oct 6, 2026

    @zooba
    Member

    One of the principles was to pass through arguments directly (after type checks), so without going through history at all, I would guess that's why it's different. Calculating the equivalent string for os.open would take non-zero time, and passing a non-string technically isn't wrong but would be a surprising change.

    If there's a very quick way to pass a suitable static string (e.g. if it is either r or w based on a single test) then I see no harm in adding that.

    But it wouldn't surprise me if the information is passed through in flags. OS_RDONLY should be zero, so you won't see it, but other flags should be in the event, I thought.

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

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions