summaryrefslogtreecommitdiff
path: root/debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-08-31 18:23:51 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-08-31 18:23:51 +0200
commit4c61c7c157581cd3d9cb89d1bc8ddf23bbffda4a (patch)
tree25cc7727f4f07c372e47cdd5768a6903d73c32b4 /debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch
parentf5e1f18a41e2d56542515b26c30d43b04295740a (diff)
add patch series
Diffstat (limited to 'debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch')
-rw-r--r--debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch b/debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch
new file mode 100644
index 00000000..49121824
--- /dev/null
+++ b/debian/patches/0001-include-detect-use-after-free-errors-using-the-refer.patch
@@ -0,0 +1,116 @@
+From 940c8c530cb0070d1a2a68c9564d660d1bdd0a22 Mon Sep 17 00:00:00 2001
+From: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Fri, 20 Jun 2014 14:27:59 +0200
+Subject: [PATCH] include: detect use-after-free errors using the reference
+ counts
+
+* include/refcount.h (refcount_init): There must be at least one
+reference at initialization time.
+(refcounts_init): Likewise.
+(refcount_unsafe_ref): New function.
+(refcount_ref): Detect use-after-free errors.
+(refcounts_ref): Likewise.
+(refcounts_ref_weak): Likewise.
+* libtrivfs/protid-clean.c (trivfs_clean_protid): Use refcount_unsafe_ref.
+---
+ include/refcount.h | 30 ++++++++++++++++++++++++++----
+ libtrivfs/protid-clean.c | 2 +-
+ 2 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/include/refcount.h b/include/refcount.h
+index 785b052..1db50e7 100644
+--- a/include/refcount.h
++++ b/include/refcount.h
+@@ -31,18 +31,22 @@
+ /* An opaque type. You must not access these values directly. */
+ typedef unsigned int refcount_t;
+
+-/* Initialize REF with REFERENCES. */
++/* Initialize REF with REFERENCES. REFERENCES must not be zero. */
+ static inline void
+ refcount_init (refcount_t *ref, unsigned int references)
+ {
++ assert (references > 0 || !"references must not be zero!");
+ *ref = references;
+ }
+
+ /* Increment REF. Return the result of the operation. This function
+ uses atomic operations. It is not required to serialize calls to
+- this function. */
++ this function.
++
++ This is the unsafe version of refcount_ref, which also checks for
++ use-after-free errors. When in doubt, use that one instead. */
+ static inline unsigned int
+-refcount_ref (refcount_t *ref)
++refcount_unsafe_ref (refcount_t *ref)
+ {
+ unsigned int r;
+ r = __atomic_add_fetch (ref, 1, __ATOMIC_RELAXED);
+@@ -50,6 +54,18 @@ refcount_ref (refcount_t *ref)
+ return r;
+ }
+
++/* Increment REF. Return the result of the operation. This function
++ uses atomic operations. It is not required to serialize calls to
++ this function. */
++static inline unsigned int
++refcount_ref (refcount_t *ref)
++{
++ unsigned int r;
++ r = refcount_unsafe_ref (ref);
++ assert (r != 1 || !"refcount detected use after free!");
++ return r;
++}
++
+ /* Decrement REF. Return the result of the operation. This function
+ uses atomic operations. It is not required to serialize calls to
+ this function. */
+@@ -101,10 +117,12 @@ union _references {
+ uint64_t value;
+ };
+
+-/* Initialize REF with HARD and WEAK references. */
++/* Initialize REF with HARD and WEAK references. HARD and WEAK must
++ not both be zero. */
+ static inline void
+ refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak)
+ {
++ assert ((hard != 0 || weak != 0) || !"references must not both be zero!");
+ ref->references = (struct references) { .hard = hard, .weak = weak };
+ }
+
+@@ -119,6 +137,8 @@ refcounts_ref (refcounts_t *ref, struct references *result)
+ union _references r;
+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+ assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
++ assert (! (r.references.hard == 1 && r.references.weak == 0)
++ || !"refcount detected use after free!");
+ if (result)
+ *result = r.references;
+ }
+@@ -208,6 +228,8 @@ refcounts_ref_weak (refcounts_t *ref, struct references *result)
+ union _references r;
+ r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+ assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
++ assert (! (r.references.hard == 0 && r.references.weak == 1)
++ || !"refcount detected use after free!");
+ if (result)
+ *result = r.references;
+ }
+diff --git a/libtrivfs/protid-clean.c b/libtrivfs/protid-clean.c
+index adc5e98..ff6cc16 100644
+--- a/libtrivfs/protid-clean.c
++++ b/libtrivfs/protid-clean.c
+@@ -36,7 +36,7 @@ trivfs_clean_protid (void *arg)
+ if (refcount_deref (&cred->po->refcnt) == 0)
+ {
+ /* Reacquire a reference while we call the hook. */
+- refcount_ref (&cred->po->refcnt);
++ refcount_unsafe_ref (&cred->po->refcnt);
+ (*trivfs_peropen_destroy_hook) (cred->po);
+ if (refcount_deref (&cred->po->refcnt) == 0)
+ {
+--
+2.1.0
+