]>
Commit | Line | Data |
---|---|---|
481c30cb | 1 | /* Test ldconfig does not segfault when aux-cache is corrupted (Bug 18093). |
581c785b | 2 | Copyright (C) 2019-2022 Free Software Foundation, Inc. |
481c30cb AH |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public License as | |
7 | published by the Free Software Foundation; either version 2.1 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
5a82c748 | 17 | not, see <https://www.gnu.org/licenses/>. */ |
481c30cb AH |
18 | |
19 | /* This test does the following: | |
20 | Run ldconfig to create the caches. | |
21 | Corrupt the caches. | |
22 | Run ldconfig again. | |
23 | At each step we verify that ldconfig does not crash. */ | |
24 | ||
25 | #include <stdio.h> | |
26 | #include <stdlib.h> | |
27 | #include <string.h> | |
28 | #include <unistd.h> | |
29 | #include <errno.h> | |
30 | #include <sys/wait.h> | |
31 | #include <ftw.h> | |
32 | #include <stdint.h> | |
33 | ||
a6c1ce77 | 34 | #include <support/capture_subprocess.h> |
481c30cb AH |
35 | #include <support/check.h> |
36 | #include <support/support.h> | |
37 | #include <support/xunistd.h> | |
38 | ||
39 | #include <dirent.h> | |
40 | ||
41 | static int | |
42 | display_info (const char *fpath, const struct stat *sb, | |
43 | int tflag, struct FTW *ftwbuf) | |
44 | { | |
45 | printf ("info: %-3s %2d %7jd %-40s %d %s\n", | |
46 | (tflag == FTW_D) ? "d" : (tflag == FTW_DNR) ? "dnr" : | |
47 | (tflag == FTW_DP) ? "dp" : (tflag == FTW_F) ? "f" : | |
48 | (tflag == FTW_NS) ? "ns" : (tflag == FTW_SL) ? "sl" : | |
49 | (tflag == FTW_SLN) ? "sln" : "???", | |
50 | ftwbuf->level, (intmax_t) sb->st_size, | |
51 | fpath, ftwbuf->base, fpath + ftwbuf->base); | |
52 | /* To tell nftw to continue. */ | |
53 | return 0; | |
54 | } | |
55 | ||
a6c1ce77 AH |
56 | static void |
57 | execv_wrapper (void *args) | |
58 | { | |
59 | char **argv = args; | |
60 | ||
61 | execv (argv[0], argv); | |
62 | FAIL_EXIT1 ("execv: %m"); | |
63 | } | |
64 | ||
481c30cb AH |
65 | /* Run ldconfig with a corrupt aux-cache, in particular we test for size |
66 | truncation that might happen if a previous ldconfig run failed or if | |
67 | there were storage or power issues while we were writing the file. | |
68 | We want ldconfig not to crash, and it should be able to do so by | |
69 | computing the expected size of the file (bug 18093). */ | |
70 | static int | |
71 | do_test (void) | |
72 | { | |
73 | char *prog = xasprintf ("%s/ldconfig", support_install_rootsbindir); | |
a6c1ce77 | 74 | char *args[] = { prog, NULL }; |
481c30cb AH |
75 | const char *path = "/var/cache/ldconfig/aux-cache"; |
76 | struct stat64 fs; | |
77 | long int size, new_size, i; | |
481c30cb AH |
78 | |
79 | /* Create the needed directories. */ | |
80 | xmkdirp ("/var/cache/ldconfig", 0777); | |
81 | ||
a6c1ce77 AH |
82 | /* Run ldconfig first to generate the aux-cache. */ |
83 | struct support_capture_subprocess result; | |
84 | result = support_capture_subprocess (execv_wrapper, args); | |
85 | support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); | |
86 | support_capture_subprocess_free (&result); | |
87 | ||
88 | xstat (path, &fs); | |
89 | ||
90 | size = fs.st_size; | |
91 | /* Run 3 tests, each truncating aux-cache shorter and shorter. */ | |
92 | for (i = 3; i > 0; i--) | |
481c30cb | 93 | { |
a6c1ce77 AH |
94 | new_size = size * i / 4; |
95 | if (truncate (path, new_size)) | |
96 | FAIL_EXIT1 ("truncation failed: %m"); | |
97 | if (nftw (path, display_info, 1000, 0) == -1) | |
98 | FAIL_EXIT1 ("nftw failed."); | |
99 | ||
100 | /* Verify that ldconfig can run with a truncated | |
101 | aux-cache and doesn't crash. */ | |
102 | struct support_capture_subprocess result; | |
103 | result = support_capture_subprocess (execv_wrapper, args); | |
104 | support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); | |
105 | support_capture_subprocess_free (&result); | |
481c30cb AH |
106 | } |
107 | ||
108 | free (prog); | |
109 | return 0; | |
110 | } | |
111 | ||
112 | #include <support/test-driver.c> |