8000 Windows: os.stat() returns random times on ERROR_ACCESS_DENIED · Issue #114273 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

Windows: os.stat() returns random times on ERROR_ACCESS_DENIED #114273

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

Closed
danny0838 opened this issue Jan 18, 2024 · 6 comments
Closed

Windows: os.stat() returns random times on ERROR_ACCESS_DENIED #114273

danny0838 opened this issue Jan 18, 2024 · 6 comments
Labels
OS-windows type-bug An unexpected behavior, bug, or error

Comments

@danny0838
Copy link
danny0838 commented Jan 18, 2024

Bug report

Bug description:

When retrieving the timestamp of an inaccessible file (or directory) in Windows, such as:

os.path.getmtime('C:\\System Volume Information')

, a negative value such as -11644246396.230042 is returned in Python 3.12.

In Python < 3.12, a normal timestamp such as 1705600376.5800736 is returned instead.

This may break many scripts as most of them don't expect a negative value.

CPython versions tested on:

3.12

Operating systems tested on:

Windows

@danny0838 danny0838 added the type-bug An unexpected behavior, bug, or error label Jan 18, 2024
@serhiy-storchaka
Copy link
Member
serhiy-storchaka commented Jan 19, 2024
>>> time.gmtime(1705600376.5800736)
time.struct_time(tm_year=2024, tm_mon=1, tm_mday=18, tm_hour=17, tm_min=52, tm_sec=56, tm_wday=3, tm_yday=18, tm_isdst=0)

It is approximately the time of the report. Perhaps the time of the request.

>>> time.gmtime(-11644246396.230042)
time.struct_time(tm_year=1601, tm_mon=1, tm_mday=3, tm_hour=15, tm_min=6, tm_sec=43, tm_wday=2, tm_yday=3, tm_isdst=0)

It is suspiciously close to the start of Win32 epoch https://devblogs.microsoft.com/oldnewthing/20090306-00/?p=18913.

@vstinner, were there some changes in time conversion that can be related to this? Or maybe Python 3.11 and 3.12 executables have different capabilities, so Win32 API returns different result? cc @zooba

danny0838 added a commit to danny0838/PyWebScrapBook that referenced this issue Jan 19, 2024
- A negative timestamp may be returned by os.stat() for an inaccessible file in Python 3.12:
  python/cpython#114273
- Add datetime to template global.
@vstinner
Copy link
Member

On Windows, os.stat() calls win32_xstat_slow_impl() which calls:

    DWORD access = FILE_READ_ATTRIBUTES;
    DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; /* Allow opening directories. */
    if (!traverse) {
        flags |= FILE_FLAG_OPEN_REPARSE_POINT; 
    }                   
                        
    hFile = CreateFileW(path, access, 0, NULL, OPEN_EXISTING, flags, NULL);

CreateFileW() returns INVALID_HANDLE_VALUE when trying to open C:\System Volume Information path. In this case, basicInfo is left unmodified, whereas the structure is allocated on the stack.

In short, os.stat() returns random values to timestamps (such as st_mtime) on C:\System Volume Information: when CreateFileW() returns INVALID_HANDLE_VALUE. The value depends on the state of the stack memory, in short it's "undefined" or "random".

In fact, CreateFileW() fails with ERROR_ACCESS_DENIED (error code 5). In this case, attributes_from_dir() is called and it works. Problem: basicInfo is not filled by this function (and is left unchanged).

cc @zooba @eryksun

@vstinner
Copy link
Member

Note: os.path.getmtime('C:\\System Volume Information') returns the expected modified time if the code is run as an administrator. The problem only occurs on "access denied". For example, if I run the script in a SSH shell, I'm an administrator, and the code works as expected.

@vstinner vstinner changed the title Negative timestamp for an inaccessible file in Python 3.12/Windows Windows: os.stat() returns random times on ERROR_ACCESS_DENIED Jan 19, 2024
@zooba
Copy link
Member
zooba commented Jan 22, 2024

This is fixed in 3.13 already. See #111877.

@zooba zooba closed this as not planned Won't fix, can't repro, duplicate, stale Jan 22, 2024
@zooba
Copy link
Member
zooba commented Jan 22, 2024

It's also been backported, so the next 3.12 will have the fix. I think it missed the last update because of a lack of reviewers.

@vstinner
Copy link
Member

I confirm that the fix works as expected. On the current main branch, os.path.getmtime('C:\\System Volume Information') returns a valid timestamp, rather than an invalid negative timestamp.

I also confirm that the code works as expected in the current 3.11 and 3.12 branches.

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

No branches or pull requests

5 participants
0