* grp.cc (pwdgrp::parse_group): Set grp.len. Drop generating any

gr_mem entries.
	(getgrgid_r): Don't try to copy gr_mem entries.  Always set gr_mem
	to an empty list.
	(getgrnam_r): Ditto.
	(app_gr): New static struct to store group data propagated to the
	calling application via getgrgid/getgrnam.
	(getgr_cp): Fill app_gr and return pointer to app_gr.g.
	(getgrgid32): Call getgr_cp.
	(getgrnam32): Ditto.
	* passwd.cc (pwdgrp::parse_passwd): Set res.len.
	(app_pw): New static struct to store passwd data propagated to the
	calling application via getpwuid/getpwnam.
	(getpw_cp): Fill app_pw and return pointer to app_pw.p.
	(getpwuid32): Cal getpw_cp.
	(getpwnam): Ditto.
	* pwdgrp.h (struct pg_pwd): Add len member.
	(struct pg_grp): Ditto.
This commit is contained in:
Corinna Vinschen 2014-05-07 11:00:00 +00:00
parent fc3a3524b2
commit 20de26ebf9
4 changed files with 110 additions and 36 deletions

View File

@ -1,3 +1,24 @@
2014-05-07 Corinna Vinschen <corinna@vinschen.de>
* grp.cc (pwdgrp::parse_group): Set grp.len. Drop generating any
gr_mem entries.
(getgrgid_r): Don't try to copy gr_mem entries. Always set gr_mem
to an empty list.
(getgrnam_r): Ditto.
(app_gr): New static struct to store group data propagated to the
calling application via getgrgid/getgrnam.
(getgr_cp): Fill app_gr and return pointer to app_gr.g.
(getgrgid32): Call getgr_cp.
(getgrnam32): Ditto.
* passwd.cc (pwdgrp::parse_passwd): Set res.len.
(app_pw): New static struct to store passwd data propagated to the
calling application via getpwuid/getpwnam.
(getpw_cp): Fill app_pw and return pointer to app_pw.p.
(getpwuid32): Cal getpw_cp.
(getpwnam): Ditto.
* pwdgrp.h (struct pg_pwd): Add len member.
(struct pg_grp): Ditto.
2014-05-06 Corinna Vinschen <corinna@vinschen.de>
* security.h (MAX_SUBAUTH_CNT): Drop. Use SID_MAX_SUB_AUTHORITIES

View File

