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 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 60 static void setup(void) 61 { 62 tst_sig(NOFORK, DEF_HANDLER, NULL); 63 TEST_PAUSE; 64 } 65 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