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

Fix fcntl module to accept 'unsigned long' type commands for ioctl(2). #69214

Closed
koobs opened this issue Sep 8, 2015 · 16 comments
Closed

Fix fcntl module to accept 'unsigned long' type commands for ioctl(2). #69214

koobs opened this issue Sep 8, 2015 · 16 comments
Labels
easy interpreter-core (Objects, Python, Grammar, and Parser dirs) OS-freebsd type-bug An unexpected behavior, bug, or error

Comments

@koobs
Copy link

koobs commented Sep 8, 2015

BPO 25026
Nosy @larryhastings, @ceronman, @vadmium, @serhiy-storchaka, @koobs, @corona10

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 = None
closed_at = None
created_at = <Date 2015-09-08.06:35:17.934>
labels = ['interpreter-core', 'easy', 'type-bug']
title = "(FreeBSD/OSX) Fix fcntl module to accept 'unsigned long' type commands for ioctl(2)."
updated_at = <Date 2019-08-25.10:01:51.693>
user = 'https://github.com/koobs'

bugs.python.org fields:

activity = <Date 2019-08-25.10:01:51.693>
actor = 'corona10'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2015-09-08.06:35:17.934>
creator = 'koobs'
dependencies = []
files = []
hgrepos = []
issue_num = 25026
keywords = ['easy']
message_count = 10.0
messages = ['250163', '250164', '250166', '250170', '250173', '250174', '250178', '250322', '296062', '350447']
nosy_count = 6.0
nosy_names = ['larry', 'ceronman', 'martin.panter', 'serhiy.storchaka', 'koobs', 'corona10']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue25026'
versions = ['Python 2.7', 'Python 3.4', 'Python 3.5', 'Python 3.6']

Linked PRs

@koobs
Copy link
Author

koobs commented Sep 8, 2015

In my current attempt to create a FreeBSD port for python35, I've come across a patch rejection for the fcntlmodule.c for a local port patch we've been carrying since Python 2.6:

https://svnweb.freebsd.org/ports/head/lang/python27/files/patch-Modules__fcntlmodule.c?revision=391238&view=markup

The original commit log for this change is:

====================================

Fix fcntl module to accept 'unsigned long' type commands for ioctl(2).

Although POSIX says the type is 'int', all BSD variants (including Mac OS X)
have been using 'unsigned long' type for very long time and its use predates
the standard long enough. For certain commands (e.g., TIOCSWINSZ, FIONBIO),
the Python value may get sign-extended on 64-bit platforms (by implicit type
promotion) and it causes annoying warnings from kernel such as this:

WARNING pid 24509 (python2.6): ioctl sign-extension ioctl ffffffff8004667e

====================================

I'm not sure how this should be fixed upstream, nor clear on how to re-patch it given recent changes to fcntlmodule.c

@koobs koobs added interpreter-core (Objects, Python, Grammar, and Parser dirs) easy type-bug An unexpected behavior, bug, or error labels Sep 8, 2015
@serhiy-storchaka
Copy link
Member

You need just replace unsigned_int with unsigned_long in Clinic declaration for fcntl.ioctl in Modules/fcntlmodule.c and regenerate Clinic code (make clinic).

@koobs
Copy link
Author

koobs commented Sep 8, 2015

Thanks for the insight Serhiy. A few questions ..

Is clinic code updated based on *.c declarations at build time? If not when/how is the best place/method to run this for our ports/package builds?

