Blame elf/tst-ldconfig-bad-aux-cache.c

Packit Service eaa5d1
/* Test ldconfig does not segfault when aux-cache is corrupted (Bug 18093).
Packit Service eaa5d1
   Copyright (C) 2019 Free Software Foundation, Inc.
Packit Service eaa5d1
   This file is part of the GNU C Library.
Packit Service eaa5d1
Packit Service eaa5d1
   The GNU C Library is free software; you can redistribute it and/or
Packit Service eaa5d1
   modify it under the terms of the GNU Lesser General Public License as
Packit Service eaa5d1
   published by the Free Software Foundation; either version 2.1 of the
Packit Service eaa5d1
   License, or (at your option) any later version.
Packit Service eaa5d1
Packit Service eaa5d1
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service eaa5d1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service eaa5d1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service eaa5d1
   Lesser General Public License for more details.
Packit Service eaa5d1
Packit Service eaa5d1
   You should have received a copy of the GNU Lesser General Public
Packit Service eaa5d1
   License along with the GNU C Library; see the file COPYING.LIB.  If
Packit Service eaa5d1
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service eaa5d1
Packit Service eaa5d1
/* This test does the following:
Packit Service eaa5d1
   Run ldconfig to create the caches.
Packit Service eaa5d1
   Corrupt the caches.
Packit Service eaa5d1
   Run ldconfig again.
Packit Service eaa5d1
   At each step we verify that ldconfig does not crash.  */
Packit Service eaa5d1
Packit Service eaa5d1
#include <stdio.h>
Packit Service eaa5d1
#include <stdlib.h>
Packit Service eaa5d1
#include <string.h>
Packit Service eaa5d1
#include <unistd.h>
Packit Service eaa5d1
#include <errno.h>
Packit Service eaa5d1
#include <sys/wait.h>
Packit Service eaa5d1
#include <ftw.h>
Packit Service eaa5d1
#include <stdint.h>
Packit Service eaa5d1
Packit Service af3534
#include <support/capture_subprocess.h>
Packit Service eaa5d1
#include <support/check.h>
Packit Service eaa5d1
#include <support/support.h>
Packit Service eaa5d1
#include <support/xunistd.h>
Packit Service eaa5d1
Packit Service eaa5d1
#include <dirent.h>
Packit Service eaa5d1
Packit Service eaa5d1
static int
Packit Service eaa5d1
display_info (const char *fpath, const struct stat *sb,
Packit Service eaa5d1
              int tflag, struct FTW *ftwbuf)
Packit Service eaa5d1
{
Packit Service eaa5d1
  printf ("info: %-3s %2d %7jd   %-40s %d %s\n",
Packit Service eaa5d1
          (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" :
Packit Service eaa5d1
          (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" :
Packit Service eaa5d1
          (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" :
Packit Service eaa5d1
          (tflag == FTW_SLN) ? "sln" : "???",
Packit Service eaa5d1
          ftwbuf->level, (intmax_t) sb->st_size,
Packit Service eaa5d1
          fpath, ftwbuf->base, fpath + ftwbuf->base);
Packit Service eaa5d1
  /* To tell nftw to continue.  */
Packit Service eaa5d1
  return 0;
Packit Service eaa5d1
}
Packit Service eaa5d1
Packit Service af3534
static void
Packit Service af3534
execv_wrapper (void *args)
Packit Service af3534
{
Packit Service af3534
  char **argv = args;
Packit Service af3534
Packit Service af3534
  execv (argv[0], argv);
Packit Service af3534
  FAIL_EXIT1 ("execv: %m");
Packit Service af3534
}
Packit Service af3534
Packit Service eaa5d1
/* Run ldconfig with a corrupt aux-cache, in particular we test for size
Packit Service eaa5d1
   truncation that might happen if a previous ldconfig run failed or if
Packit Service eaa5d1
   there were storage or power issues while we were writing the file.
Packit Service eaa5d1
   We want ldconfig not to crash, and it should be able to do so by
Packit Service eaa5d1
   computing the expected size of the file (bug 18093).  */
Packit Service eaa5d1
static int
Packit Service eaa5d1
do_test (void)
Packit Service eaa5d1
{
Packit Service eaa5d1
  char *prog = xasprintf ("%s/ldconfig", support_install_rootsbindir);
Packit Service af3534
  char *args[] = { prog, NULL };
Packit Service eaa5d1
  const char *path = "/var/cache/ldconfig/aux-cache";
Packit Service eaa5d1
  struct stat64 fs;
Packit Service eaa5d1
  long int size, new_size, i;
Packit Service eaa5d1
Packit Service eaa5d1
  /* Create the needed directories. */
Packit Service eaa5d1
  xmkdirp ("/var/cache/ldconfig", 0777);
Packit Service eaa5d1
Packit Service af3534
  /* Run ldconfig first to generate the aux-cache.  */
Packit Service af3534
  struct support_capture_subprocess result;
Packit Service af3534
  result = support_capture_subprocess (execv_wrapper, args);
Packit Service af3534
  support_capture_subprocess_check (&result, "execv", 0, sc_allow_none);
Packit Service af3534
  support_capture_subprocess_free (&result);
Packit Service af3534
Packit Service af3534
  xstat (path, &fs);
Packit Service af3534
Packit Service af3534
  size = fs.st_size;
Packit Service af3534
  /* Run 3 tests, each truncating aux-cache shorter and shorter.  */
Packit Service af3534
  for (i = 3; i > 0; i--)
Packit Service eaa5d1
    {
Packit Service af3534
      new_size = size * i / 4;
Packit Service af3534
      if (truncate (path, new_size))
Packit Service af3534
        FAIL_EXIT1 ("truncation failed: %m");
Packit Service af3534
      if (nftw (path, display_info, 1000, 0) == -1)
Packit Service af3534
        FAIL_EXIT1 ("nftw failed.");
Packit Service af3534
Packit Service af3534
      /* Verify that ldconfig can run with a truncated
Packit Service af3534
         aux-cache and doesn't crash.  */
Packit Service af3534
      struct support_capture_subprocess result;
Packit Service af3534
      result = support_capture_subprocess (execv_wrapper, args);
Packit Service af3534
      support_capture_subprocess_check (&result, "execv", 0, sc_allow_none);
Packit Service af3534
      support_capture_subprocess_free (&result);
Packit Service eaa5d1
    }
Packit Service eaa5d1
Packit Service eaa5d1
  free (prog);
Packit Service eaa5d1
  return 0;
Packit Service eaa5d1
}
Packit Service eaa5d1
Packit Service eaa5d1
#include <support/test-driver.c>