lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <af2c346e-c878-45dd-93b9-b19c80627651@app.fastmail.com>
Date: Thu, 05 Feb 2026 08:57:54 +0100
From: "Arnd Bergmann" <arnd@...db.de>
To: "Hui Min Mina Chou" <minachou@...estech.com>,
 "Paul Walmsley" <pjw@...nel.org>, "Palmer Dabbelt" <palmer@...belt.com>,
 "Albert Ou" <aou@...s.berkeley.edu>, "Alexandre Ghiti" <alex@...ti.fr>,
 linux-riscv@...ts.infradead.org, linux-kernel@...r.kernel.org,
 Linux-Arch <linux-arch@...r.kernel.org>
Cc: tim609@...estech.com, "Ben Zong-You Xie" <ben717@...estech.com>,
 az70021@...il.com, Randolph <randolph@...estech.com>
Subject: Re: [PATCH] riscv: Fix __kernel_off_t to 64 Bits in RV32

On Thu, Feb 5, 2026, at 06:58, Hui Min Mina Chou wrote:
> From: Randolph <randolph@...estech.com>
>
> Modify the __kernel_off_t type for RV32 to 64 bits to comply with
> the current glibc calling convention.
>
> In RISC-V, off_t is 64 bits in glibc, and __kernel_off_t must match
> this size. For RV32, the kernel uses the long type, which should be
> changed to long long to ensure consistency.

I don't think we can change the ABI incompatibly like this,
it breaks any current user of low-level interface that expects
the legacy types, whenever you mix a userspace binary built against
old kernel headers with a new kernel, or vice versa.

>From looking at uclibc sources, I believe they still default to
a 32-bit off_t on all 32-bit architectures.

> To address the Y2038 problem, the glibc upstream for RISC-V has adopted
> 64-bit time_t and off_t for both RV32 and RV64 [*1].
> However, no corresponding modification was made on the kernel side,
> leading to test case failures in LTP’s fnctl due to size inconsistencies.
> This discrepancy causes errors when glibc passes the struct flock
> parameter to the kernel through fnctl().

I'm not sure if this is a bug in LTP or glibc, but nothing should
ever mix the low-level kernel interfaces with the glibc types.

Regardless of the architecture, the only combinations that are
allowed are:

 - libc fcntl() with libc 'struct flock'
 - libc fcntl64() with libc 'struct flock64'
 - syscall(__NR_fcntl, ...) with kernel 'struct flock'
 - syscall(__NR_fcntl64, ...) with kernel 'struct flock64'

When using 64-bit off_t in glibc, that should transparently
map the default fcntl implementation to the newer kernel
interfaces as described in the fcntl man page.

Can you point out which LTP tests exactly are failing, and
check which combination they use in your version?

Is it picking up the 32-bit types from the kernel headers,
or is it trying to call the legacy __NR_fcntl syscall
with the glibc type?

I see a special case in
ltp/testcases/kernel/syscalls/fcntl/fcntl_common.h, but that
seems to use the low-level kernel interfaces correctly.

> The structure of flock are shown as below:
>
> struct flock in glibc:
> ------------------------------------------------------
> struct flock
>   {
>     short int l_type;
>     short int l_whence;
>     __off_t l_start;
>     __off_t l_len;
>     __off64_t l_start;
>     __off64_t l_len;             <------  "__off64_t" in glibc is 64bit
>     __pid_t l_pid;
>   };

The definition I see has this  #ifdef check:

struct flock
  {
    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
#if __WORDSIZE == 64 || !defined __USE_FILE_OFFSET64
    __off_t l_start;    /* Offset where the lock begins.  */
    __off_t l_len;      /* Size of the locked area; zero means until EOF.  */
#else
    __off64_t l_start;  /* Offset where the lock begins.  */
    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
#endif
    __pid_t l_pid;      /* Process holding the lock.  */
  };

I assume __USE_FILE_OFFSET64 is always set on riscv32, so the
two structures are defined to be the same and match the kernel's
flock64.

The definition is otherwise the same as on most 32-bit architectures.

Interestingly, microblaze does not even have that #if block
and instead defines its 'struct flock' unconditionally with
a 32-bit __off_t, which is probably a bug in glibc.

> +/*
> + * In the generic flow, this file is automatically created if it does 
> not
> + * already exist, as indicated by the line.
> + * "#include <asm-generic/posix_types.h>"
> + *
> + * If the file already exists, the automatic creation process will be 
> skipped.
> + * Adding architecture-specific types to this file may alter the 
> generic flow,
> + * potentially causing type conflicts during the build phase. To avoid 
> this,
> + * define a variable to instruct the generic code to skip the 
> re-typedef
> + * process.
> + */

There is really no need to explain how the build system works here.

> +#if __BITS_PER_LONG == 32
> +typedef long long		__kernel_off_t;
> +#define _arch_kernel_off_t	_arch_kernel_off_t
> +#endif

This does not follow the normal style for overriding types.
You are also breaking the compat syscall for rv64 kernels,
which would have to override compat_off_t.

     Arnd

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