Bug 383516 - valgrind uses getgroups16 in ppc32_linux but should be using getgroups. This causes stack smash
Summary: valgrind uses getgroups16 in ppc32_linux but should be using getgroups. This ...
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: 3.13.0
Platform: unspecified Linux
: NOR crash
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-08-14 20:37 UTC by micael
Modified: 2018-07-25 06:54 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description micael 2017-08-14 20:37:49 UTC
Architecture
------------

ppc32

Scenario:
---------

my binary:

main:

   setgroups(30, list )

   fork

   if (son)

     execve

Crash:
------

Valgrind crashes in execv. ( the impossible happened ...)
After looking at the crash a little bit here is my insight:

When the binary does execv, coregrind/m_libcfile.c:VG_(check_executable) runs. In this function, VG_(getgroups) is called.

If we look at coregrind/m_libcproc.c at the implementation of VG_(getgroups),
we see that: if defined(VGP_ppc32_linux) then valgrind uses a UShort array. This is probably because it supposes getgroups will be getgroups16 in the kernel.

But ppc32 in many kernel versions ( 2.6.16 to 3.9 or so) does not even have
the option to select CONFIG_UID16. Meaning it cant compile getgroups16.

So when valgrind calls the syscall, the kernel overruns the list16 array passed by the valgrind. After that valgrind crashes because its stack is smashed.

Notes
-----

The crash happens only when the setgroups is called with a big enough number. Otherwise the overrun is not big enough.

Solution
--------

I compiled valgrind again by changing the || defined(VGP_ppc32_linux) to the elif statement in the VG_(getgroups) function. Therefore making valgrind use a 32 bit array instead of 16 bit array. This solved the problem.

If this is the solution I would be pleased to submit the patch.
Comment 1 Julian Seward 2018-07-25 06:54:14 UTC
(In reply to micael from comment #0)

> I compiled valgrind again by changing the || defined(VGP_ppc32_linux) to the
> elif statement in the VG_(getgroups) function. Therefore making valgrind use
> a 32 bit array instead of 16 bit array. This solved the problem.
> 
> If this is the solution I would be pleased to submit the patch.

I would be happy to take that fix, *if* it will work for all ppc32-linux
kernels.  It is unclear (to me, at least) from your description, whether
the fix will work for all kernel versions, or only some.  Can you
clarify this?