Hallo pl,

strstr() ist deutlich schneller als bstrstr() und solange es sich um nullterminierte Strings handelt wie die boundary in der 1. Zeile ist strstr() völlig korrekt eingesetzt.

unsigned char *mem; mem = (char*)malloc(content_length); fread(mem,content_length,1,stdin);

Du liest content_length bytes aus stdin in den Buffer mem. Dieser Buffer ist nicht mit einem 0-Byte terminiert.

unsigned char *offs; // Wanderzeiger Offset int blen = 0; // Boundary Length char *boundary; if( offs = strstr(mem, "\r\n")){

Du rufst strtr() mit mem als Such-Buffer auf. strstr() sucht nach der gewünschten Zeichenfolge im Suchbuffer bis die Zeichenfolge gefunden wurde oder bis das terminierende 0-Byte gefunden wurde.

Du hast kein terminierendes 0-Byte, sondern höchstens zufällig eins im Payload. Wenn also kein "\r\n" gefunden wird, hast du einen out-of-bounds read.

Das gleiche gilt für spätere strstr()-Calls mit offs als Suchbuffer:

if( h = strstr(offs, "\r\n\r\n") ){

Außerdem hast du vermutlich noch einen zweiten Bug:

bstrstr(offs, content_length, boundary, blen)

Ich kenne die Implementation von bstrstr() nicht, aber das zweite Argument wird vermutlich die Länge des Suchbuffers angeben. Du gibst hier content_length an, das ist aber falsch: offs zeigt nicht auf das erste Byte des Buffers, sondern auf ein Byte irgendwo mitten drin. Du hast also nicht mehr content_length als Länge, sondern content_length - (offs - mem).

Außerdem ist deine Befüllung von pnew buggy.

hlen = h - offs; header = (char*)malloc(hlen); memcpy(header,offs,hlen); offs = h;

Du kopierst den Header in einen Buffer, mit memcpy(). Der Header-String ist also nicht 0-terminiert.

if( h = strstr(header,"Content-Type") ){

Du lässt strstr() auf einen nicht-0-terminierten Buffer los. Wenn also kein "Content-Type" gefunden werden konnte, hast du einen out-of-bounds read.

pnew->content_type = (char*)malloc(hlen); sprintf(pnew->content_type,"%s",h+14);

Du allozierst hlen Bytes für pnew->content_type. Du terminierst aber an Byte hlen+1:

pnew->content_type[hlen] = 0;

Das ist ein out-of-bounds write, du musst hlen+1 Bytes allozieren. Aber eigentlich kannst du das manuelle terminieren auch weglassen, denn das macht dein sprintf()-Call bereits. pnew->filename und pnew->name terminierst du ja auch nicht manuell.

h = strstr(header,"name"); for(int i = 0; i < hlen; i++){ if(h[i] == 34) h[i] = 0; }

Rückgabewert prüfen! Was, wenn strstr() kein name im Suchbuffer finden kann? Dann arbeitest du mit NULL.

pnew->value = (char*)malloc(vlen); memcpy(pnew->value,offs,vlen); pnew->value[vlen] = 0;

Hier das gleiche. Du allozierst vlen Bytes, schreibst aber an Byte vlen+1.

pnew->next = NULL; while( *par != NULL ){ par = &(*par)->next; } *par = pnew;

Das kann ich nicht überprüfen, weil mir die Definitionen fehlen und die Info, was par ist. Aber es lässt meine Spinnensinne klingeln…

LG,
CK

-- https://wwwtech.de/about

Folgende Nachrichten verweisen auf diesen Beitrag:

freiwillige Angabe, für jeden sichtbar
freiwillige Angabe, für jeden sichtbar
freiwillige Angabe, für jeden sichtbar

Vorschau (Nachricht wird im Forum „SELF-Forum“ erscheinen)

  • Keine Tag-Vorschläge verfügbar
  • keine Tags vergeben

abbrechen

068

c binary mode für stdin

  1. 0
    1. 0
    2. 0
      1. 0
        1. 0
          1. 0
        2. 0
          1. 0
            1. 0
              1. 0
                1. 0
      2. 0

        multipart/form-data

        1. 0
          1. 0
            1. 0
            2. 0
              1. 0
                1. 0
        2. 0
        3. 0
          1. 0
            1. 0
              1. 0
          2. 0
            1. 0
              1. 0
              2. 0
                1. 0
                  1. 0
                2. 0
                  1. 0
                    1. 0
                      1. 0
                        1. 0
                          1. -1
                            1. 0
                        2. 0
                3. 2
                  1. 0
                  2. 0
                  3. 0
                    1. 0
                      1. 0
                        1. 0
                        2. 2
                          1. 1
                            1. 0
                    2. 0
                      1. 0
                4. 0
  2. 0

    C Upload goßer Datenmengen

    1. 0
      1. 0
        1. 0
          1. 0
            1. 0
              1. 0
              2. 0

                Bug in PHP PHP/5.3.0 Upload

                1. 0
                  1. 0
                    1. 0
                      1. 0
                        1. 0
            2. 0
            3. 0
    2. 2
      1. 4