[comp.lang.c] Life after free?

quan@sol.surv.utas.oz (Stephen Quan) (09/27/90)

char *funny(ch)
char ch;
{
  char *tmp;
  int i;
  
  tmp = (char *) malloc(100);
  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
  free(tmp);
  return tmp;
}

Any comments on free-ing tmp before it is return-ed?

Stephen Quan (quan@sol.surv.utas.edu.au)
University of Tasmania.

gaynor@sparky.rutgers.edu (Silver) (09/27/90)

> Any comments on free-ing tmp before it is return-ed?
Whaaat?  That's just begging for nightmares, for you and anyone else that has
to deal with or be responsible for such code.  You're better off tease a NYC
cop with a realistic-looking toy gun -- much safer, and you'll know the outcome
immediately.

Regards, [Ag]

henry@zoo.toronto.edu (Henry Spencer) (09/27/90)

In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>  free(tmp);
>  return tmp;
>}
>
>Any comments on free-ing tmp before it is return-ed?

Yes:  don't do it.  On some implementations in some circumstances, this
will accidentally work.  It's not dependable.
-- 
TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology
OSI: handling yesterday's loads someday|  henry@zoo.toronto.edu   utzoo!henry

steve@taumet.com (Stephen Clamage) (09/28/90)

quan@sol.surv.utas.oz (Stephen Quan) writes:

>  char *tmp;
>  tmp = (char *) malloc(100);
>  ...
>  free(tmp);
>  return tmp;

>Any comments on free-ing tmp before it is return-ed?

I believe this is in the FAQ, which should always be checked before
asking basic questions.  You might also RTFM.

However:  The contents of the malloc'd memory may be changed by free().
In any event, some routine may come along and acquire that space,
possibly asynchronously, and overwrite it even if free() doesn't.
What problem are you trying to solve by using a pointer to free'd space?
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

userAKDU@mts.ucs.UAlberta.CA (Al Dunbar) (09/28/90)

In article <quan.654410256@sol>, quan@sol.surv.utas.oz (Stephen Quan) writes:
>char *funny(ch)
>char ch;
>{
>  char *tmp;
>  int i;
>
>  tmp = (char *) malloc(100);
>  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
>  free(tmp);
>  return tmp;
>}
>
>Any comments on free-ing tmp before it is return-ed?
>
>Stephen Quan (quan@sol.surv.utas.edu.au)
>University of Tasmania.
 
You have, perhaps, a death-wish?
 
-------------------+-------------------------------------------
Al Dunbar          |
Edmonton, Alberta  |   this space for rent
CANADA             |
-------------------+-------------------------------------------

lerman@stpstn.UUCP (Ken Lerman) (09/28/90)

In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
->char *funny(ch)
->char ch;
->{
->  char *tmp;
->  int i;
->  
->  tmp = (char *) malloc(100);
->  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
->  free(tmp);
->  return tmp;
->}
->
->Any comments on free-ing tmp before it is return-ed?
->
->Stephen Quan (quan@sol.surv.utas.edu.au)
->University of Tasmania.


Not only is it sensible, the semantics of free require it.  The item
freed is guaranteed to be valid until the next call to malloc,
realloc, ...

The intended use of funny() might be to format some characters which
will be printed by the user immediately after calling funny.
Unfortunately, the user can't call printf because printf might call
malloc which would destroy his temporary buffer.

So, yeah, it could be used.  Is it useful (in the sense of full of
use)? No way.

Ken

norm@oglvee.UUCP (Norman Joseph) (09/28/90)

In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:

>char *funny(ch)
>char ch;
>{
>  char *tmp;
>  [...]
>  return tmp;
>}

>Any comments on free-ing tmp before it is return-ed?

No, but I -do- have a comment on returning tmp at all.  The storage
class in the declaration of tmp defaults to "auto".  This gives the
variable tmp a number of important properties, one of which is dynamic
duration.  Dynamic duration means that tmp only "exists" while the
function in which it is declared is executing.  After returning from
the function, there is no guarantee about the value of the now non-
existent variable tmp.

If you want the variable tmp to retain its value between calls to the
function, declare the variable as "static char *tmp".
-- 
Norm Joseph - (amanue!oglvee!norm)           cgh!amanue!oglvee!norm@dsi.com, or
  Oglevee Computer Systems, Inc.             ditka!oglvee!norm@daver.bungi.com
                                   ---<*>---
      "Shucking Usenet oysters in pursuit of a pearl."  --  Bill Kennedy

