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

endianness fix for pwdb



Erik Troan found a bug in libpwdb that was making it impossible to set
passwords on big-endian machines.  It's "all the world's a VAX" again,
only this time it's the virtually indistinguishable "all the world's an
Intel".

For the benefit of all coders here: when you have a uid_t or gid_t;
which is a 16-bit, short quantity; dropping it in an int, then passing
the address of that int to a function that expects a short is a bad
idea.  Please consider the C type promotion facility something to use
sparingly, and when you pass pointers, be absolutely sure that your
pointer is what you expect.  It *will* come back to haunt you afterwards.

We don't guarantee that this fix will solve every endianness problem
in libpwdb, but it fixes the most immediate problem.  Please be on the
lookout for more, because this particular type of error has the effect
of turning valid short integers into zeros, which have (as you are all
aware) rather special meaning as uid_t and gid_t.

This patch probably only fixes the tip of the iceberg!  I can't stress
that enough!  It is very likely that there are bugs here that will let
people get root access through authentication as a normal user!  I hope
this conveys the seriousness of this problem to everyone on both of
these lists.

Also note that while this fix is against 0.54preC, preD has not fixed
this.

michaelkjohnson

"Magazines all too frequently lead to books and should be regarded by the
 prudent as the heavy petting of literature."            -- Fran Lebowitz


--- libpwdb-0.54preC/libpwdb/pwdb/interface/unix/user.c.endian	Fri May 30 15:25:23 1997
+++ libpwdb-0.54preC/libpwdb/pwdb/interface/unix/user.c	Fri May 30 15:25:50 1997
@@ -109,13 +109,13 @@
         pwdb_entry_user = _pwdb_delete_string(pwdb_entry_user);
         return retval;
     }
-    retval = pwdb_set_entry(*p, "uid", &tid, sizeof(uid_t), NULL, dump_shorts, STRLEN_INT);
+    retval = pwdb_set_entry(*p, "uid", &pwd->pw_uid, sizeof(uid_t), NULL, dump_shorts, STRLEN_INT);
     if (retval != PWDB_SUCCESS) {
         DO_DEBUG;
         pwdb_entry_user = _pwdb_delete_string(pwdb_entry_user);
         return retval;
     }
-    retval = pwdb_set_entry(*p, "gid", &tgid, sizeof(gid_t), NULL, dump_shorts, STRLEN_INT);
+    retval = pwdb_set_entry(*p, "gid", &pwd->pw_gid, sizeof(gid_t), NULL, dump_shorts, STRLEN_INT);
     if (retval != PWDB_SUCCESS) {
         DO_DEBUG;
         pwdb_entry_user = _pwdb_delete_string(pwdb_entry_user);




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