Does your suggestion to switch unsigned_int to unsigned_long imply that the following lines are no longer necessary?

  • if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
    + if (PyArg_ParseTuple(args, "O&kw#|i:ioctl",

How do we get something like this fixed upstream for FreeBSD/OSX?

If left un-patched, what is the impact on the user/system? Just a warning on console?

@serhiy-storchaka
Copy link
Member

No, the clinic code is not updated at build time. Your should either update clinic code just after patching Modules/fcntlmodule.c (Python 3 is needed), or update clinic code at patch creation time and include changes of generated clinic files in the patch.

Generated clinic files contain a code for argument parsing (PyArg_ParseTuple...).

I don't know if there is easy way to make this change conditionally for FreeBSD/OSX. The only way that I know is writing custom converters.

Perhaps the original commit log is outdated. What was the type of code at the time of this log? Now it is unsigned int and this doesn't make sign extension when casted to unsigned long. While the code parameter is in the range 0..0xffffffff, unpatched code shouldn't have any visible effects.

@koobs
Copy link
Author

koobs commented Sep 8, 2015

@serhiy

If by "type of code at the time of commit" you mean upstream python code, msg250163 contains a link to what bits we replace in fcntlmodule.c and that "I -> k" has always been the same.

@serhiy-storchaka
Copy link
Member

Originally the type of the code variable in fcntl_ioctl() was int. In cbad1f5cabb1 it was changed to unsigned int. I guess that the log message that you cited was written before this.

@vadmium
Copy link
Member

vadmium commented Sep 8, 2015

If necessary, perhaps we could unconditionally change the Python-level argument to unsigned_long, and then add a conditional bit in the C code to convert it to int if appropriate.

But I wonder if most of the problem is fixed by bpo-1471 (linked from the commit Serhiy identified). As I see it, your patch should now only be needed to support “code” values outside of the range of unsigned_int, e.g. that require > 32 bits.

@serhiy-storchaka
Copy link
Member

The question is: are ioctl codes outside of the unsigned int range used on BSD family or Mac OS X?

@vadmium
Copy link
Member

vadmium commented Jun 15, 2017

Maybe bpo-16124 is related; it mentions 64-bit values, but it sounds like an obscure use case.

@corona10
Copy link
Member

Can I take a look at this issue?
Is there anything should I care about except update clinic?
Thanks!

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@emaste
Copy link
Contributor

emaste commented Apr 19, 2022

bpo-16124 is #60328

The question is: are ioctl codes outside of the unsigned int range used on BSD family or Mac OS X?

I don't have an authoritative answer for other BSDs or OS X, but for FreeBSD they are not. In addition, we have hidden the warning under a diagnostic option in freebsd/freebsd-src@a90fb6c

vstinner added a commit to vstinner/cpython that referenced this issue May 24, 2024
Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.
@vstinner
Copy link
Member

The question is: are ioctl codes outside of the unsigned int range used on BSD family or Mac OS X?

Linux manual page of ioctl clearly uses the unsigned long type for the request parameter: https://man7.org/linux/man-pages/man2/ioctl.2.html

       int ioctl(int fd, unsigned long request, ...);

Python should use the right type. I wrote PR gh-119498 to fix the request parameter of fcntl.ioctl().

@vstinner vstinner changed the title (FreeBSD/OSX) Fix fcntl module to accept 'unsigned long' type commands for ioctl(2). Fix fcntl module to accept 'unsigned long' type commands for ioctl(2). May 24, 2024
@vstinner
Copy link
Member

Linux, FreeBSD, macOS uses unsigned long. IMO we should take care of these platforms. Solaris is not supported by Python (PEP 11).

vstinner added a commit that referenced this issue May 24, 2024
Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue May 24, 2024
Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.
(cherry picked from commit 92fab33)

Co-authored-by: Victor Stinner <[email protected]>
vstinner added a commit to vstinner/cpython that referenced this issue May 24, 2024
Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.

(cherry picked from commit 92fab33)
vstinner added a commit that referenced this issue May 24, 2024
gh-69214: Fix fcntl.ioctl() request type (#119498)

Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.

(cherry picked from commit 92fab33)
vstinner added a commit that referenced this issue May 24, 2024
gh-69214: Fix fcntl.ioctl() request type (GH-119498)

Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.
(cherry picked from commit 92fab33)

Co-authored-by: Victor Stinner <[email protected]>
vstinner added a commit to vstinner/cpython that referenced this issue Jun 1, 2024
vstinner added a commit to vstinner/cpython that referenced this issue Jun 1, 2024
…GH-119498) (python#119504)"

This reverts commit 0bab0b3.

The change modified how negative values, like termios.TIOCSWINSZ, was
treated and is actually backward incompatible.
vstinner added a commit to vstinner/cpython that referenced this issue Jun 1, 2024
…#119498) (python#119505)"

This reverts commit 078da88.

The change modified how negative values, like termios.TIOCSWINSZ, was
treated and is actually backward incompatible.
@vstinner
Copy link
Member

vstinner commented Jun 1, 2024

This change broke test_ioctl on macOS: #119770

So I created two PRs to revert the change in 3.12 and 3.13 branches.

vstinner added a commit that referenced this issue Jun 1, 2024
…) (#1… (#119905)

Revert "[3.12] gh-69214: Fix fcntl.ioctl() request type (#119498) (#119505)"

This reverts commit 078da88.

The change modified how negative values, like termios.TIOCSWINSZ, was
treated and is actually backward incompatible.
vstinner added a commit that referenced this issue Jun 1, 2024
…9498) (… (#119906)

Revert "[3.13] gh-69214: Fix fcntl.ioctl() request type (GH-119498) (#119504)"

This reverts commit 0bab0b3.

The change modified how negative values, like termios.TIOCSWINSZ, was
treated and is actually backward incompatible.
@Eclips4
Copy link
Member

Eclips4 commented Jun 1, 2024

Thank you Victor for your work!

@Eclips4 Eclips4 closed this as completed Jun 1, 2024
@vstinner
Copy link
Member

vstinner commented Jun 1, 2024

I went through FreeBSD issues recently and decided to fix this 9 years old issue.

estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
Use an 'unsigned long' instead of an 'unsigned int' for the request
parameter of fcntl.ioctl() to support requests larger than UINT_MAX.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
easy interpreter-core (Objects, Python, Grammar, and Parser dirs) OS-freebsd type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

7 participants