bomgard@iuvax.cs.indiana.edu (Tim Bomgardner) (09/28/90)

In article <606@oglvee.UUCP> norm@oglvee.UUCP (Norman Joseph) writes:
}In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
}
}>char *funny(ch)
}>char ch;
}>{
}>  char *tmp;
    int i;

    tmp = (char *) malloc(100);
    for (i=0; i<=99 ; i++) *(tmp+i) = ch;
    free(tmp);
}>  return tmp;
}>}
}
}>Any comments on free-ing tmp before it is return-ed?
}
}No, but I -do- have a comment on returning tmp at all.  The storage
}class in the declaration of tmp defaults to "auto".  This gives the
}variable tmp a number of important properties, one of which is dynamic
}duration.  Dynamic duration means that tmp only "exists" while the
}function in which it is declared is executing.  After returning from
}the function, there is no guarantee about the value of the now non-
}existent variable tmp.
}
}If you want the variable tmp to retain its value between calls to the
}function, declare the variable as "static char *tmp".

I doubt that anyone on the net is better than I am at missing the obvious,
especially when it's right in front of my face, but this doesn't make much
sense to me.  The part about auto variables is true, but that has nothing
to do with returned values.

Concerning tmp, there are three values which might be of interest:

1) tmp: the value is the address of a char
2) *tmp: the value is a char
3) &tmp: the value is the address of variable tmp (likely in a stack frame)

After the malloc, tmp contains the address of a char (likely somewhere in
the heap, but it doesn't really matter as long as it isn't in the stack
frame for this function, which it won't be).  It is also true that
the next 99 addresses also contain chars, but that doesn't matter as far as
tmp is concerned.  After free(tmp), tmp may or may not contain that address,
and the contents of that address may or may not be changed.  But assume 
everything remains intact.  The function returns the VALUE of tmp, not its
address, and the calling function then has a pointer to 100 consecutive
chars.

It's obvious to almost everyone the dangers of continuing to use a pointer
to freed memory, but could someone explain to me why tmp's being an auto
variable is in any way relevant to the original question?

roy@phri.nyu.edu (Roy Smith) (09/28/90)

norm@oglvee.UUCP (Norman Joseph) writes:
> "static char *tmp".

	Isn't that an oxymoron?
--
Roy Smith, Public Health Research Institute
455 First Avenue, New York, NY 10016
roy@alanine.phri.nyu.edu -OR- {att,cmcl2,rutgers,hombre}!phri!roy
"Arcane?  Did you say arcane?  It wouldn't be Unix if it wasn't arcane!"

pfalstad@tan.Princeton.EDU (Paul John Falstad) (09/28/90)

In article <60726@iuvax.cs.indiana.edu>, bomgard@iuvax.cs.indiana.edu (Tim Bomgardner) writes:
|> In article <606@oglvee.UUCP> norm@oglvee.UUCP (Norman Joseph) writes:
|> }In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
|> }
|> }>char *funny(ch)
|> }>char ch;
|> }>{
|> }>  char *tmp;
...
|>     tmp = (char *) malloc(100);
...
|>     free(tmp);
|> }>  return tmp;
|> }>}
|> }If you want the variable tmp to retain its value between calls to the
|> }function, declare the variable as "static char *tmp".

True, but irrelevant.  The value returned is a pointer to an area of memory
returned by malloc(), which does not go away until you either free it
explicitly or exit the program.  The four bytes of space on the stack where
that value is kept will go away when funny returns, but funny will return
a copy of it in a register variable, so who cares?

