Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jul 2018 22:13:22 -0700
From:      Cy Schubert <Cy.Schubert@cschubert.com>
To:        Ian Lepore <ian@FreeBSD.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r336619 - head/lib/libc/gen
Message-ID:  <201807230513.w6N5DM8u049113@slippy.cwsent.com>
In-Reply-To: Message from Ian Lepore <ian@FreeBSD.org> of "Sun, 22 Jul 2018 22:34:20 -0000." <201807222234.w6MMYKpn030237@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
In message <201807222234.w6MMYKpn030237@repo.freebsd.org>, Ian Lepore 
writes:
> Author: ian
> Date: Sun Jul 22 22:34:20 2018
> New Revision: 336619
> URL: https://svnweb.freebsd.org/changeset/base/336619
>
> Log:
>   Set the pw_class field to NULL when scanning the non-master passwd file.
>   This avoids a null pointer deref in pw_dup(), which assumes that all
>   pointers are either NULL or valid.
>
> Modified:
>   head/lib/libc/gen/pw_scan.c
>
> Modified: head/lib/libc/gen/pw_scan.c
> =============================================================================
> =
> --- head/lib/libc/gen/pw_scan.c	Sun Jul 22 21:39:27 2018	(r33661
> 8)
> +++ head/lib/libc/gen/pw_scan.c	Sun Jul 22 22:34:20 2018	(r33661
> 9)
> @@ -170,7 +170,8 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
>  		if (p[0])
>  			pw->pw_fields |= _PWF_EXPIRE;
>  		pw->pw_expire = atol(p);
> -	}
> +	} else
> +		pw->pw_class = NULL;
>  	if (!(pw->pw_gecos = strsep(&bp, ":")))		/* gecos */
>  		goto fmt;
>  	if (pw->pw_gecos[0])
>

Hi Ian,

This causes ssh a bit of gas.

slippy$ gdb ssh
GNU gdb (GDB) 8.1 [GDB v8.1 for FreeBSD]
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.
html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show 
copying"
and "show warranty" for details.
This GDB was configured as "x86_64-portbld-freebsd12.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ssh...Reading symbols from /usr/lib/debug//usr/bin/
ssh.debug...done.
done.
(gdb) set args bob id
(gdb) run
Starting program: /usr/bin/ssh bob id

Program received signal SIGSEGV, Segmentation fault.
strlen (str=0x0) at /opt/src/svn-current/lib/libc/string/strlen.c:101
101		va = (*lp - mask01);
(gdb) bt
#0  strlen (str=0x0) at /opt/src/svn-current/lib/libc/string/strlen.c:10
1
#1  0x000000002bf10462 in Fssh_xstrdup (str=0x0)
    at /opt/src/svn-current/crypto/openssh/xmalloc.c:98
#2  0x000000002bf0ce38 in Fssh_pwcopy (pw=0x2c5962d0)
    at /opt/src/svn-current/crypto/openssh/misc.c:302
#3  0x0000000000214391 in main (ac=3, av=0x7fffffffe648)
    at /opt/src/svn-current/crypto/openssh/ssh.c:633
(gdb) l
96		 * p and (p & ~LONGPTR_MASK) must be equally accessible since
97		 * they always fall in the same memory page, as long as page
98		 * boundaries is integral multiple of word size.
99		 */
100		lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK);
101		va = (*lp - mask01);
102		vb = ((~*lp) & mask80);
103		lp++;
104		if (va & vb)
105			/* Check if we have \0 in the first part */
(gdb) p lp
$1 = (const unsigned long *) 0x0
(gdb) up
#1  0x000000002bf10462 in Fssh_xstrdup (str=0x0)
    at /opt/src/svn-current/crypto/openssh/xmalloc.c:98
98		len = strlen(str) + 1;
(gdb) l
93	xstrdup(const char *str)
94	{
95		size_t len;
96		char *cp;
97	
98		len = strlen(str) + 1;
99		cp = xmalloc(len);
100		strlcpy(cp, str, len);
101		return cp;
102	}
(gdb) p str
$2 = 0x0
(gdb) up 
#2  0x000000002bf0ce38 in Fssh_pwcopy (pw=0x2c5962d0)
    at /opt/src/svn-current/crypto/openssh/misc.c:302
302		copy->pw_class = xstrdup(pw->pw_class);
(gdb) l
297	#endif
298	#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
299		copy->pw_change = pw->pw_change;
300	#endif
301	#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
302		copy->pw_class = xstrdup(pw->pw_class);
303	#endif
304		copy->pw_dir = xstrdup(pw->pw_dir);
305		copy->pw_shell = xstrdup(pw->pw_shell);
306		return copy;
(gdb) p pw->pw_class
$3 = 0x0
(gdb) 

(If anyone's wondering, I name my systems after dead pets.)


-- 
Cheers,
Cy Schubert <Cy.Schubert@cschubert.com>
FreeBSD UNIX:  <cy@FreeBSD.org>   Web:  http://www.FreeBSD.org

	The need of the many outweighs the greed of the few.





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