[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

pam_unix doesn't fsync the tmp passwd file before overwriting /etc/passwd



Recenty there is much rumor in Internet because of some cases of data
loss caused by the filesystem ext4 in case of a crash. Theodore T'so who
wrote the filesystem maintains that is is mainly responsibility of
application and system programmers that do not call properly fsync on
the files. A sequence like fopen fputs fclose rename it is unsafe because the 
rename could potentially overwrite a good file with one that it wasn't
wrtitten to the disk yet.
Since some bug report on Ubuntu say that the file /etc/passwd
and /etc/shadow where lost (0 length) because the computer crashed just
after changing a password I decided to give a look to the sources to see
if T'so was right and in fact in modules/pam_unix/passverify.c fsync is
never called before closing the file. A small patch like the one
appended certainly will not hurt and it is more correct formally. Always
more systems are using delayed allocation and the problem will became
more common. 


-https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/317781/comments/54
-http://thunk.org/tytso/blog/2009/03/12/delayed-allocation-and-the-zero-length-file-problem/
-http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/


diff -r -u Linux-PAM-1.0.4/modules/pam_unix/passverify.c
Linux-PAM-1.0.4.new/modules/pam_unix/passverify.c
--- Linux-PAM-1.0.4/modules/pam_unix/passverify.c	2009-03-02
16:02:22.000000000 +0100
+++ Linux-PAM-1.0.4.new/modules/pam_unix/passverify.c	2009-03-16
22:25:20.794367897 +0100
@@ -675,11 +675,10 @@
 	}
     }
 
-    if (fclose(pwfile)) {
+    if (fsync(pwfile)||fclose(pwfile)) {
 	D(("error writing entries to old passwords file: %m"));
 	err = 1;
     }
-
 done:
     if (!err) {
 	if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE))
@@ -795,7 +794,7 @@
     }
     fclose(opwfile);
 
-    if (fclose(pwfile)) {
+    if (fsync(pwfile)||fclose(pwfile)) {
 	D(("error writing entries to password file: %m"));
 	err = 1;
     }
@@ -925,7 +924,7 @@
     }
     fclose(opwfile);
 
-    if (fclose(pwfile)) {
+    if (fsync(pwfile)||fclose(pwfile)) {
 	D(("error writing entries to shadow file: %m"));
 	err = 1;
     }


Chiacchiera con i tuoi amici in tempo reale! 
 http://it.yahoo.com/mail_it/foot/*http://it.messenger.yahoo.com 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]