Schrift
[thread]712[/thread]

flock funktioniert nicht (Seite 6)



<< |< 1 ... 3 4 5 6 7 >| >> 65 Einträge, 7 Seiten
master
 2006-04-19 10:09
#7385 #7385
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
@Dubu..
ja stimmt...

@ptk
- Eigener Benchmark ohne habe einfach die Zeit in
Sekunden genommen
und ca. 50'000 mal geöffnet, geschrieben, geschlossen


@Betterworld

Zu den Benchmarks...

Bei mir kam es auf das selbe raus.. aber du musst dir vorstellen was z.b. O_TURNC macht... es löscht ohne sie wirklich zu löschen die Datei, bzw.

Ich habe daher bei meiner Version des testes syswrite() miteinbezogen und etwas hineingeschrieben....

Das ergebnis war auch erschütternd... auf den ersten blick...
Nun habe ich aber fairer weise $| = 1 gesetzt...

Damit der Print in beim normalen open sich gleich verhält wie beim sysopen.

(sysopen + syswrite) vs. (open + print )
kam das Ergebnis zu Stande, das sysopen + syswrite 30% schneller ist.

Anscheinend wird beim $| = 0; das irgendwie erkannt, und gebuffert gespeichert bzw. nur einmal geschrieben.

0 sekunden für Print ()
6 sekunden für syswrite

Waren da die Ergebnisse.
$| = 1; dann siehts umgekehrt aus.
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
master
 2006-04-19 10:16
#7386 #7386
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
seltsam....

nun wirkt sich das
$| = 1; gar nicht mehr aus..

sobald man print + syswrite einbezieht verhält es sich gleich.
sysopen & co sind schneller... ich wusste es doch ;-)
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use Fcntl;
use FindBin qw($Bin); chdir($Bin);

my $Datei = $Bin.'/a.txt';


$run = 10000;


$t = time;

for(1..$run)
{
sysopen(DATEI, $Datei, O_WRONLY | O_CREAT | O_TURNC) || die "$Datei: $!";
syswrite(DATEI,"TEST");
close(DATEI);
}
$t = time - $t; print "Zeit: $t \n";




$t = time;
for (1..$run)
{
open(DATEI2, ">$Datei" ) || die "$Datei: $!";
print DATEI2 "TEST";
close(DATEI2);
}
$t = time - $t; print "Zeit: $t \n"
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
master
 2006-04-19 10:44
#7387 #7387
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
sysopen, sysseek, syswrite vs. open, seek, print

Folgendes Ergebnis:

Zeit: 34 #sys-methode
Zeit: 40 #normal
----
Syswrite usw.  waren  16 %  schneller


hier der neuste test-code mit grösserem seek-bereich:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use Fcntl;
use FindBin qw($Bin); chdir($Bin);

my $Datei = $Bin.'/a.txt';


$run = 10000;


$t = time;

for(1..$run)
{
    sysopen(DATEI, $Datei, O_WRONLY | O_CREAT | O_TURNC) || die "$Datei: $!";
    sysseek(DATEI, 100000, 0);
    syswrite(DATEI,"TEST");    
   close(DATEI);
}
$t = time - $t; print "Zeit: $t \n";

$t = time;
for (1..$run)
{
    open(DATEI2, ">$Datei" ) || die "$Datei: $!";
    seek(DATEI2, 100000, 0);
    print DATEI2 "TEST";
   close(DATEI2);
}
$t = time - $t; print "Zeit: $t \n";


Resultat:
Zeit: 10   #sys
Zeit: 41  #normal

Nun ist die sys-methode 4 mal schneller als normales open.
besonder fatal wirkt es sich mit seek aus. je höher der seek wert, desto schlechter steht das normale seek usw. da.

Im normal fall wird eine datei ja nicht einfach nur geöffnet.. und gleich wieder geschlossen, sondern es passiert ja noch was damit.

"sysopen" gewinnt also klar gegen "open"
zudem wird durch turncate.. die Datei jedesmal auf 0 Zurückgesetzt.  Ein normales löschen zuvor würde es denke ich noch beschleunigen.

also müsste beim open-beispiel ebenfalls turncate noch mit rein. und dann steht open usw. noch schlechter dar...

ps. gab schon einen Grund warum ich mich für sysopen entschieden habe :-)\n\n

<!--EDIT|master|1145429215-->
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
pq
 2006-04-19 14:50
