All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch] Change libselinux to use getpwnam_r
@ 2004-01-13 15:41 Stephen Smalley
  2004-01-14  8:38 ` Thorsten Kukuk
  0 siblings, 1 reply; 3+ messages in thread
From: Stephen Smalley @ 2004-01-13 15:41 UTC (permalink / raw)
  To: selinux

[-- Attachment #1: Type: text/plain, Size: 410 bytes --]

The attached patch against libselinux-1.4 changes it to use getpwnam_r
internally instead of getpwnam, so that it doesn't clobber any existing
pwd struct previously obtained by the caller.  This showed up as an
issue for the selinux-enabled gdm.  It doesn't appear to affect login or
sshd, since they make a copy of the pwd struct themselves.

-- 
Stephen Smalley <sds@epoch.ncsc.mil>
National Security Agency

[-- Attachment #2: libselinux-getpwnam.patch --]
[-- Type: text/x-patch, Size: 1873 bytes --]

Index: libselinux/src/get_context_list.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/get_context_list.c,v
retrieving revision 1.8
diff -u -r1.8 get_context_list.c
--- libselinux/src/get_context_list.c	1 Dec 2003 19:28:32 -0000	1.8
+++ libselinux/src/get_context_list.c	13 Jan 2004 12:36:21 -0000
@@ -206,26 +206,38 @@
     FILE *config_file;    /* The configuration file                    */
     char *fname = 0;      /* The name of the user's configuration file */
     size_t fname_len;     /* The length of fname                       */
-    struct passwd *pwd;   /* The user's passwd structure               */
+    struct passwd pwdbuf, *pwd = &pwdbuf;   
+    char *buf;
     int retval;           /* The return value                          */
+    long buflen;
 
     if (which == USERPRIORITY)
     {
-        /* Get the password structure in order to find the home directory */
-        pwd = getpwnam (user);
-        if (!pwd)
-        {
-            return -1;
+        /* Get the password structure in order to find the home directory.
+	   Use getpwnam_r to avoid clobbering any existing pwd struct obtained
+	   by the caller. */
+	buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+	if (buflen < 0)
+		return -1;
+	buf = malloc(buflen);
+	if (!buf)
+		return -1;
+	retval = getpwnam_r (user, pwd, buf, buflen, &pwd );
+        if (retval < 0 || !pwd) {
+		free(buf);
+		return -1;
         }
         fname_len = strlen (pwd->pw_dir) + 20;
         fname = malloc (fname_len);
-        if (!fname)
+        if (!fname) 
         {
+	    free(buf);
             return -1;
         }
         sprintf (fname, "%s%s", pwd->pw_dir, "/.default_contexts");
         config_file = fopen (fname, "r");
 	free (fname);
+        free(buf);
     }
     else if (which == SYSTEMPRIORITY)
     {

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

* Re: [patch] Change libselinux to use getpwnam_r
  2004-01-13 15:41 [patch] Change libselinux to use getpwnam_r Stephen Smalley
@ 2004-01-14  8:38 ` Thorsten Kukuk
  2004-01-14 14:12   ` Stephen Smalley
  0 siblings, 1 reply; 3+ messages in thread
From: Thorsten Kukuk @ 2004-01-14  8:38 UTC (permalink / raw)
  To: selinux

On Tue, Jan 13, Stephen Smalley wrote:

> The attached patch against libselinux-1.4 changes it to use getpwnam_r
> internally instead of getpwnam, so that it doesn't clobber any existing
> pwd struct previously obtained by the caller.  This showed up as an
> issue for the selinux-enabled gdm.  It doesn't appear to affect login or
> sshd, since they make a copy of the pwd struct themselves.

> +       buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
> +       if (buflen < 0)
> +               return -1;
> +       buf = malloc(buflen);
> +       if (!buf)
> +               return -1;
> +       retval = getpwnam_r (user, pwd, buf, buflen, &pwd );
> +        if (retval < 0 || !pwd) {
> +               free(buf);
> +               return -1;
>          }

While _SC_GETPW_R_SIZE_MAX should return the max. size getpwnam_r
needs for a buffer, in reallity this is often not enough. There is
no limit, how long a line in /etc/passwd can be.
So a better way is:

while (getpwnam_r (user, pwd, buf, buflen, &pwd) != 0
         && errno == ERANGE)
    {
      errno = 0;
      buflen *= 2;
      buf = realloc (buf, buflen);
    }


 Thorsten

-- 
Thorsten Kukuk       http://www.suse.de/~kukuk/        kukuk@suse.de
SuSE Linux AG        Maxfeldstr. 5                 D-90409 Nuernberg
--------------------------------------------------------------------    
Key fingerprint = A368 676B 5E1B 3E46 CFCE  2D97 F8FD 4E23 56C6 FB4B

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

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

* Re: [patch] Change libselinux to use getpwnam_r
  2004-01-14  8:38 ` Thorsten Kukuk