|> Concerning tmp, there are three values which might be of interest:
|> 1) tmp: the value is the address of a char
|> 2) *tmp: the value is a char
|> 3) &tmp: the value is the address of variable tmp (likely in a stack frame)
|> 
|> After the malloc, tmp contains the address of a char (likely somewhere in
|> the heap, but it doesn't really matter as long as it isn't in the stack
|> frame for this function, which it won't be).  It is also true that
|> the next 99 addresses also contain chars, but that doesn't matter as far as
|> tmp is concerned.  After free(tmp), tmp may or may not contain that address,
|> and the contents of that address may or may not be changed.  But assume 
|> everything remains intact.  The function returns the VALUE of tmp, not its
|> address, and the calling function then has a pointer to 100 consecutive
|> chars.

Exactly.

|> It's obvious to almost everyone the dangers of continuing to use a pointer
|> to freed memory, but could someone explain to me why tmp's being an auto
|> variable is in any way relevant to the original question?

Certainly.  It isn't.
-- 
Here is the address to complain to:
pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD CIS: 70016,1355
That address again,
sync@thumper.princeton.edu PLink:OHS738 GEnie:OHS738 CIS: 4128 143 1234 937

jh4o+@andrew.cmu.edu (Jeffrey T. Hutzelman) (09/29/90)

norm@oglvee.UUCP (Norman Joseph) writes:

> In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan)
> writes:
>
>>char *funny(ch)
>>char ch;
>>{
>>  char *tmp;
>>  [...]
>>  return tmp;
>>}
>
>>Any comments on free-ing tmp before it is return-ed?
>
> No, but I -do- have a comment on returning tmp at all.  The storage
>class in the declaration of tmp defaults to "auto".  This gives the
> variable tmp a number of important properties, one of which is
> dynamic duration.  Dynamic duration means that tmp only "exists"
> while the function in which it is declared is executing.  After
returning
> from the function, there is no guarantee about the value of the now
> non-existent variable tmp.
>
> If you want the variable tmp to retain its value between calls to the
> function, declare the variable as "static char *tmp".

Perhaps you want to reconsider that statement.  He is returning the
VALUE of tmp, not a pointer to it.  The value of a local (i.e. auto)
variable can be returned from a function even though the variable no
longer exists once the function returns.  Now if he had been returning
&tmp, that would have been different.  Note that even if he malloc'ed
memory and placed the pointer in tmp, he could safely return(tmp), and
the pointer would be returned and would point to the still-existent area
of memory.  As long as he didn't free(tmp) first, which would be
extraordinarily BAD.
-----------------
Jeffrey Hutzelman
America Online: JeffreyH11
Internet/BITNET:jh4o+@andrew.cmu.edu, jhutz@drycas.club.cc.cmu.edu

>> Apple // Forever!!! <<

cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)

In article <606@oglvee.UUCP> norm@oglvee.UUCP (Norman Joseph) writes:
>In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>
>>char *funny(ch)
>>char ch;
>>{
>>  char *tmp;
>>  [...]
>>  return tmp;
>>}
>
>No, but I -do- have a comment on returning tmp at all.  The storage
>class in the declaration of tmp defaults to "auto".  This gives the

However, if tmp is a pointer and you return the value contained in 
the pointer, who cares about tmp.  It is just used during the 
exection of the function.  The fact that tmp is no longer a valid
variable outside of this function will have no effect on the
availability of the data at the malloc'd region that tmp pointed to 
while it existed.

Note that I am NOT saying that you can free(tmp) and then return it.  If
the free was not there, the use of tmp would be totally correct.


-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

chris@mimsy.umd.edu (Chris Torek) (09/29/90)

>In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>>Any comments on free-ing tmp before it is return-ed?

In article <5620@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes:
>Not only is it sensible, the semantics of free require it.

Nay, not so.

>So, yeah, it could be used.  Is it useful (in the sense of full of
>use)? No way.

Aye.

