mirror of git://sourceware.org/git/glibc.git
posix: fix glob bugs with long login names
Current glob implementation allows unlimited user name for home directory construction on GLOB_TILDE case. To accomplish it glob either construct a name on stack if size are small enough (based on current alloca_used) or in heap otherwise. This patch simplifies storage allocation by using the same scratch buffer for both get_rlogin_r and getpwnam_r. This also syncs with gnulib commit 064df0b (glob: fix bugs with long login names). Checked on x86_64-linux-gnu and on a build using build-many-glibcs.py for all major architectures. * posix/glob.c (GET_LOGIN_NAME_MAX): Remove. (glob): Use the same scratch buffer for both getlogin_r and getpwnam_r. Don’t require preallocation of the login name. This simplifies storage allocation, and corrects the handling of long login names.
This commit is contained in:
parent
5a79f97554
commit
ffca890177
|
@ -1,5 +1,12 @@
|
||||||
2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
[BZ #1062]
|
||||||
|
* posix/glob.c (GET_LOGIN_NAME_MAX): Remove.
|
||||||
|
(glob): Use the same scratch buffer for both getlogin_r and
|
||||||
|
getpwnam_r. Don’t require preallocation of the login name. This
|
||||||
|
simplifies storage allocation, and corrects the handling of
|
||||||
|
long login names.
|
||||||
|
|
||||||
[BZ #1062]
|
[BZ #1062]
|
||||||
* posix/glob.c (glob): Port recent patches to platforms
|
* posix/glob.c (glob): Port recent patches to platforms
|
||||||
lacking getpwnam_r.
|
lacking getpwnam_r.
|
||||||
|
|
88
posix/glob.c
88
posix/glob.c
|
@ -75,12 +75,6 @@
|
||||||
#include <flexmember.h>
|
#include <flexmember.h>
|
||||||
#include <glob_internal.h>
|
#include <glob_internal.h>
|
||||||
#include <scratch_buffer.h>
|
#include <scratch_buffer.h>
|
||||||
|
|
||||||
#ifdef _SC_LOGIN_NAME_MAX
|
|
||||||
# define GET_LOGIN_NAME_MAX() sysconf (_SC_LOGIN_NAME_MAX)
|
|
||||||
#else
|
|
||||||
# define GET_LOGIN_NAME_MAX() (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
|
static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
|
||||||
|
|
||||||
|
@ -610,67 +604,45 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||||
else
|
else
|
||||||
home_dir = "c:/users/default"; /* poor default */
|
home_dir = "c:/users/default"; /* poor default */
|
||||||
#else
|
#else
|
||||||
int success;
|
int err;
|
||||||
char *name;
|
struct passwd *p;
|
||||||
int malloc_name = 0;
|
struct passwd pwbuf;
|
||||||
size_t buflen = GET_LOGIN_NAME_MAX () + 1;
|
struct scratch_buffer s;
|
||||||
|
scratch_buffer_init (&s);
|
||||||
if (buflen == 0)
|
while (true)
|
||||||
/* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try
|
|
||||||
a moderate value. */
|
|
||||||
buflen = 20;
|
|
||||||
if (glob_use_alloca (alloca_used, buflen))
|
|
||||||
name = alloca_account (buflen, alloca_used);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
name = malloc (buflen);
|
p = NULL;
|
||||||
if (name == NULL)
|
err = __getlogin_r (s.data, s.length);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
# if defined HAVE_GETPWNAM_R || defined _LIBC
|
||||||
|
size_t ssize = strlen (s.data) + 1;
|
||||||
|
err = getpwnam_r (s.data, &pwbuf, s.data + ssize,
|
||||||
|
s.length - ssize, &p);
|
||||||
|
# else
|
||||||
|
p = getpwnam (s.data);
|
||||||
|
if (p == NULL)
|
||||||
|
err = errno;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
if (err != ERANGE)
|
||||||
|
break;
|
||||||
|
if (!scratch_buffer_grow (&s))
|
||||||
{
|
{
|
||||||
retval = GLOB_NOSPACE;
|
retval = GLOB_NOSPACE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
malloc_name = 1;
|
|
||||||
}
|
}
|
||||||
|
if (err == 0)
|
||||||
success = __getlogin_r (name, buflen) == 0;
|
|
||||||
if (success)
|
|
||||||
{
|
{
|
||||||
struct passwd *p;
|
home_dir = strdup (p->pw_dir);
|
||||||
struct scratch_buffer pwtmpbuf;
|
malloc_home_dir = 1;
|
||||||
scratch_buffer_init (&pwtmpbuf);
|
|
||||||
# if defined HAVE_GETPWNAM_R || defined _LIBC
|
|
||||||
struct passwd pwbuf;
|
|
||||||
|
|
||||||
while (getpwnam_r (name, &pwbuf,
|
|
||||||
pwtmpbuf.data, pwtmpbuf.length, &p)
|
|
||||||
== ERANGE)
|
|
||||||
{
|
|
||||||
if (!scratch_buffer_grow (&pwtmpbuf))
|
|
||||||
{
|
|
||||||
retval = GLOB_NOSPACE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
p = getpwnam (name);
|
|
||||||
# endif
|
|
||||||
if (p != NULL)
|
|
||||||
{
|
|
||||||
home_dir = strdup (p->pw_dir);
|
|
||||||
malloc_home_dir = 1;
|
|
||||||
if (home_dir == NULL)
|
|
||||||
{
|
|
||||||
scratch_buffer_free (&pwtmpbuf);
|
|
||||||
retval = GLOB_NOSPACE;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scratch_buffer_free (&pwtmpbuf);
|
|
||||||
}
|
}
|
||||||
else
|
scratch_buffer_free (&s);
|
||||||
|
if (err == 0 && home_dir == NULL)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely (malloc_name))
|
retval = GLOB_NOSPACE;
|
||||||
free (name);
|
goto out;
|
||||||
}
|
}
|
||||||
#endif /* WINDOWS32 */
|
#endif /* WINDOWS32 */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue