-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
pass big values for arg to fcntl.ioctl #74850
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
Comments
When passing a big integer value to fcntl.ioctl this might result in
. Traditionally ioctl(3) takes a pointer as third argument. The fcntl module however uses an int (format specifier 'i') which is too small to hold a pointer on 64 bit architectures. The fix is to use 'k' (and an unsigned long) instead of 'i' (and an int). An unsigned long is suitable to hold a pointer value on AFAIK all platforms that matter today. (And it works on all platforms where int is already good enough, so the suggested change doesn't do any harm.) A patch is attached. |
The FreeBSD [1], OpenBSD [2], and Solaris 10 [3] documentations specify the third argument of ioctl() as either an int or a pointer. Passing a 64-bit long instead of a 32-bit int on big-endian platform can cause incorrect interpretation of an argument. [1] https://www.freebsd.org/cgi/man.cgi?query=ioctl&sektion=2 |
So the only option to fix this is to determine the type of arg from the request parameter? I failed to find the implementation of ioctl for linux in glibc, the best I found is one that only seems to be used on powerpc[1] which seems to assume that the third argument is a pointer. The Linux kernel prototype takes an unsigned long[2] and encodes the size of the data pointed to in the request using _IOC[3]. On hurd there are different macros to determine the type. I'm not fluent in *BSD and Solaris (and other operating systems), so I cannot add specifics for them. I cannot even say which OS that runs Python can run in 64 bit BE mode. [1] https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/powerpc/ioctl.c;h=e2e3d3357f9f5ee9ffe5e9f0588ebae9976c0dfd;hb=HEAD |
PR 2286 uses for the third argument char* on Linux and int or unsigned int on other platforms. It keeps some degree of integer overflow control. |
My PR also is not correct, because even on Linux some calls require an argument of type It is not possible safely pass integer arguments in wider range without introducing an explicit parameter for this. But what is the use case? What calls require an integer argument in wider range? If it needs a pointer, it is usually a pointer to some request-specific structure, and you can pass a buffer object that represent such structure. The address of the buffer will be passed to the For now, |
Do you mind closing this issue for now? @serhiy-storchaka or do you think this should be kept opened? (in which case, maybe remove the pending label) |
Some ioctl calls need int64_t instead of int. This is a part of a bigger issue (there are several open issues for other particular cases). I have a plan of a general solution, so I'll keep this issue open as a reminder. |
I may have been wrong, or at least I can't remember what I meant. Some It may be that some values should actually be interpreted as |
I am closing this. If there are any constants that exceed the 32-bit integer range, we can re-open this issue. |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: