Skip to content

unexpected behavior of tempfile.TemporaryFile() for O_TMPFILE #96531

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

Open
zhangyoufu opened this issue Sep 3, 2022 · 4 comments
Open

unexpected behavior of tempfile.TemporaryFile() for O_TMPFILE #96531

zhangyoufu opened this issue Sep 3, 2022 · 4 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@zhangyoufu
Copy link
Contributor

zhangyoufu commented Sep 3, 2022

Bug report

When O_TMPFILE is available:

  1. tempfile.TemporaryFile(mode='wb') opens with O_RDWR instead of O_WRONLY, the opener callback ignores mode argument and always use _bin_openflags
  2. _bin_openflags has both O_CREAT and O_EXCL set, the opener callback removes O_CREAT from flags but leave O_EXCL, this is an undefined behavior according to Linux open(2) manpage

Your environment

  • CPython versions tested on: 3.10
  • Operating system and architecture: Linux x86_64

Linked PRs

@zhangyoufu zhangyoufu added the type-bug An unexpected behavior, bug, or error label Sep 3, 2022
@iritkatriel iritkatriel added the stdlib Python modules in the Lib dir label Nov 26, 2023
@rruuaanng
Copy link
Contributor

Bug report

When is available:O_TMPFILE

  1. tempfile.TemporaryFile(mode='wb') opens with instead of , the callback ignores argument and always use O_RDWR``O_WRONLY``opener``mode``_bin_openflags
  2. _bin_openflags has both and set, the callback removes from flags but leave , this is an undefined behavior according to Linux manpageO_CREAT``O_EXCL``opener``O_CREAT``O_EXCL``open(2)

Your environment

  • CPython versions tested on: 3.10
  • Operating system and architecture: Linux x86_64

Perhaps you can provide the minimum test sample.

duaneg added a commit to duaneg/cpython that referenced this issue May 1, 2025
If the `O_TMPFILE` is available and works `tempfile.TemporaryFile` will always
open the temporary file as readable, even if the mode is write only.

Fix this by masking off `O_RDWR` and setting `O_WRONLY` if "r" or "+" is not
specified in the mode.
@duaneg
Copy link

duaneg commented May 1, 2025

The first issue means a temporary file opened write-only can be read via the underlying file descriptor, which doesn't seem ideal, and might theoretically be a security concern if the user was passing it somewhere untrusted (e.g. to use as a write-only log channel), although that seems very unlikely.

import os, tempfile
with tempfile.TemporaryFile(mode='ab') as t:
    t.write(b'abc')
    t.seek(0)
    print(os.read(t.fileno(), 3)) # b'abc'

Fixing this will break any code that relies on temporary files always being implicitly readable on systems with O_TMPFILE, of course.

I think the second issue is not actually a bug, although the Linux man pages are arguably ambiguous, so this is open to interpretation. With regards O_EXCL they say:

In general, the behavior of O_EXCL is undefined if it is used without O_CREAT. There is one exception [...which isn't O_TMPFILE...]

However, it also says with regards O_TMPFILE:

Specifying O_EXCL in conjunction with O_TMPFILE prevents a temporary file from being linked into the filesystem in the above manner. (Note that the meaning of O_EXCL in this case is different from the meaning of O_EXCL otherwise.)

IMO the second bit should be read as a specific exception to the general rule in the first bit, and hence the behaviour is not undefined in this case. This matches with usage I could find with a quick code search: O_TMPFILE | O_EXCL without O_CREAT is much more common than O_TMPFILE | O_CREAT (with or without O_EXCL).

@RyanP1978
Copy link

@duaneg
Copy link

duaneg commented May 1, 2025

That doesn't look like the right issue: could you double-check the number, please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

5 participants