[LTP] shmctl03.c is broken for 32bit compat mode
Li Wang
liwang@redhat.com
Tue Aug 12 10:40:11 CEST 2025
On Mon, Aug 11, 2025 at 4:04 PM Dan Carpenter <dan.carpenter@linaro.org>
wrote:
> On Sun, Aug 10, 2025 at 11:46:32AM +0800, Li Wang wrote:
> > Hi Dan,
> >
> > On Fri, Aug 8, 2025 at 9:53 PM Dan Carpenter <dan.carpenter@linaro.org>
> > wrote:
> >
> > > In 32bit compat mode the shmctl03.c test will always fail:
> > >
> > > shmctl03.c:33: TFAIL: /proc/sys/kernel/shmmax != 2147483647 got
> 4294967295
> > > shmctl03.c:34: TPASS: /proc/sys/kernel/shmmni = 4096
> > > shmctl03.c:35: TFAIL: /proc/sys/kernel/shmall != 4278190079 got
> 4294967295
> > >
> > > The test basically does this:
> > > // === === ===
> > > #define _GNU_SOURCE
> > > #include <sys/shm.h>
> > > #include <stdio.h>
> > >
> > > int main(void)
> > > {
> > > struct shminfo info;
> > >
> > > shmctl(0, IPC_INFO, (struct shmid_ds *)&info);
> > >
> > > printf("shmmax = %lu\n", info.shmmax);
> > > printf("shmmni = %lu\n", info.shmmni);
> > > printf("shmall = %lu\n", info.shmall);
> > >
> > > return 0;
> > > }
> > > // === === ===
> > >
> > > It compares that output with what we read from the file. You can run
> > > "gcc -m32 test.c && ./a.out" to see the issue.
> > >
> > > In the first line shmmax is not the value that we read from the file
> > > because it was capped at INT_MAX by the kernel in commit af7c693f1460
> > > ("Cap shmmax at INT_MAX in compat shminfo").
> > > https://elixir.bootlin.com/linux/v6.16/source/ipc/shm.c#L1347
> > >
> > > With the last line we're trying to store a u64 value into a u32. We're
> > > going to lose something so it's not going to be accurate. The
> difference
> > > is how scanf() truncates it. If you have 32bit longs then it will give
> > > you the first u32 but if you assign a u64 to a u32 like the rest of the
> > > code does then you'll get the last 32 bits.
> > >
> > > What's the right way to go about fixing this?
> > >
> >
> > Maybe we can simply split the comparison part into two:
> >
> > #ifdef TST_ABI64: go with the original way.
> >
> > #ifdef TST_ABI32:
>
> Will this affect real 32bit systems? The problem is only when we're
> emulating a 32bit system on a 64bit system using the COMPAT code.
>
Yes, you're right.
Looking into the kernel and test related code, that seems the test will pass
as long as that /proc/sys/kernel/{shmmax,shmmni,shmall} equals with the
info.{shmmax,shmmni,shmall}.
On a modern native 32bit platform, it will still choose the IPC_64 branch
and the
kernel copies shminfo64 fields directly. So test should pass as well.
https://elixir.bootlin.com/linux/v6.16/source/ipc/shm.c#L906
>
> > 'shmmax' expects INT_MAX from shmctl(0, IPC_INFO, ...), even if '
> > /proc/sys/kernel/shmmax' is higher.
> > 'shmall' compares the lower 32 bits of the value (expect_shmall =
> > shmall & 0xFFFFFFFF;)
> >
>
> To be honest, the correct thing with regards to shmall is to cap it at
> INT_MAX in the kernel as well. I didn't want to suggest this because it
> was Friday afternoon. Reporting whatever is in the low 32bits is sort
> of random. But that would make it even more tricky to handle in LTP.
>
Okay, you can try Cyril's suggestion, which sounds more reliable.
--
Regards,
Li Wang
More information about the ltp
mailing list