Bug 383516

Summary: valgrind uses getgroups16 in ppc32_linux but should be using getgroups. This causes stack smash
Product: [Developer tools] valgrind Reporter: micael <micael.lasry>
Component: generalAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: crash CC: micael.lasry
Priority: NOR    
Version First Reported In: 3.13.0   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

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?