Subject: Re: CVS commit: gnusrc/gnu/dist/cvs/src
To: Jun-ichiro itojun Hagino <itojun@netbsd.org>
From: Urban Boquist <urban@boquist.net>
List: source-changes
Date: 11/28/2002 21:52:52
Jun-ichiro> Modified Files: gnusrc/gnu/dist/cvs/src: client.c
Jun-ichiro> Log Message: fix pointer-to-int cast problem

Hi Itojun,

I don't think this fixes the real problem with that code. Last in this
mail is a better fix, I hope. The real problem with the code is that in
the following, in auth_server():

int fd = (int) lto_server->closure;

"lto_server->closure" is of type "void *" but it is not really an int,
it is a pointer to a malloced struct of this type (from buffer.c):

struct stdio_buffer_closure
{
    FILE *fp;
    int child_pid;
};

so the code must first dereference and then use fileno() to get at the
fd. After I found this I checked www.cvshome.org, and sure enough,
this was fixed a couple of months ago in their CVS (the CVS CVS! ;-).

Here is that commit:

* buffer.h: New prototype for...
* buffer.c (stdio_buffer_get_file): this new function to abstract
access to a buffer's file descriptor.
* client.c (auth_server): Use the new function.
(Original patch from Jonathan Kamens <jik@kamens.brookline.ma.us>.)

For reference, here are the three diffs involved:

http://ccvs.cvshome.org/source/browse/ccvs/src/client.c.diff?r1=1.309&r2=1.310
http://ccvs.cvshome.org/source/browse/ccvs/src/buffer.c.diff?r1=1.18&r2=1.19
http://ccvs.cvshome.org/source/browse/ccvs/src/buffer.h.diff?r1=1.9&r2=1.10

Below is the same fix, but against NetBSD-current sources _before_
your change to client.c.

Kind regards,

        -- Urban

Index: client.c
===================================================================
RCS file: /anoncvs/gnusrc/gnu/dist/cvs/src/client.c,v
retrieving revision 1.7
diff -u -r1.7 client.c
--- client.c	2002/11/28 05:59:06	1.7
+++ client.c	2002/11/28 20:43:59
@@ -3974,10 +3974,11 @@
     if (do_gssapi)
     {
 #ifdef HAVE_GSSAPI
-	int fd = (int) lto_server->closure;
+	FILE *fp = stdio_buffer_get_file(lto_server);
+	int fd = fp ? fileno(fp) : -1;
 	struct stat s;
 
-	if (fstat (fd, &s) < 0 || !S_ISSOCK(s.st_mode))
+	if ((fd < 0) || (fstat (fd, &s) < 0) || !S_ISSOCK(s.st_mode))
 	{
 	    error (1, 0, "gserver currently only enabled for socket connections");
 	}

Index: buffer.c
===================================================================
RCS file: /anoncvs/gnusrc/gnu/dist/cvs/src/buffer.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 buffer.c
--- buffer.c	2002/11/28 04:54:18	1.1.1.2
+++ buffer.c	2002/11/28 20:38:15
@@ -1247,6 +1247,19 @@
 			   (void *) bc);
 }
 
+/* Return the file associated with a stdio buffer. */
+FILE *
+stdio_buffer_get_file (buf)
+   struct buffer *buf;
+{
+   struct stdio_buffer_closure *bc;
+
+   assert(buf->shutdown == stdio_buffer_shutdown);
+
+   bc = (struct stdio_buffer_closure *) buf->closure;
+   return(bc->fp);
+}
+
 /* The buffer input function for a buffer built on a stdio FILE.  */
 
 static int

Index: buffer.h
===================================================================
RCS file: /anoncvs/gnusrc/gnu/dist/cvs/src/buffer.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 buffer.h
--- buffer.h	2002/11/28 04:54:53	1.1.1.2
+++ buffer.h	2002/11/28 20:44:12
@@ -112,6 +112,7 @@
 extern struct buffer *buf_nonio_initialize PROTO((void (*) (struct buffer *)));
 extern struct buffer *stdio_buffer_initialize
   PROTO((FILE *, int, int, void (*) (struct buffer *)));
+extern FILE *stdio_buffer_get_file PROTO((struct buffer *));
 extern struct buffer *compress_buffer_initialize
   PROTO((struct buffer *, int, int, void (*) (struct buffer *)));
 extern struct buffer *packetizing_buffer_initialize