Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-05-07 15:00:00 +0400
committerCorinna Vinschen <corinna@vinschen.de>2014-05-07 15:00:00 +0400
commit20de26ebf982c2645b724b126b103cc8629f51eb (patch)
tree001c4a35d6f4467cc2f0df3840009a2793e434a2 /winsup
parentfc3a3524b243956ad1c483a7436ddd37849ce2a9 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/grp.cc83
-rw-r--r--winsup/cygwin/passwd.cc40
-rw-r--r--winsup/cygwin/pwdgrp.h2
4 files changed, 110 insertions, 36 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 806539cd9..99a843935 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index fadadff64..3ccdbee0f 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -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__
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index b0e5ff8de..9a7c91863 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -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);
}
diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h
index 1a964def3..dfeef5680 100644
--- a/winsup/cygwin/pwdgrp.h
+++ b/winsup/cygwin/pwdgrp.h
@@ -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