[PATCH] nptl: Fix SYSCALL_CANCEL for return values larger than INT_MAX (BZ 33245)
Sam James
sam@gentoo.org
Sat Aug 2 19:07:58 GMT 2025
Sam James <sam@gentoo.org> writes:
> Adhemerval Zanella <adhemerval.zanella@linaro.org> writes:
>
>> The SYSCALL_CANCEL calls __syscall_cancel, which in turn
>> calls __internal_syscall_cancel with an 'int' return instead of the
>> expected 'long int'. This causes issues with syscalls that return
>> values larger than INT_MAX, such as copy_file_range [1].
>>
>> Checked on x86_64-linux-gnu.
>>
>> [1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79139
>
> The patch is OK:
>
> Reviewed-by: Sam James <sam@gentoo.org>
>
>> ---
>> nptl/cancellation.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> but I have a question about some other instances, though I didn't look
> afresh yet today, just from last night.
>
> Do we need something like the attached? I think the readlink one doesn't
> actually matter because of path sizes.
OK, looked more closely..
>
> diff --git a/sysdeps/unix/sysv/linux/dl-origin.c b/sysdeps/unix/sysv/linux/dl-origin.c
> index 3c52ba51a6..b7fec7cc3f 100644
> --- a/sysdeps/unix/sysv/linux/dl-origin.c
> +++ b/sysdeps/unix/sysv/linux/dl-origin.c
> @@ -32,7 +32,7 @@ _dl_get_origin (void)
> {
> char linkval[PATH_MAX];
> char *result;
> - int len;
> + long len;
>
> len = INTERNAL_SYSCALL_CALL (readlinkat, AT_FDCWD, "/proc/self/exe",
> linkval, sizeof (linkval));
> @@ -84,7 +84,7 @@ _dl_canonicalize (int fd)
> struct fd_to_filename fdfilename;
> char canonical[PATH_MAX];
> char *path = __fd_to_filename (fd, &fdfilename);
> - int size = INTERNAL_SYSCALL_CALL (readlinkat, AT_FDCWD, path,
> + long size = INTERNAL_SYSCALL_CALL (readlinkat, AT_FDCWD, path,
> canonical, PATH_MAX - 1);
Again, doesn't really matter in practice AFAICT.
>
> /* Check if the path was truncated. */
> diff --git a/sysdeps/unix/sysv/linux/lseek.c b/sysdeps/unix/sysv/linux/lseek.c
> index ff83735d09..9a1383f782 100644
> --- a/sysdeps/unix/sysv/linux/lseek.c
> +++ b/sysdeps/unix/sysv/linux/lseek.c
> @@ -47,7 +47,7 @@ __lseek (int fd, off_t offset, int whence)
>
> # ifdef __NR__llseek
> loff_t res;
> - int rc = INLINE_SYSCALL_CALL (_llseek, fd,
> + long int rc = INLINE_SYSCALL_CALL (_llseek, fd,
> (long) (((uint64_t) (offset)) >> 32),
> (long) offset, &res, whence);
> return rc ?: lseek_overflow (res);
*llseek* uses a parameter for its return value, so it should be fine. If
the arch lacks llseek, the other path is fine.
> diff --git a/sysdeps/unix/sysv/linux/lseek64.c b/sysdeps/unix/sysv/linux/lseek64.c
> index 49f4136844..b5624388cc 100644
> --- a/sysdeps/unix/sysv/linux/lseek64.c
> +++ b/sysdeps/unix/sysv/linux/lseek64.c
> @@ -32,7 +32,7 @@ __lseek64 (int fd, off64_t offset, int whence)
>
> #ifdef __NR__llseek
> loff_t res;
> - int rc = INLINE_SYSCALL_CALL (_llseek, fd,
> + long int rc = INLINE_SYSCALL_CALL (_llseek, fd,
> (long) (((uint64_t) (offset)) >> 32),
> (long) offset, &res, whence);
Ditto llseek/lseek above.
> return rc ?: res;
> diff --git a/sysdeps/unix/sysv/linux/sendfile.c b/sysdeps/unix/sysv/linux/sendfile.c
> index 990a26a3ea..1f04ce5aab 100644
> --- a/sysdeps/unix/sysv/linux/sendfile.c
> +++ b/sysdeps/unix/sysv/linux/sendfile.c
> @@ -32,7 +32,7 @@ sendfile (int out_fd, int in_fd, off_t *offset, size_t count)
> return INLINE_SYSCALL_CALL (sendfile, out_fd, in_fd, offset, count);
> # else
> __off64_t off64;
> - int rc;
> + ssize_t rc;
>
> if (offset != NULL)
> {
>
This one looks wrong but all arches have __NR_sendfile, so limited impact.
>
> (Completely untested, it's just from the audit I did earlier.)
>
>> [...]
>
> sam
sam
More information about the Libc-alpha
mailing list