diff options
author | markj <markj@FreeBSD.org> | 2015-03-10 21:08:58 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2015-03-10 21:08:58 +0000 |
commit | 564efa5c094daac4e86d36af51649ae394beb6af (patch) | |
tree | 497deb9ebfb1fb58571dce83bb7707fd4d9fdaa7 /cddl | |
parent | 3b420f99116487a23eca39c21bac65a4bb32681d (diff) | |
download | FreeBSD-src-564efa5c094daac4e86d36af51649ae394beb6af.zip FreeBSD-src-564efa5c094daac4e86d36af51649ae394beb6af.tar.gz |
CTF containers use the ctf_dtoldid field as a threshold type index which
indicates the range of type indices which have been committed to the
container by ctf_update(). However, the top bit of the dtd_type field is
not part of the type index; rather, it is a flag used to indicate that the
corresponding CTF container is a parent. This is why the maximum CTF type
index is 2^15 - 1 rather than 2^16 - 1. Therefore, this flag must be masked
off (using the CTF_TYPE_TO_INDEX macro) when comparing a type index with the
ctf_dtoldid field of a container.
This bug was causing libctf to erroneously free committed type definitions
in ctf_discard(). libdtrace holds some references to such types, resulting
in a use-after-free.
MFC after: 2 weeks
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'cddl')
-rw-r--r-- | cddl/contrib/opensolaris/common/ctf/ctf_create.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/cddl/contrib/opensolaris/common/ctf/ctf_create.c b/cddl/contrib/opensolaris/common/ctf/ctf_create.c index 41e81e5..679ed18 100644 --- a/cddl/contrib/opensolaris/common/ctf/ctf_create.c +++ b/cddl/contrib/opensolaris/common/ctf/ctf_create.c @@ -584,7 +584,7 @@ ctf_discard(ctf_file_t *fp) for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { ntd = ctf_list_prev(dtd); - if (dtd->dtd_type <= fp->ctf_dtoldid) + if (CTF_TYPE_TO_INDEX(dtd->dtd_type) <= fp->ctf_dtoldid) continue; /* skip types that have been committed */ ctf_dtd_delete(fp, dtd); @@ -1328,7 +1328,7 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) */ if (dst_type == CTF_ERR && name[0] != '\0') { for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL && - dtd->dtd_type > dst_fp->ctf_dtoldid; + CTF_TYPE_TO_INDEX(dtd->dtd_type) > dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) { if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) == kind && dtd->dtd_name != NULL && |