@ 2004-01-14 14:12   ` Stephen Smalley
  0 siblings, 0 replies; 3+ messages in thread
From: Stephen Smalley @ 2004-01-14 14:12 UTC (permalink / raw)
  To: Thorsten Kukuk; +Cc: selinux, Daniel J Walsh

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

On Wed, 2004-01-14 at 03:38, Thorsten Kukuk wrote:
> While _SC_GETPW_R_SIZE_MAX should return the max. size getpwnam_r
> needs for a buffer, in reallity this is often not enough. There is
> no limit, how long a line in /etc/passwd can be.
> So a better way is:
> 
> while (getpwnam_r (user, pwd, buf, buflen, &pwd) != 0
>          && errno == ERANGE)
>     {
>       errno = 0;
>       buflen *= 2;
>       buf = realloc (buf, buflen);
>     }

Thanks.  An updated patch for libselinux-1.4 is attached.

-- 
Stephen Smalley <sds@epoch.ncsc.mil>
National Security Agency

[-- Attachment #2: libselinux-getpwnam3.patch --]
[-- Type: text/x-patch, Size: 2145 bytes --]

Index: libselinux/src/get_context_list.c
===================================================================
RCS file: /nfshome/pal/CVS/selinux-usr/libselinux/src/get_context_list.c,v
retrieving revision 1.8
retrieving revision 1.10
diff -u -r1.8 -r1.10
--- libselinux/src/get_context_list.c	1 Dec 2003 19:28:32 -0000	1.8
+++ libselinux/src/get_context_list.c	14 Jan 2004 14:06:52 -0000	1.10
@@ -206,26 +206,50 @@
     FILE *config_file;    /* The configuration file                    */
     char *fname = 0;      /* The name of the user's configuration file */
     size_t fname_len;     /* The length of fname                       */
-    struct passwd *pwd;   /* The user's passwd structure               */
+    struct passwd pwdbuf, *pwd = &pwdbuf;   
+    char *buf;
     int retval;           /* The return value                          */
+    long buflen;
 
     if (which == USERPRIORITY)
     {
-        /* Get the password structure in order to find the home directory */
-        pwd = getpwnam (user);
-        if (!pwd)
-        {
-            return -1;
+        /* Get the password structure in order to find the home directory.
+	   Use getpwnam_r to avoid clobbering any existing pwd struct obtained
+	   by the caller. */
+	buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+	if (buflen < 0)
+		return -1;
+	buf = malloc(buflen);
+	if (!buf)
+		return -1;
+	retval = getpwnam_r (user, pwd, buf, buflen, &pwd );
+	while (retval < 0 && errno == ERANGE) {
+		char *newbuf;
+		errno = 0;
+		buflen *= 2;
+		newbuf = realloc (buf, buflen);
+		if (!newbuf) {
+			free(buf);
+			return -1;
+		}
+		buf = newbuf;
+		retval = getpwnam_r (user, pwd, buf, buflen, &pwd );
+	}
+        if (retval < 0 || !pwd) {
+		free(buf);
+		return -1;
         }
         fname_len = strlen (pwd->pw_dir) + 20;
         fname = malloc (fname_len);
-        if (!fname)
+        if (!fname) 
         {
+	    free(buf);
             return -1;
         }
         sprintf (fname, "%s%s", pwd->pw_dir, "/.default_contexts");
         config_file = fopen (fname, "r");
 	free (fname);
+        free(buf);
     }
     else if (which == SYSTEMPRIORITY)
     {

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

end of thread, other threads:[~2004-01-14 14:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-13 15:41 [patch] Change libselinux to use getpwnam_r Stephen Smalley
2004-01-14  8:38 ` Thorsten Kukuk
2004-01-14 14:12   ` Stephen Smalley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.