Home | History | Annotate | Download | only in gethostbyname_r
      1 /*
      2  *   Copyright (c) 2015 Fujitsu Ltd.
      3  *   Author: Zeng Linggang <zenglg.jy (at) 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