On Sat, Aug 01, 2020 at 08:38:20AM -0600, Alan Post wrote:
> On Sat, Aug 01, 2020 at 01:40:38AM -0500, Emilio Perea wrote:
> > On Fri, Jul 31, 2020 at 11:21:26PM -0600, Alan Post wrote:
> > > remove the -s flag to gcc in conf-ld and recompile. After that run the
> > > below where/backtrace commands again, along with the others below.
> > >
> > *----------------------------------------------------------------------*
> > eperea@diana:~{45} % gdb /bin/checkpassword checkpassword.core
> > GNU gdb 6.3
> > Copyright 2004 Free Software Foundation, Inc.
> > GDB is free software, covered by the GNU General Public License, and you are
> > welcome to change it and/or distribute copies of it under certain conditions.
> > Type "show copying" to see the conditions.
> > There is absolutely no warranty for GDB. Type "show warranty" for details.
> > This GDB was configured as "amd64-unknown-openbsd6.7"...
> > Core was generated by `checkpassword'.
> > Program terminated with signal 11, Segmentation fault.
> > Loaded symbols for /bin/checkpassword
> > Reading symbols from /usr/lib/libc.so.96.0...done.
> > Loaded symbols for /usr/lib/libc.so.96.0
> > Reading symbols from /usr/libexec/ld.so...Error while reading shared library symbols:
> > Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/libexec/ld.so]
> > #0 strcmp () at /usr/src/lib/libc/arch/amd64/string/strcmp.S:59
> > 59 movb (%rdi),%al
> > (gdb) where
> > #0 strcmp () at /usr/src/lib/libc/arch/amd64/string/strcmp.S:59
> > #1 0x00000b0040ee75a3 in main (argc=3, argv=0x7f7ffffc4d18) at checkpassword.c:81
> > Current language: auto; currently asm
> > (gdb) backtrace
> > #0 strcmp () at /usr/src/lib/libc/arch/amd64/string/strcmp.S:59
> > #1 0x00000b0040ee75a3 in main (argc=3, argv=0x7f7ffffc4d18) at checkpassword.c:81
> > (gdb) p encrypted
> > No symbol "encrypted" in current context.
> > (gdb) p stored
> > No symbol "stored" in current context.
> > (gdb)
> > *----------------------------------------------------------------------*
>
> It still looks like there are no debug symbols, plus I made a misake.
> edit conf-cc to replace the -O2 with -g, along with the previous
> change of removing -s from conf-ld. Rebuild checkpassword.
Actually you mentioned earlier to compile with -g so all the dbg runs
have been with conf-cc and all after the first with -s removed from
conf-ld.
> when the crash occurs, you're in strcmp, and need to move up the
> stack frame (with the "up" command) before you can print the value
> of encrypted and stored in the main routine.
Thanks. I'm not at all familiar with gdb. When I was in college the
choice of languages were COBOL and FORTRAN, and as a Physics mayor you
know what I worked with. Picked up a bit of C, but not enough.
> > >
> > > strcmp.S line, 59:
> > >
> > > https://github.com/openbsd/src/blob/master/lib/libc/arch/amd64/string/strcmp.S#L59
> > >
> > > and checkpassword.c line 81:
> > >
> > > https://github.com/TobyGoodwin/checkpassword/blob/master/checkpassword.c#L81
> > >
> > > Neither the crypt call on line 78 nor the strcmp call on line 81 have changed
> > > in OpenBSD 6.7.
> >
> > I saw that after the first gdb run.
> >
> > > With a debug build, type (don't use production data here):
> > >
> > > (gdb) p encrypted
> > > (gdb) p stored
> > >
> > > I wonder if encrypted is NULL and stored is "*"?
> > >
> > > What are the contents of hasspnam.h and hasuserpw.h?
> >
> > They are both empty! And not only those...
> >
> > -rw-r--r-- 1 eperea wheel 0 Aug 1 01:09 crypt.lib
> > -rw-r--r-- 1 eperea wheel 0 Aug 1 01:09 hasspnam.h
> > -rw-r--r-- 1 eperea wheel 0 Aug 1 01:09 hasuserpw.h
> > -rw-r--r-- 1 eperea wheel 0 Aug 1 01:09 s.lib
> > -rw-r--r-- 1 eperea wheel 0 Aug 1 01:09 shadow.lib
>
> Not a surprise, OpenBSD has neither getspnam (tryspnam.c -> hasspnam.h)
> nor getuserpw (tryuserpw.c -> hasuserpw.h)
>
> I believe what's happening is that the call to getpwnam on or about
> line 55 is returning an entry without the hashed password, meaning
> that stored has the value "*" on line 57.
>
> That results in crypt returning a NULL string:
>
> https://github.com/openbsd/src/blob/master/lib/libc/crypt/crypt.c
>
> Which results in strcmp crashing dereferencing it.
>
> The problem isn't the upgrade to OpenBSD 6.7, it's that your previous
> checkpassword had it's setuid bit set, and your new one does not.
The checkpassword in another server running OpenBSD 6.6 (i386) is not
setuid, but have not tested it in quite a while. This one may well have
been setuid. I just changed it, so it is now.
> If you make checkpassword setuid, the pw_passwd field will return
> the hashed password instead of "*" and the crypt call will then invoke
> bcrypt returning a non-NULL value that is assigned to encrypted, resulting
> in strcmp returning the result of the comparison rather than segfaulting.
>
> Is that what happens?
With the recompiled and setuid checkpassword, DJB's test using
qmail-popup does not crash, but get '-ERR authorization failed" whether
the password is right or wrong. However, trying to retrieve mail using
one of the usual clients does cause it to crash.
Anyhow, this is the latest:
*----------------------------------------------------------------------*
eperea@diana:~{12} % gdb /bin/checkpassword checkpassword.core
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "amd64-unknown-openbsd6.7"...
Core was generated by `checkpassword'.
Program terminated with signal 11, Segmentation fault.
Loaded symbols for /bin/checkpassword
Reading symbols from /usr/lib/libc.so.96.0...done.
Loaded symbols for /usr/lib/libc.so.96.0
Reading symbols from /usr/libexec/ld.so...Error while reading shared library symbols:
Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /usr/libexec/ld.so]
#0 strcmp () at /usr/src/lib/libc/arch/amd64/string/strcmp.S:59
59 movb (%rdi),%al
(gdb) up
#1 0x00000d668b9bd5a3 in main (argc=3, argv=0x7f7ffffd0ac8) at checkpassword.c:81
81 if (!*stored || strcmp(encrypted,stored)) _exit(1);
(gdb) p encrypted
$1 = 0x0
(gdb) p stored
$2 = 0xd68d960c073 "*"
(gdb)
*----------------------------------------------------------------------*
Whatever the result, I'm really grateful for all your help!