@ -38,23 +38,14 @@ pwdgrp::parse_group ()
if (!*grp.g.gr_name)
return false;
grp.g.gr_passwd = next_str (':');
/* Note that lptr points to the first byte of the gr_gid field.
We deliberately ignore the gr_gid and gr_mem entries when copying
the buffer content since they are not referenced anymore. */
grp.len = lptr - grp.g.gr_name;
if (!next_num (grp.g.gr_gid))
return false;
int n;
char *dp = raw_ptr ();
for (n = 0; *next_str (','); n++)
continue;
/* Don't generate gr_mem entries. */
grp.g.gr_mem = &null_ptr;
if (n)
{
char **namearray = (char **) ccalloc (HEAP_BUF, n + 1, sizeof (char *));
if (namearray)
{
for (int i = 0; i < n; i++, dp = strchr (dp, '\0') + 1)
namearray[i] = dp;
grp.g.gr_mem = namearray;
}
}
grp.sid.getfromgr (&grp.g);
return true;
}
@ -228,32 +219,60 @@ getgrgid_r (gid_t gid, struct group *grp, char *buffer, size_t bufsize,
if (!tempgr)
return 0;
/* check needed buffer size. */
int i;
/* Check needed buffer size. Deliberately ignore gr_mem. */
size_t needsize = strlen (tempgr->gr_name) + strlen (tempgr->gr_passwd)
+ 2 + sizeof (char *);
for (i = 0; tempgr->gr_mem[i]; ++i)
needsize += strlen (tempgr->gr_mem[i]) + 1 + sizeof (char *);
if (needsize > bufsize)
return ERANGE;
/* make a copy of tempgr */
/* Make a copy of tempgr. Deliberately ignore gr_mem. */
*result = grp;
grp->gr_gid = tempgr->gr_gid;
buffer = stpcpy (grp->gr_name = buffer, tempgr->gr_name);
buffer = stpcpy (grp->gr_passwd = buffer + 1, tempgr->gr_passwd);
grp->gr_mem = (char **) (buffer + 1);
buffer = (char *) grp->gr_mem + (i + 1) * sizeof (char *);
for (i = 0; tempgr->gr_mem[i]; ++i)
buffer = stpcpy (grp->gr_mem[i] = buffer, tempgr->gr_mem[i]) + 1;
grp->gr_mem[i] = NULL;
grp->gr_mem[0] = NULL;
return 0;
}
/* getgrgid/getgrnam are not reentrant. */
static struct {
struct group g;
char *buf;
size_t bufsiz;
} app_gr;
static struct group *
getgr_cp (struct group *tempgr)
{
if (!tempgr)
return NULL;
pg_grp *gr = (pg_grp *) tempgr;
if (app_gr.bufsiz < gr->len)
{
char *newbuf = (char *) realloc (app_gr.buf, gr->len);
if (!newbuf)
{
set_errno (ENOMEM);
return NULL;
}
app_gr.buf = newbuf;
app_gr.bufsiz = gr->len;
}
memcpy (app_gr.buf, gr->g.gr_name, gr->len);
memcpy (&app_gr.g, &gr->g, sizeof gr->g);
ptrdiff_t diff = app_gr.buf - gr->g.gr_name;
app_gr.g.gr_name += diff;
app_gr.g.gr_passwd += diff;
return &app_gr.g;
}
extern "C" struct group *
getgrgid32 (gid_t gid)
{
return internal_getgrgid (gid);
struct group *tempgr = internal_getgrgid (gid);
pthread_testcancel ();
return getgr_cp (tempgr);
}
#ifdef __x86_64__
@ -282,32 +301,28 @@ getgrnam_r (const char *nam, struct group *grp, char *buffer,
if (!tempgr)
return 0;
/* check needed buffer size. */
int i;
/* Check needed buffer size. Deliberately ignore gr_mem. */
size_t needsize = strlen (tempgr->gr_name) + strlen (tempgr->gr_passwd)
+ 2 + sizeof (char *);
for (i = 0; tempgr->gr_mem[i]; ++i)
needsize += strlen (tempgr->gr_mem[i]) + 1 + sizeof (char *);
if (needsize > bufsize)
return ERANGE;
/* make a copy of tempgr */
/* Make a copy of tempgr. Deliberately ignore gr_mem. */
*result = grp;
grp->gr_gid = tempgr->gr_gid;
buffer = stpcpy (grp->gr_name = buffer, tempgr->gr_name);
buffer = stpcpy (grp->gr_passwd = buffer + 1, tempgr->gr_passwd);
grp->gr_mem = (char **) (buffer + 1);
buffer = (char *) grp->gr_mem + (i + 1) * sizeof (char *);
for (i = 0; tempgr->gr_mem[i]; ++i)
buffer = stpcpy (grp->gr_mem[i] = buffer, tempgr->gr_mem[i]) + 1;
grp->gr_mem[i] = NULL;
grp->gr_mem[0] = NULL;
return 0;
}
extern "C" struct group *
getgrnam32 (const char *name)
{
return internal_getgrnam (name);
struct group *tempgr = internal_getgrnam (name);
pthread_testcancel ();
return getgr_cp (tempgr);
}
#ifdef __x86_64__

View File

@ -41,6 +41,7 @@ pwdgrp::parse_passwd ()
res.p.pw_dir = next_str (':');
res.p.pw_shell = next_str (':');
res.sid.getfrompw (&res.p);
res.len = lptr - res.p.pw_name;
return true;
}
@ -180,12 +181,47 @@ internal_getpwuid (uid_t uid, cyg_ldap *pldap)
return NULL;
}
/* getpwuid/getpwnam are not reentrant. */
static struct {
struct passwd p;
char *buf;
size_t bufsiz;
} app_pw;
static struct passwd *
getpw_cp (struct passwd *temppw)
{
if (!temppw)
return NULL;
pg_pwd *pw = (pg_pwd *) temppw;
if (app_pw.bufsiz < pw->len)
{
char *newbuf = (char *) realloc (app_pw.buf, pw->len);
if (!newbuf)
{
set_errno (ENOMEM);
return NULL;
}
app_pw.buf = newbuf;
app_pw.bufsiz = pw->len;
}
memcpy (app_pw.buf, pw->p.pw_name, pw->len);
memcpy (&app_pw.p, &pw->p, sizeof pw->p);
ptrdiff_t diff = app_pw.buf - pw->p.pw_name;
app_pw.p.pw_name += diff;
app_pw.p.pw_passwd += diff;
app_pw.p.pw_gecos += diff;
app_pw.p.pw_dir += diff;
app_pw.p.pw_shell += diff;
return &app_pw.p;
}
extern "C" struct passwd *
getpwuid32 (uid_t uid)
{
struct passwd *temppw = internal_getpwuid (uid);
pthread_testcancel ();
return temppw;
return getpw_cp (temppw);
}
#ifdef __x86_64__
@ -246,7 +282,7 @@ getpwnam (const char *name)
{
struct passwd *temppw = internal_getpwnam (name);
pthread_testcancel ();
return temppw;
return getpw_cp (temppw);
}

View File

@ -59,12 +59,14 @@ struct pg_pwd
{
struct passwd p;
cygsid sid;
size_t len;
};
struct pg_grp
{
struct group g;
cygsid sid;
size_t len;
};
class pwdgrp