Subject: security/9543: iruserok() mismatches local/remote user
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dave@dtsp.co.nz>
List: netbsd-bugs
Date: 03/04/2000 23:57:35
>Number: 9543
>Category: security
>Synopsis: iruserok() mismatches local/remote user
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: security-officer (NetBSD Security Officer)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Mar 4 23:57:00 2000
>Last-Modified:
>Originator: Dave Sainty
>Organization:
Dynamic Technology Services and Products Ltd (NZ)
>Release: NetBSD-current 20000304
>Environment:
System: NetBSD tequila.dave.dtsp.co.nz 1.4R NetBSD 1.4R (TEQUILA) #3: Wed Feb 16 20:01:31 NZDT 2000 dave@tequila.dave.dtsp.co.nz:/vol/tequila/userB/u2/NetBSD-current/src/sys/arch/i386/compile/TEQUILA i386
>Description:
iruserok() uses iruserok_sa() to implement its check. However, it
switches the local and remote users. If you have compiled a new libc,
but have not recompiled rshd recently, this potentially allows anyone
to become anyone.
The current rshd is not vulnerable, only an older rshd. The change
between 1.17 and 1.18 fixed it (2000/01/31). The library was broken
between 1.36 and 1.37 (2000/01/27). So, anyone compiling a new
library from 2000/01/27 source or later, and not recompiling rshd
since 2000/01/31 sources will have "issues".
>How-To-Repeat:
Try and use rsh and find that the .rhosts rules don't seem to be
followed. ktrace 'rshd' and find that it is reading the .rhosts file
of the CONNECTING user, not the local user!
Look in the source, decide everything looks ok, recompile rshd, find
that it works!
Guess that rshd used to use iruserok() instead of iruserok_sa(), so
the newly compiled version doesn't have the problem (And verify this
with cvs).
>Fix:
This fixes iruserok().
--- lib/libc/net/rcmd.c.orig Sat Mar 4 15:58:39 2000
+++ lib/libc/net/rcmd.c Sun Mar 5 19:40:09 2000
@@ -641,8 +641,8 @@
sin.sin_len = sizeof(struct sockaddr_in);
#endif
memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr));
- return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, luser,
- ruser);
+ return iruserok_sa(&sin, sizeof(struct sockaddr_in), superuser, ruser,
+ luser);
}
/*
>Audit-Trail:
>Unformatted: