Security

Giorgos Keramidas keramida at ceid.upatras.gr
Sun Dec 5 15:04:34 EET 2004


On 2004-12-05 06:22, William Wallace <vplia at otenet.gr> wrote:
>
> Ara buffer overflow einai afto pou simvainei otan se ena menu zititai
> apo ton xristi enas ari8mos kai aftos (eite katala8os eite
> eksepitides) eisagei ena gramma.

Oxi.  Buffer overflow einai kathe periptosh sthn opoia ena meros tou
programmatos kseperna ta `oria' enos pinaka ston opoio grafei.

Kati pou moiazei me buffer overflow alla den einai:

     1  #include <stdio.h>
     2
     3  static int isum(int *, size_t);
     4
     5  int
     6  main(void)
     7  {
     8          int vec[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     9          int s;
    10
    11          s = isum(vec, 10);
    12          printf("%d\n", s);
    13          return (0);
    14  }
    15
    16  int
    17  isum(int *ip, size_t len)
    18  {
    19          int s;
    20          size_t k;
    21
    22          for (s =0, k = 0; k <= len; k++)
    23                  s += ip[k];
    24  }

Giati auto to programma otan trexei typonei lathos apotelesma?

    gothmog:/tmp/vplia$ ./vplia
    16
    gothmog:/tmp/vplia$

Ayto einai ena paradeigma `off-by-one error', opws tha katalabeis an
koitakseis kala-kala kai prosektika th grammh 22.  O elegxos k <= len
tha prepe na einai k < len.

H timh `len' den epitrepetai na xrhsimopoih8ei ws index sto vec[].
Epitrepetai MONO ws timh kapoiou pointer pou xrhsimopoieitai se
pointer-arithmetic kai mono an to pointer auto de ginei dereference
(etsi leei toulaxiston to standard ths C99).

Edo xrhsimopoieitai o pinakas mono gia diabasma omws.  Otan
xrhsimopoieitai gia grapsimo, tote einai pou arxizoun ta omorfa:

     1  #include <errno.h>
     2  #include <stdio.h>
     3  #include <stdlib.h>
     4  #include <string.h>
     5
     6  static void overflow(char *buf);
     7
     8  int
     9  main(void)
    10  {
    11          char *buf;
    12
    13          if ((buf = malloc(200 * sizeof(char))) == NULL) {
    14                  fprintf(stderr, "%s", strerror(errno));
    15                  exit(1);
    16          }
    17
    18          overflow(buf);
    19          free(buf);
    20          return (0);
    21  }
    22
    23  static void
    24  overflow(char *buf)
    25  {
    26          int k;
    27
    28          for (k = 0; k < 4095; k++)
    29                  buf[k] = ' ';
    30          buf[4096] = '\0';
    31  }

Einai profanes edo giati h overflow() kanei blakeia.

Se alles periptoseis isos na min einai toso profanes omws.  Opws p.x. an
to loop twn grammwn 28-29 ekane th lathos ypothesi oti to buf[] periexei
panta ena valid C string, to opoio termatizei me '\0'.  Tote mporei na
mpei kapoios ston peirasmo na grapsei:

    while (buf && *buf)
	*buf++ = ' ';

Eksakolouthei na mhn yparxei kanenas elegxos oriwn omws, kai sto proto
buffer me 'skoupidia' tha ginei overflow:

    gothmog:/tmp/vplia$ ./vplia
    Segmentation fault (core dumped)
    gothmog:/tmp/vplia$

> Exw lisei to provlima. Den thimamai akrivws, an endiafereste peite mou
> na sas ton pw.

Fobamai pws oxi, den to 'xeis lusei.

> einai kati san
>
> char menu()
> {
>       printf("******************\n");
>       printf("** 1) Hello     **\n");
>       printf("** 2) World     **\n");
>       printf("******************\n");
>       printf("What's your choice?");
>       scanf("%s", &option);
>       return option;
> }

Den yparxei visible identifier me onoma `option' sto menu() opote den
tha kanei kan compile.

To printf() einai buffered output.  Den sou egguatai kaneis oti tha exei
tupothei otidhpote prin treksei h scanf().  Xrhsimopoihse thn fflush().

> int main()
> {
>       char option=menu();
>       int opt;
>       if(*isalfa(option))
>       {
>               opt=atoi(option);
>       }
>       else { }
>       return 0;
> }

1. H atoi() kalytera na apofeugetai, afou den exei eukolo tropo na breis
ek twn ysterwn an ekane lathos sth metatroph, giati to ekane kai pou to
ekane.  Kalytera einai sinithos na xrhsimopoieis thn strtol():

	char *s = "1234567890";
	char *ep;
	long val;
	int result;

	ep = NULL;
	errno = 0;
	val = strtol(s, &ep, 0);
	if (ep != NULL && *ep != '\0') {
		/* Den eftase h metatroph sto telos tou string! */
	} else if (errno != 0) {
		/* Oops!  Kapoia blakeia egine. */
	}
	if (val < INT_MIN || val > INT_MAX)
		/* Timh ektos oriwn. */
	else
		result = (int)val;
	/* Ola kala.  Mporei n timh tou `result' na xrhsimopoih8ei. */

2. H menu() epistrefei char ki esu to ana8eteis ws timh se ena (char *).

3. Einai lathos o tropos pou skeftesai, giati exeis grapsei ton kwdika
pou pairnei eisodo apo ton xrhsth kai ton kwdika pou kanei elegxo
orthothtas ayths ths eisodou se duo polu apomakrusmena shmeia.

Ena pio swsto programma me menu tha htan isws:

     1  #include <stdio.h>
     2
     3  static int menu(void);
     4
     5  int
     6  main(void)
     7  {
     8          int option;
     9
    10          option = menu();
    11          printf("Option %d was selected.\n", option);
    12          return (0);
    13  }
    14
    15  static int
    16  menu(void)
    17  {
    18          int opt;
    19
    20  again:
    21          printf("\n"
    22              "INSTALLATION TYPE\n"
    23              "\n"
    24              "1. CD-ROM install\n"
    25              "2. FTP install\n"
    26              "3. NFS install\n"
    27              "4. No installation, abort\n"
    28              "\n"
    29              ": ");
    30          fflush(stdout);
    31          scanf("%d", &opt);
    32          if (opt < 1 || opt > 4) {
    33                  printf("%d is not a valid installation type\n", opt);
    34                  fflush(stdout);
    35                  goto again;
    36          }
    37          return (opt);
    38  }

H poluplokothta tou menu, ki otidhpote exei sxesh me auto einai ontws
encapsulated mesa sthn menu().  Gi auto o kwdikas ths main() einai toso
aplos kai suntomos:

        1. pare option
        2. typose option
        3. telos

- Giorgos




More information about the Linux-greek-users mailing list