Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Linux-UNIX-Programmierung von Jürgen Wolf
Das umfassende Handbuch – 2., aktualisierte und erweiterte Auflage 2006
Buch: Linux-UNIX-Programmierung

Linux-UNIX-Programmierung
1216 S., mit CD, 49,90 Euro
Rheinwerk Computing
ISBN 3-89842-749-8
gp Kapitel A Sicherheit unter Linux
  gp A.1 Viren und Trojaner
  gp A.2 Der Superuser (su)
  gp A.3 Überlaufen von Logfiles
  gp A.4 Zugriffsrechte auf Dateien
  gp A.5 Das SUID-Bit
  gp A.6 Programme ohne Ausführrechte
  gp A.7 Buffer Overflow (Pufferüberlauf)
  gp A.8 Race Condition
  gp A.9 Temporäre Dateien
  gp A.10 chroot
  gp A.11 Umgebungsvariablen
  gp A.12 Zugriffsrechte – häufig gemachte Fehler
  gp A.13 system() und popen()
  gp A.14 Offene Filedeskriptoren
  gp A.15 Core Dump
  gp A.16 SQL Injection
  gp A.17 Filedeskriptor-Überlauf mit select()


Rheinwerk Computing

A.14 Offene Filedeskriptoren  toptop

Wollen Sie sicher gehen, dass beim Start Ihres Programms außer den Standard-Filedeskriptoren stdin, stdout und stderr keine weiteren Filedeskriptoren geöffnet sind, müssen Sie gesonderte Maßnamen treffen. Denn mit jedem offenen Filedeskriptor machen Sie Ihren Rechner anfälliger auf DoS (Denial of Service) Attacken und vermeiden außerdem, dass ein Angreifer einen speziell codierten Filedeskriptor verwendet um bspw. bestimmte Dateien zu verwenden.


Hinweis   Beachten Sie, dass mit dem »Start Ihres Programms« auch die Prozesse gemeint sind, die Sie mittels fork() kreiern. Besonders weil eben die Kindprozesse auch die Filedeskriptoren Ihrer Eltern erben.


Um zunächst zu ermitteln, wie viele Dateien gleichzeitig geöffnet werden können, gibt es unter Linux/UNIX die Funktion getdtablesize(), welche die Anzahl der Dateien zurückgibt, die ein Prozess offen halten darf. getdtablesize() wurde als Bibliotheksfunktion in DLL 4.4.1 implementiert. Die Funktion liefert OPEN_MAX (in Linux 0.99.11 auf 256 gesetzt), falls OPEN_MAX bei Übersetzung per Library definiert war. Andernfalls wird –1 zurückgeliefert und errno wird auf ENOSYS gesetzt. Die Syntax:

#include <unistd. h.>
int getdtablesize(void);

Nachdem Sie ermittelt haben, wie viele Dateien gleichzeitig geöffnet sein dürfen, können Sie alle Filedeskriptoren, außer stdin, stdout und stderr (0, 1, 2), mit close() schließen.

Natürlich sollten Sie auch noch die Standard-Deskriptoren stdin, stdout und stderr überprüfen, ob diese auch wirklich geöffnet sind. Hierzu verwendet man am besten fstat() auf die Deskriptoren. Wird nach dem Funktionsaufruf von fstat() errno auf EBADF gesetzt, so bedeutet dies, dass der Filedeskriptor falsch ist oder nicht vorhanden.

Sofern einer der Standarddeskriptoren also nicht vorhanden bzw. geöffnet ist, sollten Sie diesen zur Sicherheit mit /dev/null öffnen und auch offen lassen. Sollten Sie dies nicht machen, so kann ein Funktionsaufruf wie printf() unerwartete und chaotische Auswirkungen haben. Bspw. verlangen einige Standard-C-Funktionen stderr um eine Fehlerausgabe zu machen (auch wenn diese nur nach /dev/null umgeleitet wird). Schreibt Ihr Programm bspw. Daten in eine Datei und bekommt dabei 2 (=stderr) als Filedeskriptor zugewiesen so wird im Falle eines unerwarteten Fehlers, die Meldung einfach in die Datei geschrieben – weil eben die Standard-C Funktionen die Standard-Filedeskriptoren speziell behandeln.

Hier das Beispiel, womit Sie beim Starten Ihrer Anwendung den Filedeskriptoren Herr werden:

/* safefiledeskriptor.c */
#include <sys/types.h> 
#include <limits.h> 
#include <sys/stat.h> 
#include <stdio.h> 
#include <stdlib.h>
#include <unistd. h.> 
#include <errno.h> 
/* enhält den Pfad zu /dev/null - _PATH_DEVNULL*/
#include <paths.h> 
/* Falls getdtablesize fehlschlägt auf 256 setzen */
#ifndef OPEN_MAX 
#define OPEN_MAX 256 
#endif 
/* Standard-Filedeskriptoren ggf. mit /dev/null öffnen */
static int fd_devnull(int fd) { 
  FILE *fz = NULL; 
  switch(fd) {
     case 0 :  /* Standardeingabe - stdin */
        fz = freopen(_PATH_DEVNULL, "rb", stdin);
        break;
     case 1 :  /* Standardausgabe - stdout */
        fz = freopen(_PATH_DEVNULL, "wb", stdout); 
        break;
     case 2 :  /* Standardfehlerausgabe - stderr */
        fz = freopen(_PATH_DEVNULL, "wb", stderr); 
        break;
     default:
        break;
  }
  return (fz && fileno(fz) == fd);
}
/* Diese Funktion behandelt die Filedeskriptoren */
void safe_descriptor(void) { 
  int         fd, fdsize; 
  struct stat st; 
  
  /* Wieviele Dateien dürften insges. geöffnet sein ... */
  if ((fdsize = getdtablesize( )) == -1)
     fdsize = OPEN_MAX;
  /* Alle Filedeskriptoren bis auf die 
   * Standard-Deskriptoren schließen */
  for (fd = 3;  fd < fdsize;  fd++)
     close(fd); 
  /* Jetzt die Standard-Filedeskriptoren behandeln - mit fstat()
   * überprüfen, ob vorhanden und ungleich EBADF oder Standard-
   * Deskriptor mit /dev/null öffnen. Schlägt alles fehl, 
   * Programm mit abort() beenden, da Fehlerausgabe sinnlos wäre.
   */
  for (fd = 0;  fd < 3;  fd++)
    if (fstat(fd, &st) == -1 && (errno != EBADF || 
        !fd_devnull(fd)))
       abort(); 
}
int main(int argc, char **argv) {
   safe_descriptor();
   return EXIT_SUCCESS;
}
 << zurück
  
  Zum Rheinwerk-Shop
Neuauflage: Linux-UNIX-Programmierung
Neuauflage:
Linux-UNIX-
Programmierung

bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-
 Programmierung


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
Info





Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern