Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Jun 2012 02:02:24 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Guy Helmer <ghelmer@palisadesystems.com>
Cc:        svn-src-stable@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   Re: svn commit: r237106 - stable/9/lib/libc/gen
Message-ID:  <20120615230224.GI2337@deviant.kiev.zoral.com.ua>
In-Reply-To: <880C698D-7620-48CB-B0EB-68BBC7FECDBB@palisadesystems.com>
References:  <201206142148.q5ELmFul023002@svn.freebsd.org> <20120615212651.GH2337@deviant.kiev.zoral.com.ua> <880C698D-7620-48CB-B0EB-68BBC7FECDBB@palisadesystems.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--OtZJUqNUNrB9XA/T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Jun 15, 2012 at 05:33:27PM -0500, Guy Helmer wrote:
>=20
> On Jun 15, 2012, at 4:26 PM, Konstantin Belousov wrote:
>=20
> > On Thu, Jun 14, 2012 at 09:48:15PM +0000, Guy Helmer wrote:
> >> Author: ghelmer
> >> Date: Thu Jun 14 21:48:14 2012
> >> New Revision: 237106
> >> URL: http://svn.freebsd.org/changeset/base/237106
> >>=20
> >> Log:
> >>  MFC 235739-235740,236402:
> >>  Apply style(9) to return and switch/case statements.
> >>=20
> >>  Add checks for memory allocation failures in appropriate places, and
> >>  avoid creating bad entries in the grp list as a result of memory allo=
cation
> >>  failures while building new entries.
> >>=20
> >>  Style(9) improvements: remove unnecessary parenthesis, improve order
> >>  of local variable declarations, remove bogus casts, and resolve long
> >>  lines.
> >>=20
> >>  PR:		bin/83340
> >>=20
> >> Modified:
> >>  stable/9/lib/libc/gen/getnetgrent.c
> >> Directory Properties:
> >>  stable/9/lib/libc/   (props changed)
> >>=20
> > This broke mountd(8) for me. It dies with SIGSEGV on start. Autopsy has
> > shown that this happen due to free(3) on an unallocated pointer.
> >=20
> > I have two netgroups in my /etc/netgroup:
> > testboxes (solo.home, , ) (x.home, , ) (nv.home, , ) (sandy.home, , ) (=
tom.home, ,)
> > laptops (alf.home, , ) (alf.home-air, , ) (sirion.home, , ) (sirion.hom=
e-air, , )
> >=20
> > The http://people.freebsd.org/~kib/misc/netgr.c shows the issue. Run it
> > as "netgr testboxes laptops".
> >=20
> > Your change below makes lp->l_lines pointer for already processed groups
> > invalid because you reallocf(3) the memory pointed by it. Then
> > 1. accessing the l_lines later causes undefined behaviour;
> > 2. free(3) call in endnetgrent() dies because pointer is dandling.
> >=20
> >> @@ -595,15 +615,15 @@ read_for_group(const char *group)
> >> 				} else
> >> 					cont =3D 0;
> >> 				if (len > 0) {
> >> -					linep =3D (char *)malloc(olen + len + 1);
> >> -					if (olen > 0) {
> >> -						bcopy(olinep, linep, olen);
> >> -						free(olinep);
> >> +					linep =3D reallocf(linep, olen + len + 1);
> >> +					if (linep =3D=3D NULL) {
> >> +						free(lp->l_groupname);
> >> +						free(lp);
> >> +						return (NULL);
> >> 					}
> >> 					bcopy(pos, linep + olen, len);
> >> 					olen +=3D len;
> >> 					*(linep + olen) =3D '\0';
> >> -					olinep =3D linep;
> >> 				}
> >> 				if (cont) {
> >> 					if (fgets(line, LINSIZ, netf)) {
> >=20
> > Below is partial revert of your changes that cures mountd for me. Also,
> > the second patch does some further cleanup of the getnetgrent.c.
> >=20
> > Do you agree ?
>=20
> Sorry for the breakage. FWIW, I am having difficulty seeing how:
>=20
> 					linep =3D malloc(olen + len + 1);
> 					?
> 					if (olen > 0) {
> 						bcopy(olinep, linep, olen);
> 						free(olinep);
> 					}
>=20
> is different from:
>=20
> 					linep =3D reallocf(linep, olen + len + 1);
>=20
The old value of linep is invalid after the call to reallocf() and
must be not used further. But it is saved as l_line value, so it gets
free()d. You de-facto use very long line, containing lines for all
groups, with l_line pointing in the middle of it. It is some luck that
in my case reallocf() was able to extend original chunk, otherwise I
would also get garbage in l_lines.

>=20
> but if it fixes the issue, it is good. I would beware the disorder in the=
 sorting of the variables in the line:
>=20
> 	char *pos, *spos, *linep, *olinep;".
Fixed.

--OtZJUqNUNrB9XA/T
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAk/bvwAACgkQC3+MBN1Mb4hrHwCfZuxLndQKUvjGXpuROMnTrxlg
9AoAn3Q7rGBlwe6Xkpk9hhancGAtFP4R
=JoUY
-----END PGP SIGNATURE-----

--OtZJUqNUNrB9XA/T--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120615230224.GI2337>