mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 14:00:30 +00:00
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>
|
||||
|
||||
[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]
|
||||
* posix/glob.c (glob): Port recent patches to platforms
|
||||
lacking getpwnam_r.
|
||||
|
88
posix/glob.c
88
posix/glob.c
@ -75,12 +75,6 @@
|
||||
#include <flexmember.h>
|
||||
#include <glob_internal.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;
|
||||
|
||||
@ -610,67 +604,45 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
|
||||
else
|
||||
home_dir = "c:/users/default"; /* poor default */
|
||||
#else
|
||||
int success;
|
||||
char *name;
|
||||
int malloc_name = 0;
|
||||
size_t buflen = GET_LOGIN_NAME_MAX () + 1;
|
||||
|
||||
if (buflen == 0)
|
||||
/* '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
|
||||
int err;
|
||||
struct passwd *p;
|
||||
struct passwd pwbuf;
|
||||
struct scratch_buffer s;
|
||||
scratch_buffer_init (&s);
|
||||
while (true)
|
||||
{
|
||||
name = malloc (buflen);
|
||||
if (name == NULL)
|
||||
p = 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;
|
||||
goto out;
|
||||
}
|
||||
malloc_name = 1;
|
||||
}
|
||||
|
||||
success = __getlogin_r (name, buflen) == 0;
|
||||
if (success)
|
||||
if (err == 0)
|
||||
{
|
||||
struct passwd *p;
|
||||
struct scratch_buffer pwtmpbuf;
|
||||
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);
|
||||
home_dir = strdup (p->pw_dir);
|
||||
malloc_home_dir = 1;
|
||||
}
|
||||
else
|
||||
scratch_buffer_free (&s);
|
||||
if (err == 0 && home_dir == NULL)
|
||||
{
|
||||
if (__glibc_unlikely (malloc_name))
|
||||
free (name);
|
||||
retval = GLOB_NOSPACE;
|
||||
goto out;
|
||||
}
|
||||
#endif /* WINDOWS32 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user