Bug 331833 - the memory initialized by semget(key, 0, GETALL, semun) is treated as uninitialized on some platforms
Summary: the memory initialized by semget(key, 0, GETALL, semun) is treated as uniniti...
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.9.0
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-06 23:28 UTC by Tony Cook
Modified: 2014-03-06 23:28 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tony Cook 2014-03-06 23:28:08 UTC
The memory initialized by semget(key, 0, GETALL, semun) is considered uniniitalized by valgrind on some platforms.

I tested this on CentOS 6.4 (which complained) and Debian 7.4 (which didn't).

In both cases valgrind was built from source.

Reproducible: Always

Steps to Reproduce:
1.
2.
3.

1. Build the following code:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>

void fail(const char *what) {
  perror(what);
  exit(1);
}

union semun {
  int              val;    /* Value for SETVAL */
  struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
  unsigned short  *array;  /* Array for GETALL, SETALL */
  struct seminfo  *__buf;  /* Buffer for IPC_INFO                               
                              (Linux-specific) */
};

#define SCOUNT 10

int main() {
  int key = semget(IPC_PRIVATE, SCOUNT, 0600);
  if (key == -1) fail("semget");

  int i;
  unsigned short setbuf[SCOUNT];
  /* fill with something we're unlikely to see otherwise */
  for (i = 0; i < 10; ++i)
    setbuf[i] = 10 + i * 9;
  union semun su;

  su.array = setbuf;
  if (semctl(key, 0, SETALL, su) != 0)
    fail("SETALL");

  unsigned short getbuf[SCOUNT];
  su.array = getbuf;
  if (semctl(key, 0, GETALL, su) != 0)
    fail("GETALL");
  if (getbuf[0] != 10)
    printf("broken\n");
  for (i = 0; i < SCOUNT; ++i)
    printf("%d: %u\n", i, getbuf[i]);

  semctl(key, 0, IPC_RMID);

  return 0;
}

$ gcc -g -osemctl semctl.c

2. Run with valgrind 3.9.0 on CentoOS 6.4:

Actual Results:  
$ ~/local/valgrind-3.9.0/bin/valgrind ./semctl 
==13614== Memcheck, a memory error detector
==13614== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13614== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==13614== Command: ./semctl
==13614== 
==13614== Conditional jump or move depends on uninitialised value(s)
==13614==    at 0x400716: main (semctl.c:40)
==13614== 
==13614== Use of uninitialised value of size 8
==13614==    at 0x4E72D1B: _itoa_word (in /lib64/libc-2.12.so)
==13614==    by 0x4E758D2: vfprintf (in /lib64/libc-2.12.so)
==13614==    by 0x4E7E409: printf (in /lib64/libc-2.12.so)
==13614==    by 0x40074E: main (semctl.c:43)
==13614== 
==13614== Conditional jump or move depends on uninitialised value(s)
==13614==    at 0x4E72D25: _itoa_word (in /lib64/libc-2.12.so)
==13614==    by 0x4E758D2: vfprintf (in /lib64/libc-2.12.so)
==13614==    by 0x4E7E409: printf (in /lib64/libc-2.12.so)
==13614==    by 0x40074E: main (semctl.c:43)
==13614== 
0: 10
1: 19
2: 28
3: 37
4: 46
5: 55
6: 64
7: 73
8: 82
9: 91
==13614== 
==13614== HEAP SUMMARY:
==13614==     in use at exit: 0 bytes in 0 blocks
==13614==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13614== 
==13614== All heap blocks were freed -- no leaks are possible
==13614== 
==13614== For counts of detected and suppressed errors, rerun with: -v
==13614== Use --track-origins=yes to see where uninitialised values come from
==13614== ERROR SUMMARY: 41 errors from 3 contexts (suppressed: 6 from 6)


Expected Results:  
$ ~/local/valgrind-3.9.0/bin/valgrind ./semctl 
==13614== Memcheck, a memory error detector
==13614== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13614== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==13614== Command: ./semctl
==13614== 
0: 10
1: 19
2: 28
3: 37
4: 46
5: 55
6: 64
7: 73
8: 82
9: 91
==13614== 
==13614== HEAP SUMMARY:
==13614==     in use at exit: 0 bytes in 0 blocks
==13614==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==13614== 
==13614== All heap blocks were freed -- no leaks are possible
==13614== 
==13614== For counts of detected and suppressed errors, rerun with: -v
==13614== Use --track-origins=yes to see where uninitialised values come from
==13614== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


From the CentOS machine that fails:

$ uname -sr
Linux 2.6.32-358.el6.x86_64
$ gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
...

From the Debian machine that passes:

$ uname -sr
Linux 3.2.0-4-amd64
$ gcc --version
gcc (Debian 4.7.2-5) 4.7.2
...

This example was produced based on a valgrind failure for blead perl, see:

https://rt.perl.org/Ticket/Display.html?id=121335

for details.