#7388 #7388
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
[quote=master,19.04.2006, 08:16]
Code: (dl )
    sysopen(DATEI, $Datei, O_WRONLY | O_CREAT | O_TURNC) || die "$Datei: $!";
[/quote]
tja, use strict und warnings ist schon was feines...
mach mal aus dem O_TURNC ein O_TRUNC und miss nochmal. und das bitte
mit dem Benchmark-Modul, denn dafür ist es da. mittels time() zu messen,
und dann auch noch ohne millisekunden, ist steinzeitlich.

muss ich mir für meine nächsten benchmarks merken: einfach ein paar
fehler einbauen, die keiner bemerkt, die mein ergebnis so verfälschen,
wie ich es gern hätte. toll.\n\n

<!--EDIT|pq|1145443936-->
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
master
 2006-04-19 15:04
#7389 #7389
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
ach wie peinlich... "O_TRUNC" ja sorry, hatte es per hand geschrieben... war beim besten willen keine Absicht..

Aber Moment.. setzte die Datei trotzdem zurück *staun*..
Naja versuche es nochmal :-)
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
sid burn
 2006-04-22 22:50
#7390 #7390
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Tag zusammen,
dass open gefolgt von einem flock unsicherer im Gegensatz zu sysopen ist, habe ich ebenfalls gelesen.

Dieses Thema wird auch im Linux Magazin April 2006 http://www.linux-magazin.de/Artikel/ausgabe/2006/04 behandelt.

Dort wurde das Problem auch Live vorgestellt am Programm ridentd.pl. Als erstes war es damit möglich beliebige Dateien als Benutzer mit root Rechten zu löschen.

Das problem war erst das keine Überprüfung auf Symlinks und kein flock Benutzt wurde. Dies wurde dann nachgeholt mit einer vorherigen Überprüfung mit -l etc. und nach dem open Befehl mit einem flock. Trotzdem wird in dem Artikel gezeigt das die Lücke nicht ganz geschlossen ist, mit einem Shell Skript, und einer endlos schleife war man immer noch in er lage beliebige Dateien zu löschen. Die Begründung war die selbe wie master bereits sagte. Es wurde zuerst die Datei auf Symlink überprüft etc. Danach geht die Programmverarbeitung weiter, aber es gibt nunmal keine Garantie das irgendein Prozess genau zwischen den aufruf von open und flock die Datei bearbeitet, oder schon zwischen der Überprüfung auf symlink und open bearbeitet wurde, und auf einmal eine symlink Datei ist.

Das Problem wurde dann letztendlich komplett umgangen mit sysopen, da man dort alle Angaben gleichzeitig ausführt, und sich zwischendurch kein anderer Prozess einmischen kann.

Leider habe ich diese Ausgabe verliehen und kann dazu auch nichts mehr genaueres sagen als das es letztendlich zu einer Sicherheitslücke in ridentd geführt hat, weil open benutzt wurde.

Die genaue Erklärung und die Ausnutzung steht im Linux Magazin April 2006.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
pq
 2006-04-22 23:11
#7391 #7391
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
wenn zwei prozesse flock() benutzen, gibt es kein problem. wenn ein
anderer prozess kein flock() benutzt, ist das natürlich ein problem,
da flock() eben nur einen advisory lock setzt, nicht mandatory.
im CGI-skript des OP reicht es also völlig aus, open()+flock()
zu benutzen. wozu gäbe es die funktion denn, wenn sie völlig unnütz wäre?
um hier im forum für diskussionsstoff zu sorgen?\n\n

<!--EDIT|pq|1145733134-->
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
sid burn
 2006-04-22 23:23
#7392 #7392
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=pq,22.April.2006, 21:11]wenn zwei prozesse flock() benutzen, gibt es kein problem. wenn ein
anderer prozess kein flock() benutzt, ist das natürlich ein problem,
da flock() eben nur einen advisory lock setzt, nicht mandatory.
im CGI-skript des OP reicht es also völlig aus, open()+flock()
zu benutzen. wozu gäbe es die funktion denn, wenn sie völlig unnütz wäre?
um hier im forum für diskussionsstoff zu sorgen?[/quote]
Wofür gibt es den sysopen wenn die Verwendung von open und danach flock das gleiche sein würde?
Open gibt es hauptsächlich da sie einfacher ist, und man eben schnell Skripte schreiben kann. Dafür wurde ja Perl nunmal entwickelt. Ein sysopen ist sicherer, und es gibt sie wenn man halt sicherer Programmieren möchte. Das heißt ja nicht das die eine oder die andere Funktion deswegen unbrauchbar wird.

