On 64-bit platforms such as x86_64, glibc is usally built with 32-bit compatibilty for various structures. One of them is utmp. What this means is that gettimeofday(&ut.ut_tv, NULL) on x86_64 will end up overwriting the first parts of ut_addr_v6, leading to garbage in the utmp file. --- util-linux-2.13-pre6/login-utils/login.c.kzak 2006-08-10 11:38:33.000000000 +0200 +++ util-linux-2.13-pre6/login-utils/login.c 2006-08-10 11:38:49.000000000 +0200 @@ -257,6 +257,7 @@ static void logbtmp(const char *line, const char *username, const char *hostname) { struct utmp ut; + struct timeval tv; memset(&ut, 0, sizeof(ut)); @@ -267,7 +268,9 @@ xstrncpy(ut.ut_line, line, sizeof(ut.ut_line)); #if defined(_HAVE_UT_TV) /* in included by */ - gettimeofday(&ut.ut_tv, NULL); + gettimeofday(&tv, NULL); + ut.ut_tv.tv_sec = tv.tv_sec; + ut.ut_tv.tv_usec = tv.tv_usec; #else { time_t t; @@ -872,6 +875,7 @@ { struct utmp ut; struct utmp *utp; + struct timeval tv; utmpname(_PATH_UTMP); setutent(); @@ -911,7 +915,9 @@ strncpy(ut.ut_user, username, sizeof(ut.ut_user)); xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); #ifdef _HAVE_UT_TV /* in included by */ - gettimeofday(&ut.ut_tv, NULL); + gettimeofday(&tv, NULL); + ut.ut_tv.tv_sec = tv.tv_sec; + ut.ut_tv.tv_usec = tv.tv_usec; #else { time_t t;