1 /*
2 * Copyright (c) 2015 Fujitsu Ltd.
3 * Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program 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
13 * the GNU General Public License for more details.
14 */
15
16 /*
17 * This is a test for glibc bug:
18 * https://www.qualys.com/research/security-advisories/GHOST-CVE-2015-0235.txt
19 */
20
21 #include <netdb.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include "test.h"
27
28 #define CANARY "in_the_coal_mine"
29
30 static void setup(void);
31 static void check_vulnerable(void);
32
33 static struct {
34 char buffer[1024];
35 char canary[sizeof(CANARY)];
36 } temp = {
37 "buffer",
38 CANARY,
39 };
40
41 char *TCID = "gethostbyname_r01";
42 int TST_TOTAL = 1;
43
main(int ac,char ** av)44 int main(int ac, char **av)
45 {
46 int lc;
47
48 tst_parse_opts(ac, av, NULL, NULL);
49
50 setup();
51
52 for (lc = 0; TEST_LOOPING(lc); lc++) {
53 tst_count = 0;
54 check_vulnerable();
55 }
56
57 tst_exit();
58 }
59
setup(void)60 static void setup(void)
61 {
62 tst_sig(NOFORK, DEF_HANDLER, NULL);
63 TEST_PAUSE;
64 }
65
check_vulnerable(void)66 static void check_vulnerable(void)
67 {
68 struct hostent resbuf;
69 struct hostent *result;
70 int herrno;
71 int retval;
72 char name[sizeof(temp.buffer)];
73 size_t len;
74
75 /*
76 * <glibc>/nss/digits_dots.c:
77 * strlen(name) = size_needed - sizeof(*host_addr) -
78 * sizeof(*h_addr_ptrs) - 1;
79 */
80 len = sizeof(temp.buffer) - 16 - 2 * sizeof(char *) - 1;
81 memset(name, '0', len);
82 name[len] = '\0';
83
84 retval = gethostbyname_r(name, &resbuf, temp.buffer,
85 sizeof(temp.buffer), &result, &herrno);
86
87 if (strcmp(temp.canary, CANARY) != 0) {
88 tst_resm(TFAIL, "vulnerable");
89 return;
90 }
91
92 if (retval == ERANGE) {
93 tst_resm(TPASS, "not vulnerable");
94 return;
95 }
96
97 tst_resm(TFAIL, "gethostbyname_r() returned %s, expected ERANGE",
98 tst_strerrno(retval));
99 }
100