Subject: bin/9385: Bug in /usr/bin/Mail conflicts with Hesiod passwd source
To: None <gnats-bugs@gnats.netbsd.org>
From: Geoff Adams <gadams@avernus.com>
List: netbsd-bugs
Date: 02/10/2000 00:24:49
>Number: 9385
>Category: bin
>Synopsis: mail defines a function send() that conflicts with system's send()
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Feb 10 00:24:00 2000
>Last-Modified:
>Originator: Geoff Adams
>Organization:
>Release: 19990210
>Environment:
System: NetBSD heisenberg.avernus.com 1.4P NetBSD 1.4P (HEISENBERG) #0: Tue Dec 7 00:14:40 EST 1999 gadams@heisenberg.avernus.com:/build/netbsd/sys/arch/sparc/compile/HEISENBERG sparc
>Description:
The file usr.bin/mail/send.c defines a function send() (here is its prototype
in usr.bin/mail/extern.h):
int send __P((struct message *, FILE *, struct ignoretab *, char *));
that is used throughout the program. This function overrides the normal
send(2) system call wrapper found in libc. This has been fine, until the
introduction of nsswitch. Now, it's possible to have network sources for
password entries.
If the passwd map in /etc/nsswitch.conf is set to "dns" (and probably
"nis" as well), then as soon as Mail does a lookup of any password entry,
which it does in functions in getname.c while starting up, the Hesiod
lookup routines try to call send(2), but instead end up calling Mail's
send(). The arguments clash horribly, and we end up with a core dump.
>How-To-Repeat:
1. Replace any existing passwd line in /etc/nsswitch.conf with this one:
passwd: dns [notfound=return] files
2. It may be neccessary to have an /etc/hesiod.conf file. If so, try
this one:
rhs=.netbsd.org
lhs=.ns
classes=HS
3. Invoke Mail:
/usr/bin/Mail
4. Observe the core dump.
>Fix:
The following trivial patch against today's source fixes the problem.
Index: cmd1.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/cmd1.c,v
retrieving revision 1.12
diff -c -r1.12 cmd1.c
*** cmd1.c 1999/02/09 04:51:30 1.12
--- cmd1.c 2000/02/10 08:05:05
***************
*** 349,355 ****
dot = mp;
if (value("quiet") == NOSTR)
fprintf(obuf, "Message %d:\n", *ip);
! (void) send(mp, obuf, doign ? ignore : 0, NOSTR);
}
close_pipe:
if (obuf != stdout) {
--- 349,355 ----
dot = mp;
if (value("quiet") == NOSTR)
fprintf(obuf, "Message %d:\n", *ip);
! (void) sendmessage(mp, obuf, doign ? ignore : 0, NOSTR);
}
close_pipe:
if (obuf != stdout) {
Index: cmd2.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/cmd2.c,v
retrieving revision 1.9
diff -c -r1.9 cmd2.c
*** cmd2.c 1998/12/19 16:31:41 1.9
--- cmd2.c 2000/02/10 08:05:08
***************
*** 203,209 ****
for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
mp = &message[*ip - 1];
touch(mp);
! if (send(mp, obuf, ignore, NOSTR) < 0) {
perror(file);
Fclose(obuf);
return(1);
--- 203,209 ----
for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
mp = &message[*ip - 1];
touch(mp);
! if (sendmessage(mp, obuf, ignore, NOSTR) < 0) {
perror(file);
Fclose(obuf);
return(1);
Index: collect.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/collect.c,v
retrieving revision 1.19
diff -c -r1.19 collect.c
*** collect.c 1999/02/17 20:48:48 1.19
--- collect.c 2000/02/10 08:05:11
***************
*** 641,647 ****
touch(mp);
printf(" %d", *msgvec);
! if (send(mp, fp, ig, tabst) < 0) {
perror(tempMail);
return(-1);
}
--- 641,647 ----
touch(mp);
printf(" %d", *msgvec);
! if (sendmessage(mp, fp, ig, tabst) < 0) {
perror(tempMail);
return(-1);
}
Index: extern.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/extern.h,v
retrieving revision 1.10
diff -c -r1.10 extern.h
*** extern.h 1998/10/08 17:36:55 1.10
--- extern.h 2000/02/10 08:05:11
***************
*** 224,230 ****
int schdir __P((void *));
int screensize __P((void));
int scroll __P((void *));
! int send __P((struct message *, FILE *, struct ignoretab *, char *));
int sendmail __P((void *));
int set __P((void *));
int setfile __P((char *));
--- 224,230 ----
int schdir __P((void *));
int screensize __P((void));
int scroll __P((void *));
! int sendmessage __P((struct message *, FILE *, struct ignoretab *, char *));
int sendmail __P((void *));
int set __P((void *));
int setfile __P((char *));
Index: quit.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/quit.c,v
retrieving revision 1.10
diff -c -r1.10 quit.c
*** quit.c 1997/12/07 21:27:10 1.10
--- quit.c 2000/02/10 08:05:13
***************
*** 275,281 ****
}
for (mp = &message[0]; mp < &message[msgCount]; mp++)
if (mp->m_flag & MBOX)
! if (send(mp, obuf, saveignore, NOSTR) < 0) {
perror(mbox);
Fclose(ibuf);
Fclose(obuf);
--- 275,281 ----
}
for (mp = &message[0]; mp < &message[msgCount]; mp++)
if (mp->m_flag & MBOX)
! if (sendmessage(mp, obuf, saveignore, NOSTR) < 0) {
perror(mbox);
Fclose(ibuf);
Fclose(obuf);
***************
*** 404,410 ****
for (mp = &message[0]; mp < &message[msgCount]; mp++)
if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
p++;
! if (send(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) {
perror(mailname);
Fclose(obuf);
return(-1);
--- 404,410 ----
for (mp = &message[0]; mp < &message[msgCount]; mp++)
if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
p++;
! if (sendmessage(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) {
perror(mailname);
Fclose(obuf);
return(-1);
***************
*** 525,531 ****
if ((mp->m_flag & MDELETED) != 0)
continue;
c++;
! if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
perror(mailname);
relsesigs();
reset(0);
--- 525,531 ----
if ((mp->m_flag & MDELETED) != 0)
continue;
c++;
! if (sendmessage(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
perror(mailname);
relsesigs();
reset(0);
Index: send.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/mail/send.c,v
retrieving revision 1.10
diff -c -r1.10 send.c
*** send.c 1998/12/19 16:34:38 1.10
--- send.c 2000/02/10 08:05:14
***************
*** 59,65 ****
* prefix is a string to prepend to each output line.
*/
int
! send(mp, obuf, doign, prefix)
struct message *mp;
FILE *obuf;
struct ignoretab *doign;
--- 59,65 ----
* prefix is a string to prepend to each output line.
*/
int
! sendmessage(mp, obuf, doign, prefix)
struct message *mp;
FILE *obuf;
struct ignoretab *doign;
>Audit-Trail:
>Unformatted: