public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] getpw: Get rid of alloca
@ 2023-08-28 19:48 Joe Simmons-Talbott
  2023-08-29  8:03 ` Florian Weimer
  0 siblings, 1 reply; 4+ messages in thread
From: Joe Simmons-Talbott @ 2023-08-28 19:48 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Since _SC_GETPW_R_SIZE_MAX will be always NSS_BUFLEN_PASSWD, use a fixed
sized array rather than alloca to avoid potential stack overflow.
---
Changes to v1:
 * Get rid of the scratch_buffer and use a fixed sized array instead.

 pwd/getpw.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/pwd/getpw.c b/pwd/getpw.c
index cf747374b8..86ccbc8d6e 100644
--- a/pwd/getpw.c
+++ b/pwd/getpw.c
@@ -15,7 +15,6 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <alloca.h>
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -31,31 +30,39 @@ int __getpw (__uid_t uid, char *buf);
 int
 __getpw (__uid_t uid, char *buf)
 {
-  size_t buflen;
-  char *tmpbuf;
+  char tmpbuf[NSS_BUFLEN_PASSWD];
   struct passwd resbuf, *p;
+  int retval = 0;
 
   if (buf == NULL)
     {
       __set_errno (EINVAL);
-      return -1;
+      retval =  -1;
+      goto error_out;
     }
 
-  buflen = __sysconf (_SC_GETPW_R_SIZE_MAX);
-  tmpbuf = alloca (buflen);
-
-  if (__getpwuid_r (uid, &resbuf, tmpbuf, buflen, &p) != 0)
-    return -1;
+  if (__getpwuid_r (uid, &resbuf, tmpbuf, sizeof (tmpbuf), &p) != 0)
+    {
+      retval = -1;
+      goto error_out;
+    }
 
   if (p == NULL)
-    return -1;
+    {
+      retval = -1;
+      goto error_out;
+    }
 
   if (sprintf (buf, "%s:%s:%lu:%lu:%s:%s:%s", p->pw_name, p->pw_passwd,
 	       (unsigned long int) p->pw_uid, (unsigned long int) p->pw_gid,
 	       p->pw_gecos, p->pw_dir, p->pw_shell) < 0)
-    return -1;
+    {
+      retval = -1;
+      goto error_out;
+    }
 
-  return 0;
+error_out:
+  return retval;
 }
 weak_alias (__getpw, getpw)
 
-- 
2.39.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] getpw: Get rid of alloca
  2023-08-28 19:48 [PATCH v2] getpw: Get rid of alloca Joe Simmons-Talbott
@ 2023-08-29  8:03 ` Florian Weimer
  2023-08-29 12:26   ` Adhemerval Zanella Netto
  0 siblings, 1 reply; 4+ messages in thread
From: Florian Weimer @ 2023-08-29  8:03 UTC (permalink / raw)
  To: Joe Simmons-Talbott via Libc-alpha; +Cc: Joe Simmons-Talbott

* Joe Simmons-Talbott via Libc-alpha:

> Since _SC_GETPW_R_SIZE_MAX will be always NSS_BUFLEN_PASSWD, use a fixed
> sized array rather than alloca to avoid potential stack overflow.

_SC_GETPW_R_SIZE_MAX is not very well-named, it is the initial suggested
buffer size.  The code should use the usual scratch buffer retry loop.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] getpw: Get rid of alloca
  2023-08-29  8:03 ` Florian Weimer
@ 2023-08-29 12:26   ` Adhemerval Zanella Netto
  2023-10-10 19:02     ` Joe Simmons-Talbott
  0 siblings, 1 reply; 4+ messages in thread
From: Adhemerval Zanella Netto @ 2023-08-29 12:26 UTC (permalink / raw)
  To: Florian Weimer, Joe Simmons-Talbott via Libc-alpha



On 29/08/23 05:03, Florian Weimer via Libc-alpha wrote:
> * Joe Simmons-Talbott via Libc-alpha:
> 
>> Since _SC_GETPW_R_SIZE_MAX will be always NSS_BUFLEN_PASSWD, use a fixed
>> sized array rather than alloca to avoid potential stack overflow.
> 
> _SC_GETPW_R_SIZE_MAX is not very well-named, it is the initial suggested
> buffer size.  The code should use the usual scratch buffer retry loop.

I though about that on initial revision, however this will change the function
semantic and the code below:

  long int sz = sysconf (_SC_GETPW_R_SIZE_MAX);
  char *buf = NULL;
  while (1) {
    buf = realloc (buf,  sz);
    r = getpw (uid, buf);
    if (r != -1 || errno != ENOMEM)
      break;
    sz *= 2;
  }

will start to trigger a buffer overrun.  This is an old tricky interface
where I would prefer if we continue to keep same semantic, and maybe 
deprecate and move it to compat symbol. 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] getpw: Get rid of alloca
  2023-08-29 12:26   ` Adhemerval Zanella Netto
@ 2023-10-10 19:02     ` Joe Simmons-Talbott
  0 siblings, 0 replies; 4+ messages in thread
From: Joe Simmons-Talbott @ 2023-10-10 19:02 UTC (permalink / raw)
  To: Adhemerval Zanella Netto
  Cc: Florian Weimer, Joe Simmons-Talbott via Libc-alpha

On Tue, Aug 29, 2023 at 09:26:39AM -0300, Adhemerval Zanella Netto via Libc-alpha wrote:
> 
> 
> On 29/08/23 05:03, Florian Weimer via Libc-alpha wrote:
> > * Joe Simmons-Talbott via Libc-alpha:
> > 
> >> Since _SC_GETPW_R_SIZE_MAX will be always NSS_BUFLEN_PASSWD, use a fixed
> >> sized array rather than alloca to avoid potential stack overflow.
> > 
> > _SC_GETPW_R_SIZE_MAX is not very well-named, it is the initial suggested
> > buffer size.  The code should use the usual scratch buffer retry loop.
> 
> I though about that on initial revision, however this will change the function
> semantic and the code below:
> 
>   long int sz = sysconf (_SC_GETPW_R_SIZE_MAX);
>   char *buf = NULL;
>   while (1) {
>     buf = realloc (buf,  sz);
>     r = getpw (uid, buf);
>     if (r != -1 || errno != ENOMEM)
>       break;
>     sz *= 2;
>   }
> 
> will start to trigger a buffer overrun.  This is an old tricky interface
> where I would prefer if we continue to keep same semantic, and maybe 
> deprecate and move it to compat symbol. 
> 

Where does this leave this patch?  Should I submit a patch deprecating
getpw?

Thanks,
Joe


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-10-10 19:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-28 19:48 [PATCH v2] getpw: Get rid of alloca Joe Simmons-Talbott
2023-08-29  8:03 ` Florian Weimer
2023-08-29 12:26   ` Adhemerval Zanella Netto
2023-10-10 19:02     ` Joe Simmons-Talbott

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).