FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

resource library (getrlimit, setrlimit) interprets resource limits as signed integers instead of unsigned · Issue #137044 · python/cpython · GitHub

Repository navigation

resource library (getrlimit, setrlimit) interprets resource limits as signed integers instead of unsigned #137044

Closed

Description

Bug report

Bug description:

  • as per System Calls Manual (man 2 setrlimit), rlim_t is an unsigned integer type
  • in Python, reading the default hard limit (resource.getrlimit(resource.RLIMIT_CPU)) will return -1
  • executing this:
resource.setrlimit(resource.RLIMIT_CPU, (-2, -2))
os.system("ulimit -t")

returns 18446744073709551614

  • executing ulimit -t 18446744073709551614, then in python3 resource.getrlimit(resource.RLIMIT_CPU), will return -2

This behaviour is very weird and will cause the following rather useful and common snippet to fail:

_, hardlimit = resource.getrlimit(resource.RLIMIT_CPU)
rlimit = (min(timelimit, hardlimit), hardlimit)
resource.setrlimit(resource.RLIMIT_CPU, rlimit)

There happens to exist the following workaround:

_, hardlimit = resource.getrlimit(resource.RLIMIT_CPU)
softlimit = ctypes.c_long(min(seconds, ctypes.c_ulong(hardlimit).value)).value
rlimit = (softlimit, hardlimit)
resource.setrlimit(resource.RLIMIT_CPU, rlimit)

but it just feels extremely hacky to do things like this and I believe a lot of programmers end in this trap.
Especially that when you handle the -1 case specially (as it is mentioned in man, that "RLIM_INFINITY typically is the same as -1"), it still fails with other negative values like -2.

CPython versions tested on:

3.15

Operating systems tested on:

Linux

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jul 23, 2025
  2. serhiy-storchaka commented on Jul 23, 2025

    Member

    This is one of the cases where the integer type is unsigned, but -1 is a special value. RLIM_INFINITY is defined as ((__rlim_t) -1). It is more convenient to get/set -1 on all platforms than 0xffffffff or 0xffffffffffffffff depending on platform.

    There is no standard way to handle this. We have special converters for uid_t, gid_t and dev_t. It seems that it is also needed for rlim_t.

  3. serhiy-storchaka commented on Jul 23, 2025

    Member

    I assigned this to myself because it requires writing non-trivial bulky code, and I've already started.

  4. added a commit that references this issue on Aug 3, 2025
  5. serhiy-storchaka commented on Aug 3, 2025

    Member

    User code can depends on the fact that RLIM_INFINITY is -1 (although this is not documented). But there are reasons to represent it a large positive value, larger than any finite limit. One of them shown in the original report, but there is also the glibc feature on 32-bit platforms: if a program tried to set a resource limit to a value larger than can be represented in a 32-bit unsigned long, then the glibc setrlimit() wrapper function silently converted the limit value to RLIM_INFINITY.

    So, I am planning two changes:

    1. Support large values and reject negative values (except RLIM_INFINITY). This can be considered as a bug fix and can be backported.
    2. Make RLIM_INFINITY a positive integer. This can only go in 3.15.
  6. serhiy-storchaka commented on Aug 6, 2025

    Member

    On some platforms RLIM_INFINITY is not (rlim_t)-1, but (rlim_t)-3, 2**31-1 or 2**63-1. On FreeBSD rlim_t is signed.

  7. added a commit that references this issue on Aug 7, 2025
  8. added 2 commits that reference this issue on Aug 7, 2025
  9. added 2 commits that reference this issue on Aug 7, 2025
  10. encukou commented on Aug 7, 2025

    Member

    There are two parts to step 2:

    • Make RLIM_INFINITY a positive integer. This can only go in 3.15
    • Disallow setting the limit to the negative-number representation of RLIM_INFINITY

    I don't think we should make the second change. It seems it could break an unknown number of quick & dirty platform-specific scripts.

    Thinking about it, I'm -0 on making RLIM_INFINITY positive, too. If it's -1 (or -3 on some systems), I can just print it out from a script and it'll make sense. If it's a huge number, it needs the "proper" treatment (an if and print "unlimited" instead) -- too much extra work in a quick admin script.

  11. ArturBieniek4 commented on Aug 7, 2025

    Author

    Why shouldn't it just work like in C?

    • RLIM_INFINITY is defined as -1 assigned to an unsigned integer, which for a 64-bit int is 2**63-1
    • You can pass any negative value and it will just be interpreted as an unsigned binary-equal value

    I also don't think passing negative integers should be disallowed - why not just allow them but interpret them as unsigned values?

  12. 9 remaining items

  13. encukou commented on Aug 19, 2025

    Member

    AFAIU, that sentence means that whenever you have RLIM_INFINITY you should consider it infinite, regardless of what the actual numeric value is.
    In other words, the value doesn't matter. It should not be used for numeric comparisons.

  14. added a commit that references this issue on Aug 19, 2025
  15. added a commit that references this issue on Aug 19, 2025
  16. serhiy-storchaka commented on Aug 19, 2025

    Member

    Even if it can be interpreted that way, I don't know of any platform where RLIM_INFINITY is not greater than any other value (except for the special values RLIM_SAVED_MAX and RLIM_SAVED_CUR). I think a lot of code depends on that, so it would be not safe to define RLIM_INFINITY any other way.

  17. encukou commented on Aug 19, 2025

    Member

    I think a lot of code depends on that

    Do you have any examples?

  18. ArturBieniek4 commented on Aug 19, 2025

    Author

    The most trivial example is already given at the beginning of this issue:

    _, hardlimit = resource.getrlimit(resource.RLIMIT_CPU)
    rlimit = (min(timelimit, hardlimit), hardlimit)
    resource.setrlimit(resource.RLIMIT_CPU, rlimit)

    I genuinely wrote this code and expected it to work and was so surprised it did not.

  19. encukou commented on Aug 19, 2025

    Member

    This would suggest that existing, working Python code does not depend on RLIM_INFINITY being a large int. (As it should not, per Posix.)

  20. serhiy-storchaka commented on Aug 19, 2025

    Member

    But a similar code in C works.

    Well, I'll remove that sentence if you insist.

  21. added 2 commits that reference this issue on Aug 19, 2025
  22. added 3 commits that reference this issue on Aug 19, 2025
  23. added a commit that references this issue on Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


    Back | FazBrowse Home | New Git URL