Bug#805391: src:rrdtool: FTBFS on mips: `FAIL: tune2`

Niko Tyni <[email protected]>
Newsgroups gmane.linux.debian.devel.bugs.general,gmane.linux.debian.ports.mips
Message-ID <[email protected]>
On Tue, Nov 24, 2015 at 04:24:54PM +0000, Jean-Michel Vourgère wrote:
> Control: tags -1 + help
> 
> Antonio Terceiro wrote:
> > "make  check-TESTS" fails
> 
> I tested previous version on mips, and it now FTBFS too. It used to work
> ok. [1] (thanks Tobias, upstream, for suggesting that.)
> 
> So I suppose it is related to another package.
> 
> I tried compiling with good old gcc 4.9 and I get the same error in 1.5.4.

It's a latent bug in rrdtool that triggered with libc6 2.19-20 on mips.

The test suite failure in tests/tune2 boils down to

 rrdtool tune --beta 0.4 tests/tune2-testorg.rrd

zeroing out a big part of the file in addition to changing a single byte
like it's supposed to. It's easy to see by calling

 rrdtool dump tests/tune2-testorg.rrd >/dev/null

which starts to fail with stderr

 ERROR: unknown consolidation function ''

on a corrupted file.

This started to happen with libc6 2.19-20, as tested by compiling rrdtool
1.5.5 on jessie and running with LD_LIBRARY_PATH pointing to different
libc.so.6 versions.

The problem is that rrd_write() ends up calling memcpy(3) on overlapping
memory areas, which is explicitly prohibited in its documentation. With
libc6 2.19-20 on mips, this started zeroing out part of the areas under
some conditions. The attached testcase triggers it at least on minkus.d.o,
tested with something like

  #!/bin/bash
  dd if=/dev/urandom of=testfile.orig bs=1024 count=1
  gcc t.c
  cp testfile.orig testfile
  ./a.out testfile
  diff -u <(od -x testfile.orig) <(od -x testfile)
  
which normally doesn't show any differences.  I'm cc'ing the libc6
maintainers, not sure how intentional this change of behaviour is.

Backtrace for the rrd_write() call that triggers it:

  #0  rrd_write (rrd_file=0x41d038, buf=0x77fef168, count=560) at rrd_open.c:798
  #1  0x77f65888 in rrd_tune (argc=4, argv=0x7fff6648) at rrd_tune.c:395
  #2  0x00402f44 in HandleInputLine (argc=5, argv=0x7fff6644, out=0x77f56900 <_IO_2_1_stderr_>) at rrd_tool.c:800
  #3  0x00400f10 in main (argc=5, argv=0x7fff6644) at rrd_tool.c:545
  
  (gdb) print ((rrd_simple_file_t *) rrd_file->pvt)->file_start + rrd_file->pos
  $6 = 0x77fef168 "HWPREDICT"
  
  (gdb) print (char *)buf
  $8 = 0x77fef168 "HWPREDICT"

A workaround is to configure with --disable-mmap, except that seems
to break tests/tune1 on all architectures (at least amd64 and mips).
I haven't looked into that.
-- 
Niko Tyni   [email protected]
t.c (text/x-csrc, 612 B)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

#define MYSIZE 1024

int main(int argc, char **argv) {
    int fd;
    char *d;

    if (argc != 2) {
        fprintf(stderr, "file argument needed\n");
        exit(1);
    }
    fd = open(argv[1], O_RDWR);
    if (fd < 0)
        perror("open failed");
    d = mmap(NULL, MYSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (!d)
        perror("mmap");
    memcpy(d+260, d+260, 355);
    if (munmap(d, MYSIZE) < 0)
        perror("munmap");
    return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.