[<<] [<] Page 1 of 1 [>] [>>] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
NULL pointer
From: Gary James ####@####.#### Date: 2 Feb 2001 02:42:23 -0000 Message-Id: <20010201215406.A830@pc.twcny.rr.com> This function in srvfunc.c void GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data) { void *p; if(!(p = malloc(len))) GsError(GR_ERROR_MALLOC_FAILED, wid); memcpy(p, data, thislen); GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); } probably ought to return after the GsError() function call void GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data) { void *p; if(!(p = malloc(len))) { GsError(GR_ERROR_MALLOC_FAILED, wid); return; } memcpy(p, data, thislen); GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: NULL pointer
From: Gary James ####@####.#### Date: 2 Feb 2001 03:07:44 -0000 Message-Id: <20010201221927.A848@pc.twcny.rr.com> This function in microwin/src/nanox/srvfunc.c void GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data) { void *p; if(!(p = malloc(len))) GsError(GR_ERROR_MALLOC_FAILED, wid); memcpy(p, data, thislen); GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); } Actually on second gander this function seems quite messed up. We are allocating buffer of length "len" then copying into it "thislen" bytes. So even if the allocation is happy, the memcpy() could exceed the buffer boundary. It looks like the calling function wants a buffer of "len" sent back to the client not one of length "thislen". Another observation, why do we do we allocate a buffer at all. The function GsDeliverClientDataEvent() allocates its own buffer and does another memcpy() into the new buffer that it creates. It seems that we could save a copy by passing the original pointer to the second function. Last observation, it doesn't look like anybody is freeing the buffer allocated in this function. Gary James On Thu, 01 Feb 2001 21:54:06 Gary James wrote: > This function in srvfunc.c > > void > GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, > GR_LENGTH len, GR_LENGTH thislen, void > *data) > { > void *p; > > if(!(p = malloc(len))) GsError(GR_ERROR_MALLOC_FAILED, wid); > memcpy(p, data, thislen); > > GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); > } > > probably ought to return after the GsError() function call > > void > GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, > GR_LENGTH len, GR_LENGTH thislen, void > *data) > { > void *p; > > if(!(p = malloc(len))) > { > GsError(GR_ERROR_MALLOC_FAILED, wid); > return; > } > memcpy(p, data, thislen); > > GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); > } > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: ####@####.#### > For additional commands, e-mail: ####@####.#### > > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: NULL pointer
From: "Greg Haerr" ####@####.#### Date: 5 Feb 2001 17:58:12 -0000 Message-Id: <028201c08f99$1c3864c0$15320cd0@gregh> : void : GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, : GR_LENGTH len, GR_LENGTH thislen, void *data) : { : void *p; : : if(!(p = malloc(len))) GsError(GR_ERROR_MALLOC_FAILED, wid); : memcpy(p, data, thislen); : : GsDeliverClientDataEvent(did, wid, serial, len, thislen, p); : } Yes, you're right about the return, it should return after the malloc failed... : : Actually on second gander this function seems quite messed up. : : We are allocating buffer of length "len" then copying into it "thislen" : bytes. So even if the allocation is happy, the memcpy() could exceed the : buffer boundary. It looks like the calling function wants a buffer of "len" : sent back to the client not one of length "thislen". : : Another observation, why do we do we allocate a buffer at all. The function : GsDeliverClientDataEvent() allocates its own buffer and does another : memcpy() into the new buffer that it creates. It seems that we could save a : copy by passing the original pointer to the second function. I included this function, written by Alex, without any testing, as I was trying to get pre7 out, and I had been sitting on the patch for a month. I think you're generally correct in your observations. I had asked Alex to test the get/setselection client test programs, but haven't heard back yet. The copy is required in the LINK_APP_TO_SERVER case, though. I am planning on enhancing and generalizing this submission to include general client-to-client communications, but haven't had a chance yet. Regards, Greg | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: NULL pointer
From: Gary James ####@####.#### Date: 5 Feb 2001 19:40:21 -0000 Message-Id: <3A7F02A6.4050409@criticallink.com> Greg Haerr wrote: > The copy is required in the LINK_APP_TO_SERVER case, though. I agree that you need a copy, but the required copy is the function GsDeliverClientDataEvent() not in this function. So how was the show in NYC last week. I was real tempted to drive down and visit you but it was way too busy of a week at work. Maybe next year. Gary James | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: NULL pointer
From: Alex Holden ####@####.#### Date: 6 Feb 2001 21:34:28 -0000 Message-Id: <Pine.LNX.4.04.10102062052190.1170-100000@hyperspace.linuxhacker.org> On Thu, 1 Feb 2001, Gary James wrote: > This function in microwin/src/nanox/srvfunc.c > GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, Hi, sorry it's took so long to reply; I've been too busy to work on Microwindows for the past few weeks. <snip> > We are allocating buffer of length "len" then copying into it "thislen" > bytes. So even if the allocation is happy, the memcpy() could exceed the > buffer boundary. It looks like the calling function wants a buffer of "len" > sent back to the client not one of length "thislen". The first thing you said is definitely right- the function should return after the GsError(). As to the second part, the logic is indeed incorrect but not in the way that you think. Thislen is guaranteed to be <= len because the only time when they are not equal is when the data block has to be fragmented into multiple packets (in which case len gives the total length of the block and thislen gives the length of this packet). So allocating an area of memory the size of the entire block to store the amount of data needed for the current packet is wasteful and could use up the server's memory if the block is too large, but it isn't a buffer overrun bug like you suggested. The correct fix for this would be to change: if(!(p = malloc(len))) GsError(GR_ERROR_MALLOC_FAILED, wid); memcpy(p, data, thislen); to: if(!(p = malloc(thislen))) { GsError(GR_ERROR_MALLOC_FAILED, wid); return; } memcpy(p, data, thislen); > Another observation, why do we do we allocate a buffer at all. The function > Last observation, it doesn't look like anybody is freeing the buffer > allocated in this function. Ah, this is a result me cocking up when I fixed a bug that Greg pointed out where the buffer could get freed twice if two clients selected for CLIENT_DATA events on the same window- in fixing that pretty obscure problem I added a rather more obvious memory leak. The old way, the data got copied once in GrSendClientData() and freed when it was used in GrGetNextEventWrapperFinish() (for every client which had selected for it, which was the original bug). After the fix, the data gets copied once per client in GsDeliverClientDataEvent() instead, which fixes the original bug, but I forgot to take out the (now completely unnecessary) copy in GrSendClientData(). So forget the previous fix to GrSendClientData(); it should instead simply be: void GrSendClientData(GR_WINDOW_ID wid, GR_WINDOW_ID did, GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data) { GsDeliverClientDataEvent(did, wid, serial, len, thislen, data); } I just tried transferring 64MB of data through it with this fix, and the nano-X memory usage stayed reasonable. -- ------- Alex Holden ------- http://www.linuxhacker.org/ http://www.robogeeks.org/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[<<] [<] Page 1 of 1 [>] [>>] |