Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
76ae790f
Commit
76ae790f
authored
Nov 21, 2009
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New talloc_set for auto-cleanup.
parent
f88058f6
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
105 additions
and
0 deletions
+105
-0
ccan/talloc/talloc.c
ccan/talloc/talloc.c
+29
-0
ccan/talloc/talloc.h
ccan/talloc/talloc.h
+25
-0
ccan/talloc/test/compile_fail-talloc_set.c
ccan/talloc/test/compile_fail-talloc_set.c
+15
-0
ccan/talloc/test/run-talloc_set.c
ccan/talloc/test/run-talloc_set.c
+36
-0
No files found.
ccan/talloc/talloc.c
View file @
76ae790f
...
...
@@ -789,6 +789,35 @@ void *_talloc(const void *context, size_t size)
return
__talloc
(
context
,
size
);
}
static
int
talloc_destroy_pointer
(
void
***
pptr
)
{
if
((
uintptr_t
)
**
pptr
<
getpagesize
())
TALLOC_ABORT
(
"Double free or invalid talloc_set?"
);
/* Invalidate pointer so it can't be used again. */
**
pptr
=
(
void
*
)
1
;
return
0
;
}
void
_talloc_set
(
void
*
ptr
,
const
void
*
ctx
,
size_t
size
,
const
char
*
name
)
{
void
***
child
;
void
**
pptr
=
ptr
;
*
pptr
=
talloc_named_const
(
ctx
,
size
,
name
);
if
(
unlikely
(
!*
pptr
))
return
;
child
=
talloc
(
*
pptr
,
void
**
);
if
(
unlikely
(
!
child
))
{
talloc_free
(
*
pptr
);
*
pptr
=
NULL
;
return
;
}
*
child
=
pptr
;
talloc_set_name_const
(
child
,
"talloc_set destructor"
);
talloc_set_destructor
(
child
,
talloc_destroy_pointer
);
}
/*
externally callable talloc_set_name_const()
*/
...
...
ccan/talloc/talloc.h
View file @
76ae790f
...
...
@@ -87,6 +87,30 @@
*/
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
/**
* talloc_set - allocate dynamic memory for a type, into a pointer
* @ptr: pointer to the pointer to assign.
* @ctx: context to be parent of this allocation, or NULL.
*
* talloc_set() does a talloc, but also adds a destructor which will make the
* pointer invalid when it is freed. This can find many use-after-free bugs.
*
* Note that the destructor is chained off a zero-length allocation, and so
* is not affected by talloc_set_destructor().
*
* Example:
* unsigned int *a;
* a = talloc(NULL, unsigned int);
* talloc_set(&b, a, unsigned int);
* talloc_free(a);
* *b = 1; // This will crash!
*
* See Also:
* talloc.
*/
#define talloc_set(pptr, ctx) \
_talloc_set((pptr), (ctx), sizeof(&**(pptr)), __location__)
/**
* talloc_free - free talloc'ed memory and its children
* @ptr: the talloced pointer to free
...
...
@@ -940,6 +964,7 @@ void *talloc_add_external(const void *ctx,
/* The following definitions come from talloc.c */
void
*
_talloc
(
const
void
*
context
,
size_t
size
);
void
_talloc_set
(
void
*
ptr
,
const
void
*
ctx
,
size_t
size
,
const
char
*
name
);
void
_talloc_set_destructor
(
const
void
*
ptr
,
int
(
*
destructor
)(
void
*
));
size_t
talloc_reference_count
(
const
void
*
ptr
);
void
*
_talloc_reference
(
const
void
*
context
,
const
void
*
ptr
);
...
...
ccan/talloc/test/compile_fail-talloc_set.c
0 → 100644
View file @
76ae790f
#include "talloc/talloc.c"
int
main
(
void
)
{
int
*
p
;
talloc_set
(
#ifdef FAIL
p
#else
&
p
#endif
,
NULL
);
return
0
;
}
ccan/talloc/test/run-talloc_set.c
0 → 100644
View file @
76ae790f
#include "talloc/talloc.c"
#include "tap/tap.h"
#include <assert.h>
int
main
(
void
)
{
char
*
c
;
int
*
i
;
plan_tests
(
12
);
/* Set C to a valid pointer, with correct parent. */
talloc_set
(
&
c
,
NULL
);
ok1
(
c
>=
(
char
*
)(
intptr_t
)
getpagesize
());
ok1
(
talloc_parent
(
c
)
==
NULL
);
/* Free it, should blatt c. */
talloc_free
(
c
);
ok1
(
c
);
ok1
(
c
<
(
char
*
)(
intptr_t
)
getpagesize
());
/* Same test, indirect. */
talloc_set
(
&
i
,
NULL
);
talloc_set
(
&
c
,
i
);
ok1
(
c
>=
(
char
*
)(
intptr_t
)
getpagesize
());
ok1
(
i
>=
(
int
*
)(
intptr_t
)
getpagesize
());
ok1
(
talloc_parent
(
i
)
==
NULL
);
ok1
(
talloc_parent
(
c
)
==
i
);
talloc_free
(
i
);
ok1
(
c
);
ok1
(
c
<
(
char
*
)(
intptr_t
)
getpagesize
());
ok1
(
i
);
ok1
(
i
<
(
int
*
)(
intptr_t
)
getpagesize
());
return
exit_status
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment