Anzeige:
Ergebnis 1 bis 6 von 6

Thema: Problem mit getcwd

  1. #1
    Registrierter Benutzer
    Registriert seit
    05.01.2006
    Beiträge
    44

    Exclamation Problem mit getcwd

    HI Leute,

    habe folgendes Problem.

    Ich möchte das Arbeitsverzeichnis meines Programms auslesen. Ich möchte das alles dynamisch machen, da ich nicht weiß wie lang das Arbeitsverzeichnis sein wird.

    Bis jetzt habe ich folgenden Quellcode:

    Code:
    int i = 3;
    char workingDir[5];
        
    while (1)
    {
        if ( getcwd( workingDir , i ) == NULL ) break;
        i++;
    }
    Aus dieser Website (http://www.informit.com/guides/conte...eqNum=245&rl=1) entnehme ich, dass getcwd NULL zurückgibt, wenn die Größe, die ich an die Funktion übergebe, kleiner ist als der Pfadname.
    Deswegen habe ich die Schleife geschrieben. Mit i++ übergebe ich ständig einen neuen Wert an getcwd. Wenn ich es richtig verstanden habe, erweitert getcwd mit malloc das Array wenn die Größe, die an getcwd übergeben wird, für den Pfadnamen ausreicht.

    Nur funktioniert meine Schleife nicht. Das Array wird nicht erweitert.

    Was mache ich falsch? Ich finde den Fehler nicht.

    Gruß
    Konstantin
    Elektrotechnik Student

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Nein, getcwp, wenn es in der POSIX Variante benutzt wird, hat keinerlei Speicherallokierung.

    D.h. entweder du handhabst das selbst (bleibt portabel), oder du benutzt die linuxspezifische Ausprägung (nicht POSIX kompatibel, geht nur unter Linux) und übergibst NULL als "buf" und 0 als "size"

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    05.01.2006
    Beiträge
    44
    Also ich habe folgenden Quellcode ausprobiert und es funktioniert.

    Code:
    char puffer[0];
        
    getcwd(puffer,90);
        
    printf("%s\n", puffer);
    Gruß
    Konstantin
    Elektrotechnik Student

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Das ist gewagt, ich denke es wäre sinnvoller das spezifizierte Verhalten der Linuxvariante zu benutzen.

    Und free() nicht vergessen

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Das sollte funktionieren (ist aber nicht ansi):
    Code:
    #include <unistd.h>
    
    char path[PATH_MAX] = {0};
    
    getcwd(path,PATH_MAX);
    Eventuell kannst dir aber ein Funktion wie diese schreiben:
    Code:
    #include <unistd.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <limits.h>
    
    #include <stdio.h>
    
    #ifndef PATH_MAX
    #   define PATH_MAX 256
    #endif
    
    char * get_cwd() {
       size_t size = PATH_MAX;
       char * path = NULL;
    
       for(;;) {
          path = malloc(size);
    
          if(path == NULL) {
             break;
          }
    
          if(getcwd(path,size) == NULL) {
             free(path);
             path = NULL;
    
             if(errno == ERANGE) {
                size *= 2;
             }
             else {
                break;
             }
          }
          else {
             break;
          }
       }
    
       return path;
    }
    
    int main() {
    	char * cwd = get_cwd();
    
    	puts(cwd);
    
    	/* free()-en nicht vergessen! */
    	free(cwd);
    
    	return 0;
    }
    Kopier das in eine Datei mit den Namen getcwd.c und es kompeliert mit:
    Code:
    gcc -Wall -pedantic -ansi -O2 -g getcwd.c -o getcwd
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  6. #6
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von KRibel Beitrag anzeigen
    Also ich habe folgenden Quellcode ausprobiert und es funktioniert.

    Code:
    char puffer[0];
        
    getcwd(puffer,90);
        
    printf("%s\n", puffer);
    Gruß
    Konstantin
    Natürlich funktioniert der Code. Es funktionieren auch all die anderen Programme die Pufferüberläufe haben. Trotzdem sind das schwere Sicherheitslücken!! Über diesen Code könnte ein Angreifer Code einschleusen, wenn er einen Ordner anlegen kann, der im Ordnernamen code enthält (unwarscheinlich, weil einige Zeichen nicht gehn, trotzdedm möglich). Auf alle fälle wird bei längeren Ordnernamen dein Programm mit einen Speicherzugriffsfehler (segmentation fault) abstürzen, da falsche Bereiche im Speicher überschreioben werden.

    Wenn du folgendes Programm kompelierst (ohne -Ox, denn optimierungen ändern alles) gibt es dir "hallo" aus:
    Code:
    #include <string.h>
    #include <stdio.h>
    
    int main() {
    	char a = 0;
    	char b = 0;
    	char c = 0;
    	char d = 0;
    	char e = 0;
    	char buf[1] = {0};
    
    	strcpy(buf, "hallo");
    	printf("%c%c%c%c%c%c\n",buf[0],a,b,c,d,e);
    
    	return 0;
    }
    Beängstigend, oder?

    Ohne dem a,b,c,d,e würden Teile deines Stacks überschrieben werden. unter anderen auch die Rücksprungadresse, also wo im Code nach der aktuellen Funktion weitergemacht werden soll. Wenn man die Adresse auf eigenen Code (den man über den selben Fehler einschleust) setzen kann, kann man Code reinschmugeln. Auf die art funktionieren schlimmer Weiße noch immer die meisten Sicherheitslücken. Finde ich schrecklich. C-Puffer zu verwenden sollte verboten werden. Eine Pufferklasse zu implementieren, die die Grenzen überprüft, ist kein so schlimmer overhead. Das sollte einmal gemacht werden und dann nur noch die verwendet werden. Dann gäbs zig Sicherheitslücken nicht mehr.
    Geändert von panzi (22-02-2007 um 00:37 Uhr)
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •