bin/102848: Malformed line in master.passwd causes libutil's
pw_copy to crash
Thomas Quinot
thomas at cuivre.fr.eu.org
Mon Sep 4 14:40:26 UTC 2006
>Number: 102848
>Category: bin
>Synopsis: Malformed line in master.passwd causes libutil's pw_copy to crash
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Sep 04 14:40:20 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Thomas Quinot
>Release: FreeBSD 6.1-RC i386
>Organization:
>Environment:
System: FreeBSD melamine.cuivre.fr.eu.org 6.1-RC FreeBSD 6.1-RC #0: Thu May 4 13:21:21 CEST 2006 thomas at melamine.cuivre.fr.eu.org:/space/build/obj/space/build/src/RELENG_6/sys/MELAMINE i386
>Description:
pw_copy is a libutil subprogram that copies master.passwd and replaces
or adds a single entry. It is used, among others, by rpc.yppasswdd, to
update master.passwd for a single user.
When a malformed line is encountered in master.passwd, this function
causes a null pointer dereference instead of silently copying the malformed
line to the output FD. In the case of rpc.yppasswdd, this causes the daemon
to abort if a password change is attempted for an entry located after the
malformed one.
>How-To-Repeat:
Add a malformed entry (wrong number of fields) to master.passwd
on a NIS server.
Use rpc.yppasswdd to attempt to change the password of an entry
located after the faulty one.
Observe that rpc.yppasswdd dies on a segfault and that master.passwd
is left unmodified.
>Fix:
Index: pw_util.c
===================================================================
RCS file: /space/mirror/ncvs/src/lib/libutil/pw_util.c,v
retrieving revision 1.35
diff -u -r1.35 pw_util.c
--- pw_util.c 18 May 2004 15:53:58 -0000 1.35
+++ pw_util.c 4 Sep 2006 10:43:53 -0000
@@ -481,13 +481,22 @@
}
/* is it the one we're looking for? */
+
t = *q;
*q = '\0';
+
fpw = pw_scan(r, PWSCAN_MASTER);
+
+ /*
+ * fpw is either the struct password for the current line,
+ * or NULL if the line is malformed.
+ */
+
*q = t;
- if (strcmp(fpw->pw_name, pw->pw_name) != 0) {
+ if (fpw == NULL || strcmp(fpw->pw_name, pw->pw_name) != 0) {
/* nope */
- free(fpw);
+ if (fpw != NULL)
+ free(fpw);
if (write(tfd, p, q - p + 1) != q - p + 1)
goto err;
++q;
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list