To sum up: in many implementations, the space released via free()
remains unchanged at least until a later call to malloc or calloc.
A few even document this behaviour.  It is, however, not guaranteed
by the closest thing we have to a standard (i.e., ANSI X3.159-1989,
a.k.a. `ANSI C'), and there are some implementations out there that
will in fact immediately stomp on the space released by free().

As to the other question---that of returning the value of an automatic
---I think it has been sufficiently answered, but just for the record,
there is nothing wrong with returning the value of an automatic `char *'
variable:

	char *f() {
		char *p;
		int g();
		p = g() ? "yes" : "no";
		return p;
	}

This is no worse than, e.g.,

	int f1() {
		int i;
		i = g() ? 1 : 0;
		return i;
	}

The value is not necessarily returned in a register: all you can be
sure of is that the value is returned.  The compiler is free to, as
Ron Natalie once put it, stuff arguments into an envelope and mail
them off to the function being called, and results can be returned
the same way.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

karl@haddock.ima.isc.com (Karl Heuer) (09/29/90)

In article <5620@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes:
>In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>->Any comments on free-ing tmp before it is return-ed?
>
>Not only is it sensible, the semantics of free require it.

No.  An early manual once made the mistake of describing the local
implementation instead of the interface%, but not all versions do it that
way.  Some modern systems still include such a guarantee, but only to provide
backward compatibility to the programs that were foolish enough to depend on
it.  The Standard doesn't even guarantee that you can *look* at the value
remaining in tmp, much less dereference it.

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
________
% Okay, I'm exaggerating a bit.  It was a poorly-designed interface, though.

burley@world.std.com (James C Burley) (09/29/90)

In article <5620@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes:

   In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
   ->char *funny(ch)
   ->char ch;
   ->{
   ->  char *tmp;
   ->  int i;
   ->  
   ->  tmp = (char *) malloc(100);
   ->  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
   ->  free(tmp);
   ->  return tmp;
   ->}
   ->
   ->Any comments on free-ing tmp before it is return-ed?
   ->
   ->Stephen Quan (quan@sol.surv.utas.edu.au)
   ->University of Tasmania.

   Not only is it sensible, the semantics of free require it.  The item
   freed is guaranteed to be valid until the next call to malloc,
   realloc, ...

To who or what do you refer when you say "The item freed is guaranteed to
be valid..."?  I think it's fair to assume such statement would refer either
to the First Edition K&R C book or the ANSI C standard.  I don't have a K&R
C I book (and of course my K&R C II is based on the ANSI C standard), but my
ANSI C standard has this to say at the end of the paragraph beginning section
4.10.3 "Memory management functions":

    "The value of a pointer that refers to free space is indeterminate."

Perhaps some implementations make such a guarantee; if you're referring to
one of those, it might be a good idea to qualify the comment accordingly.
If you're referring to K&R C I, and you also are correct, that surprises me
because I wasn't aware of that guarantee either in my early days of using
C or when I read the ANSI C standard and other articles on the dangerous
so-called "quiet changes" -- and it seems to me dropping such a guarantee
from K&R C I when creating ANSI C would constitute such a quiet change.

James Craig Burley, Software Craftsperson    burley@world.std.com

eyal@delta.canberra.edu.au (Eyal Lebedinsky) (09/30/90)

In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>char *funny(ch)
>char ch;
>{
>  char *tmp;
>  int i;
>  
>  tmp = (char *) malloc(100);
>  for (i=0; i<=99 ; i++) *(tmp+i) = ch;
>  free(tmp);
>  return tmp;
>}
>
>Any comments on free-ing tmp before it is return-ed?

I hope this is a serious question. You should not use an area after it is freed.
Not only can it be re-used, but some schemes clobber it when it is added to the
free-list (that is, they use some of it for the memory management). Remember that
some C functions allocate memory implicitly, so you cannot trust your memory
just because you do no mallocs after the free().
>
>Stephen Quan (quan@sol.surv.utas.edu.au)
>University of Tasmania.

Regards
	Eyal
-- 
Regards
	Eyal

ark@alice.att.com (Andrew Koenig) (09/30/90)

In article <5620@stpstn.UUCP>, lerman@stpstn.UUCP (Ken Lerman) writes:

> Not only is it sensible, the semantics of free require it.  The item
> freed is guaranteed to be valid until the next call to malloc,
> realloc, ...

This statement was true ten years ago, but is false today.

You can find more detail in `C Traps and Pitfalls,' page 95.
-- 
				--Andrew Koenig
				  ark@europa.att.com

norm@oglvee.UUCP (Norman Joseph) (10/01/90)

In <60726@iuvax.cs.indiana.edu> bomgard@iuvax.cs.indiana.edu (Tim Bomgardner)
writes:
>In article <606@oglvee.UUCP> norm@oglvee.UUCP (Norman Joseph) writes:
>}In <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>}
>}>Any comments on free-ing tmp before it is return-ed?
>}
>}No, but I -do- have a comment on returning tmp at all.
>}[mindless babbling mercifully deleted]

>I doubt that anyone on the net is better than I am at missing the obvious,
>especially when it's right in front of my face, but this doesn't make much
>sense to me.

Well, now you can be sure that there is at least -one- person here better
than you in that regard.  :-)  It's a humbling experience to step into the
limelight of the Net only to fall flat on your face.  I don't know where my
head was at when I wrote that (that's the last time I'll skip my Thorazine!)
So now I'll beg the Net's pardon, promise not to take any more Stupid Pills
before reading news and promise to -read- every posting 42 times before
hitting "f", and then hit "n" instead.
-- 
Norm Joseph - (amanue!oglvee!norm)           cgh!amanue!oglvee!norm@dsi.com, or
  Oglevee Computer Systems, Inc.             ditka!oglvee!norm@daver.bungi.com
                                   ---<*>---
      "Shucking Usenet oysters in pursuit of a pearl."  --  Bill Kennedy

kdq@demott.COM (Kevin D. Quitt) (10/02/90)

    It should be noted that in secure systems, free() will clear the memory.
-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

mikep@dirty.csc.ti.com (Michael A. Petonic) (10/02/90)

In article <18339@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
>In article <5620@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes:
>>In article <quan.654410256@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:
>>->Any comments on free-ing tmp before it is return-ed?
>>
>>Not only is it sensible, the semantics of free require it.
>
>No.  An early manual once made the mistake of describing the local
>implementation instead of the interface%, but not all versions do it that
>way.  Some modern systems still include such a guarantee, but only to provide
>backward compatibility to the programs that were foolish enough to depend on
>it.  The Standard doesn't even guarantee that you can *look* at the value
>remaining in tmp, much less dereference it.
>
>Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint

In K&R (1st edition), malloc() isn't a feature of the language, it's a
library call.  So -- I guess it would have to depend on the library's
implementation, wouldn't it?  

In UNIX V.3, malloc(3C) (ie, the freemalloc() function contained within libc)
is defined to have a free() which leaves the contents of the freed memory
undisturbed.  But in libmalloc, free(3X) is defined to destroy the contents
of the freed memory.

-MikeP

bilbo@bisco.kodak.com (10/02/90)

> char *funny(ch)
> char ch;
> {
>   char *tmp;
>   int i;
>   
>   tmp = (char *) malloc(100);
>   for (i=0; i<=99 ; i++) *(tmp+i) = ch;
>   free(tmp);
>   return tmp;
> }
> 
> Any comments on free-ing tmp before it is return-ed?

GAG!  CHOKE!  COUGH!         1/2 :-)

I'd say you might get lucky if the calling function copied the result out
of the "buffer" IMMEDIATELY (i.e., in the very next statement) after the
return.  Most machines wouldn't have destroyed it by that time, but I wouldn't
guarantee ANYTHING.

This looks like the (BROKEN) code I've seen many times:

char *
foobar()
{
	char x[100];  			/*  NOTE: this is an AUTOMATIC variable	*/

	/* put something in x[] */

	return x;
}

Note that, since x is on the stack, it MIGHT not get blown away until after
you have a chance to move it somewhere, but don't bet your life on it!


--
Chuck Tryon
    (PLEASE use this address, as Kodak foobars one in header!)
    <bilbo@bisco.kodak.com>
    USmail: 46 Post Ave.;Roch. NY 14619                       B. Baggins
    <<...include standard disclamer...>>                      At Your Service

     "Then again, squirrels could be stupid."   (D. Mocsny)

richard@calvin.spp.cornell.edu (Richard Brittain - VOS hacker) (10/04/90)

Msdos programmers should be aware that Turbo-C free() modifies the memory
immediately.  This bit me once in porting from unix code that assumed "life
after free"

-- 
Richard Brittain,                   School of Elect. Eng.,  Upson Hall   
                                    Cornell University, Ithaca, NY 14853
ARPA: richard@calvin.spp.cornell.edu	
UUCP: {uunet,uw-beaver,rochester,cmcl2}!cornell!calvin!richard

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (10/04/90)

In <26770@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:

   The compiler is free to, as Ron Natalie once put it, stuff arguments
   into an envelope and mail them off to the function being called...

This idea has always seemed so quaint, but I wonder if it really works
for pointers?  For example, suppose I'm in California, which I am, and
you're in Maryland which you probably are, if you haven't moved since
you posted your article.  (Ah, moving!  What a pain.  I moved some time
ago from Indiana from California and it's such a hassle!  I still
haven't finished unpacking.  But I did unpack all my envelopes.  I have
both types -- the white ones, and the "privacy" sort that won't let you
see through them.  These latter ones are probably great for Modula-2
and Ada users, since you could mail "opaque" type arguments in them.)

Anyway, getting back to the discussion, does Maryland follow the same
addressing conventions?  If I mailed you a char * pointer in an
envelope, and its value was say 0x00adbcdd, would it point to the same
character once it reached you?

Well I once mailed some pointers off to a friend in Montana, and he
reported that the objects they pointed to were very different from the
objects I was using.  My guess that this sort of thing varies from
state to state, sort of like warranty rights that you may or may not
have.

This whole issue of envelopes for mailing arguments ought to be
addressed by a standards committee.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (10/04/90)

In article <2539@cirrusl.UUCP>, dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
> In <26770@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
>    The compiler is free to, as Ron Natalie once put it, stuff arguments
>    into an envelope and mail them off to the function being called...

> This idea has always seemed so quaint, but I wonder if it really works
> for pointers?

It works just fine.  What you overlooked is that when you want to
dereference a pointer, you have to mail it _back_ to me!
(As it happens, there are multiprocessor implementations of certain
programming languages where this very thing happens, interpreting
"put in an envelope and mail" as "put in a packet and squirt down a wire".)
-- 
Fixed in the next release.

bomgard@iuvax.cs.indiana.edu (Tim Bomgardner) (10/04/90)

In article <2539@cirrusl.UUCP>, dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
} In <26770@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes:
}    The compiler is free to, as Ron Natalie once put it, stuff arguments
}    into an envelope and mail them off to the function being called...
}
} This idea has always seemed so quaint, but I wonder if it really works
} for pointers?
}

It does work, altho there is additional overhead.  This is exactly how
remote procedure calls (RPCs) are implemented.  Note that the "envelope"
is usually called a "packet" in this context, and while the compiler
COULD do it, it's usually handled elsewhere (i.e., library procedures
called "stubs").

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/05/90)

In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>     It should be noted that in secure systems, free() will clear the memory.

That would be quite amusing, since there's absolutely no concept of
security within C. If you can free it, you can copy it out and save it
first.

---Dan

manning@nntp-server.caltech.edu (Evan Marshall Manning) (10/05/90)

In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>     It should be noted that in secure systems, free() will clear the memory.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:

>That would be quite amusing, since there's absolutely no concept of
>security within C. If you can free it, you can copy it out and save it
>first.

You're missing the point.  Of course you can do what you like with your
data.  But when you free() it you return it to the OS.  And anybody else
can end up with your data when they next malloc().

***************************************************************************
Your eyes are weary from staring at the CRT for so | Evan M. Manning
long.  You feel sleepy.  Notice how restful it is  |      is
to watch the cursor blink.  Close your eyes.  The  |manning@gap.cco.caltech.edu
opinions stated above are yours.  You cannot       | manning@mars.jpl.nasa.gov
imagine why you ever felt otherwise.               | gleeper@tybalt.caltech.edu

kaleb@thyme.jpl.nasa.gov (Kaleb Keithley ) (10/05/90)

In article <1990Oct5.002416.3196@nntp-server.caltech.edu> manning@nntp-server.caltech.edu (Evan Marshall Manning) writes:
>In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>>     It should be noted that in secure systems, free() will clear the memory.
>
>brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>
>>That would be quite amusing, since there's absolutely no concept of
>>security within C. If you can free it, you can copy it out and save it
>>first.
>
>You're missing the point.  Of course you can do what you like with your
>data.  But when you free() it you return it to the OS.  And anybody else
>can end up with your data when they next malloc().

Which OS is that on?  At the risk of exhibiting "small world" syndrome,
in UNIX, malloc and free work within the confines of the heap, which
is given to the process through the sbrk system call.  No other process
can *normally* gain access to a process' heap space without generating 
a memory exception of some kind and dumping core.  Memory given to a process
through sbrk is returned to the system memory pool only when the program
terminates.  I'd hazard that other multi-tasking OS's like VMS behave
similarly.

-- 
Kaleb Keithley                      Jet Propulsion Labs
kaleb@thyme.jpl.nasa.gov

Stirring up trouble again.

cpcahil@virtech.uucp (Conor P. Cahill) (10/05/90)

In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>
>    It should be noted that in secure systems, free() will clear the memory.

There is no requirement for this.  The only requirement is that memory that 
is made available to a process must have no information left in it
from the previous process that used that memory. 

Since free() does not release memory to the system on most implementations,
it doesn't matter what it does (from an object reuse point of view) since 
the only process that has access to it is the one that wrote the data there.

Even if free() did release the memory to the OS, as long as the object
reuse policy of the OS cleared the free'd pages prior to allocating them
to a new process it would meet secure system requirements.
-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/05/90)

In article <1990Oct5.002416.3196@nntp-server.caltech.edu> manning@nntp-server.caltech.edu (Evan Marshall Manning) writes:
> In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
> >     It should be noted that in secure systems, free() will clear the memory.
> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> > That would be quite amusing, since there's absolutely no concept of
> > security within C. If you can free it, you can copy it out and save it
> > first.
> You're missing the point.  Of course you can do what you like with your
> data.  But when you free() it you return it to the OS.  And anybody else
> can end up with your data when they next malloc().

And any sane operating system will zero-fill pages that it gives to a
process, rather than adding slow code to free(). And no UNIX malloc()
I've seen even tries to return memory to the system---it'll probably
just have to allocate it again. And this is comp.lang.c, where the word
``security'' means something like ``modularity'' or what might now be
called ``data hiding'' or ``object-oriented programming''.

---Dan

jtc@van-bc.wimsey.bc.ca (J.T. Conklin) (10/05/90)

In article <1990Oct5.002416.3196@nntp-server.caltech.edu> manning@nntp-server.caltech.edu (Evan Marshall Manning) writes:
>You're missing the point.  Of course you can do what you like with your
>data.  But when you free() it you return it to the OS.  And anybody else
>can end up with your data when they next malloc().

In most systems, free()ed memory is not returned to the OS, it is
placed in malloc()'s unallocated memory pool to be assigned at some
subsequent malloc().

The time that memory is typically cleared, is when malloc() cannot
satisfy a request from its pool, and has to request more from the OS
with sbrk().  The OS then clears the memory before it is passed to
the process.

	--jtc




-- 
J.T. Conklin	UniFax Communications Inc.
		...!{uunet,ubc-cs}!van-bc!jtc, jtc@wimsey.bc.ca

jbickers@templar.actrix.co.nz (John Bickers) (10/06/90)

Quoted from - kaleb@thyme.jpl.nasa.gov (Kaleb Keithley	):
> In article <1990Oct5.002416.3196@nntp-server.caltech.edu> manning@nntp-server.caltech.edu (Evan Marshall Manning) writes:
> >You're missing the point.  Of course you can do what you like with your
> >data.  But when you free() it you return it to the OS.  And anybody else
> >can end up with your data when they next malloc().
> 
> Which OS is that on?  At the risk of exhibiting "small world" syndrome,
> in UNIX, malloc and free work within the confines of the heap, which

    The Amiga's Exec, for example.

> terminates.  I'd hazard that other multi-tasking OS's like VMS behave
> similarly.

    I'd hazard that a multi-tasking OS where programs to not run in
    seperate virtual address spaces behaves similarly to Exec wrt how
    memory is allocated and deallocated.

> Kaleb Keithley                      Jet Propulsion Labs
--
*** John Bickers, TAP, NZAmigaUG.         jbickers@templar.actrix.co.nz ***
***          "All I can do now is wait for the noise." - Numan          ***

cpcahil@virtech.uucp (Conor P. Cahill) (10/06/90)

In article <1990Oct5.002416.3196@nntp-server.caltech.edu> manning@nntp-server.caltech.edu (Evan Marshall Manning) writes:
>You're missing the point.  Of course you can do what you like with your
>data.  But when you free() it you return it to the OS.  And anybody else
>can end up with your data when they next malloc().

Then it really doesn't matter whether or not free clears it since your 
process will no longer have access to it once it is freed.

In this scenario, the key point is that free() releases the memory to the
OS (something that is not done by most implementations of free() today), 
not the fact that the memory may be cleared.
-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

goudreau@dg-rtp.dg.com (Bob Goudreau) (10/06/90)

In article <5360:Oct421:09:4890@kramden.acf.nyu.edu>,
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>
> In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
> >     It should be noted that in secure systems, free() will clear
> > the memory.
> 
> That would be quite amusing, since there's absolutely no concept of
> security within C. If you can free it, you can copy it out and save
> it first.

I think what he was thinking about was that on secure operating
systems, all memory that a process used should be wiped clean before
being made available to any other process.  This prevents the other
process from being able to accidentally see data it shouldn't.
There's no problem with the *original* process copying and storing
the data somewhere else; it's his data, after all.

But as you note, this is an OS issue, not a language issue; it must
be enforced at the system call layer.  On a UNIX system, this could
be accomplished by making the sbrk() call clear memory as it is
allocated.  The free() function, even if it actually calls sbrk()
to deallocate memory (it isn't required to), need not take any
memory-wiping action.

----------------------------------------------------------------------
Bob Goudreau				+1 919 248 6231
Data General Corporation
62 Alexander Drive			goudreau@dg-rtp.dg.com
Research Triangle Park, NC  27709	...!mcnc!rti!xyzzy!goudreau
USA

kdq@demott.COM (Kevin D. Quitt) (10/06/90)

In article <5360:Oct421:09:4890@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>>     It should be noted that in secure systems, free() will clear the memory.
>
>That would be quite amusing, since there's absolutely no concept of
>security within C. If you can free it, you can copy it out and save it
>first.
>

    That's no problem.  It's what the next guy does when he gets the
memory you've freed up.  I used to do this all the time (freeing and
allocating memory) so I could examine it for all sorts of useful
information.  This may happen more than you're aware of in a paged-
memory system.  In a previous life, it was my job to break into systems
and this was one of my favorite tools.  It's amazing what people leave
in their trash!


-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

kdq@demott.COM (Kevin D. Quitt) (10/07/90)

In article <1990Oct05.020434.12344@virtech.uucp> cpcahil@virtech.uucp (Conor P. Cahill) writes:
>In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>>
>>    It should be noted that in secure systems, free() will clear the memory.
>
>There is no requirement for this.  The only requirement is that memory that 
>is made available to a process must have no information left in it
>from the previous process that used that memory. 
>
>Since free() does not release memory to the system on most implementations,
>it doesn't matter what it does (from an object reuse point of view) since 
>the only process that has access to it is the one that wrote the data there.


    If free() does not release the memory to the OS, it's less of a problem.


>Even if free() did release the memory to the OS, as long as the object
>reuse policy of the OS cleared the free'd pages prior to allocating them
>to a new process it would meet secure system requirements.

    This is not as safe as clearing it before releasing it.  An operting
system can often be coerced into giving dirty pages to a task.  Unless
the system can be mathematically proven to be immune from this, the
memory should be cleared before being released - whether it's free() or
exit() that does this makes little difference, but it must be done. 

    Paranoid? You bet! (When it's my job to be) Remember - terrorists
can get past a retinal scanner and a palm/fingerprint machine by taking
along the head and hand of someone who's been cleared. 

-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

peter@ficc.ferranti.com (Peter da Silva) (10/08/90)

In article <6573.tnews@templar.actrix.co.nz> jbickers@templar.actrix.co.nz (John Bickers) writes:
> Quoted from - kaleb@thyme.jpl.nasa.gov (Kaleb Keithley	):
> > Which OS is that on?  At the risk of exhibiting "small world" syndrome,
> > in UNIX, malloc and free work within the confines of the heap, which

>     The Amiga's Exec, for example.

In every implementation of malloc and free I know of on the Amiga, a free
does not return the pointer to the O/S. A FreeMem does, but that's not a
standard C routine. And I'm pretty sure a FreeMem doesn't scribble on the
data freed, nor does AllocMem guarantee an empty block.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

cpcahil@virtech.uucp (Conor P. Cahill) (10/08/90)

In article <688@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>In article <1990Oct05.020434.12344@virtech.uucp> cpcahil@virtech.uucp (Conor P. Cahill) writes:
>>Even if free() did release the memory to the OS, as long as the object
>>reuse policy of the OS cleared the free'd pages prior to allocating them
>>to a new process it would meet secure system requirements.
>
>    This is not as safe as clearing it before releasing it.  An operting
>system can often be coerced into giving dirty pages to a task.  Unless
>the system can be mathematically proven to be immune from this, the

As far as I remember (and that may not be that far) mathematical proof
is only required in A1 systems.  

And besides, it's just as easy to clear them at startup/acess time as it
is to clean it up at end/de-access time.

But we get away from the point.  The original posting was about whether
the original program could us a pointer obtained from malloc() after 
it was passed to free.  If it was released back to the OS, then it wouldn't
matter if it was cleared since the original program no longer has access 
to it.


-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

seanf@sco.COM (Sean Fagan) (10/08/90)

In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>    It should be noted that in secure systems, free() will clear the memory.

Uhm... says *who*?

>96.37% of all statistics are made up.

And some facts, as well, it would appear.

-- 
-----------------+
Sean Eric Fagan  | "Never knock on Death's door:  ring the bell and 
seanf@sco.COM    |   run away!  Death really hates that!"
uunet!sco!seanf  |     -- Dr. Mike Stratford (Matt Frewer, "Doctor, Doctor")
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

kdq@demott.COM (Kevin D. Quitt) (10/10/90)

In article <8058@scolex.sco.COM> seanf@sco.COM (Sean Fagan) writes:
>
>In article <623@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>>    It should be noted that in secure systems, free() will clear the memory.
>
>Uhm... says *who*?
>
>>96.37% of all statistics are made up.
>
>And some facts, as well, it would appear.

    I speak from personal experience, from systems I have developed and
worked on.  Note that I do not contend that this is necessary for normal
operation in commercial systems, or even desirable.  I was merely pointing
out yet another way that using a free()'d pointer was a lose.


-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.