Das Problem sofern ich mich erinnere lag folgendermaßen:
1. Überprüfung auf Symlink, wenn nein dann
2. Datei öffnen mit >
3. Datei flocken
4. Inhalt schreiben

Das Problem daran:
1. Datei wurde auf Symlink überprüft, alles ist okay.
P1: Ein anderer Prozess macht aus der Datei jetzt ein Symlink auf /boot/vmlinuz
2. Datei wird mit > geöffnet. Mitlerweile ist die Datei jedoch eine Symlink datei auf den Linux Kernel
P1: Hier bin ich mir nicht 100%ig sicher. Da die Datei aber noch nicht geflockt ist, dürfte es hier genauso Möglich sein das ein anderer Prozess aus der Datei ein Symlink auf /boot/vmlinuz zu erzeugt.
3. Datei wird geflockt. Also Linux Kernel wird geflockt.
4. Inhalt wird geschrieben. Da ">" benutzt wird, löschen wir den Linux Kernel.
5. Viel Spaß beim nächsten Reboot.


Mit sysopen würde das nicht passieren. Da man gleichzeitig z.B. auf symlink, datei öffnen, und flocken kann.


Genau darin lag auch das Problem von ridentd.pl. Es wurde auch praktisch gezeigt das man das verhalten so wie ich beschrieben habe, durchaus ausnutzen kann.\n\n

<!--EDIT|sid burn|1145734557-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
pq
 2006-04-22 23:43
#7393 #7393
User since
2003-08-04
12209 Artikel
Admin1
[Homepage]
user image
klar, wenn du eine datei hast, die jemand anderes ausser dir auch
verändern kann, und der andere böses im sinn hat, hast du ein problem.
hat aber nicht unbedingt was mit dem original-problem zu tun,
nämlich mehrere prozesse vom gleichen user.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Dubu
 2006-04-23 00:52
#7394 #7394
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=sid burn,22.04.2006, 21:23]Mit sysopen würde das nicht passieren. Da man gleichzeitig z.B. auf symlink, datei öffnen, und flocken kann.[/quote]
Ich habe das Heft auch nicht zur Hand, aber so, wie du es beschreibst, bestand die Lücke offensichtlich zwischen dem Test auf Symlink und dem open().  Das hat absolut nix mit flock() zu tun. Und nein, sysopen() kann nicht gleichzeitig flock()en!

Wie pq schon sagte, sind Locks ohnehin nur advisory: Wenn ein Programm kein flock() benutzt, dann hat das andere Programm Pech gehabt. Ein flock() kann daher nie vor einem böswilligen Programm schützen.

Aber sysopen() kennt die Optionen O_EXCL und O_CREAT, die zusammen verhindern, dass eine Datei überschrieben wird, wenn sie ein Symlink ist (siehe perldoc -f sysopen). Dieser Kombination wurde wohl in dem Beispiel zur Absicherung vor Symlink-Attacken benutzt.

(Das hilft aber auch nur gegen Symlink-Attacken. Was ist wohl, wenn ich einen Hardlink auf die anzugreifende Datei anlege? Das kann sysopen() nicht erkennen, und meine /boot/vmlinuz ist trotzdem weg. Wenn der Admin /boot auf eine separate Partition legt, nehme ich eben die /etc/passwd oder eine andere kritische Datei.)

Du hast Recht, dass Perls open() existiert, um dem Benutzer eine einfache Möglichkeit zum Lesen und Schreiben von Dateien zu geben. Es ist ja auch einfacher, "open FILE, '>', $dateiname" zu schreiben, als sich die passenden Optionen für sysopen() zu merken. Auch kann man mit open() einfach Umleitungen und Pipes realisieren, wie man es von der Shell kennt (naja, sofern man überhaupt eine Shell kennt).

Deswegen aber hier hartnäckig zu behaupten "open ist unsicher, sysopen ist sicherer", halte ich für Humbug. Und dass ich mir durch ein sysopen() das flock() dahinter sparen könne, ist schlicht falsch.
<< |< 1 ... 3 4 5 6 7 >| >> 65 Einträge, 7 Seiten



View all threads created 2006-04-17 19:11.