CHECK_ACCESS inner pointers using the new __unmangle_inner_ptr meth
authorMatt Corallo <git@bluematt.me>
Mon, 29 Nov 2021 01:03:22 +0000 (01:03 +0000)
committerMatt Corallo <git@bluematt.me>
Wed, 1 Dec 2021 14:14:13 +0000 (14:14 +0000)
gen_type_mapping.py
genbindings.py
genbindings.sh
java_strings.py
typescript_strings.py

index 39ee2605a88804d24ef707c468ded6d84aed760c..01bd92914b01dc857a5ca1b9a432889b5c8ef147 100644 (file)
@@ -257,9 +257,10 @@ class TypeMappingGenerator:
                 opaque_arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv;\n"
                 opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.inner = (void*)(" + ty_info.var_name + " & (~1));\n"
                 if ty_info.is_ptr and holds_ref:
-                    opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.is_owned = false;"
+                    opaque_arg_conv += ty_info.var_name + "_conv.is_owned = false;\n"
                 else:
-                    opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.is_owned = (" + ty_info.var_name + " & 1) || (" + ty_info.var_name + " == 0);"
+                    opaque_arg_conv += ty_info.var_name + "_conv.is_owned = (" + ty_info.var_name + " & 1) || (" + ty_info.var_name + " == 0);\n"
+                opaque_arg_conv += "CHECK_INNER_FIELD_ACCESS_OR_NULL(" + ty_info.var_name + "_conv);"
                 if not is_free and (not ty_info.is_ptr or not holds_ref or ty_info.requires_clone == True) and ty_info.requires_clone != False:
                     if (ty_info.rust_obj.replace("LDK", "") + "_clone") in self.clone_fns:
                         # TODO: This is a bit too naive, even with the checks above, we really need to know if rust wants a ref or not, not just if its pass as a ptr.
@@ -290,6 +291,7 @@ class TypeMappingGenerator:
 
                 opaque_ret_conv_suf += indent + "CHECK((((uint64_t)" + ty_info.var_name + "_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.\n"
                 opaque_ret_conv_suf += indent + "CHECK((((uint64_t)&" + ty_info.var_name + "_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.\n"
+                opaque_ret_conv_suf += "CHECK_INNER_FIELD_ACCESS_OR_NULL(" + ty_info.var_name + "_var);\n"
                 if holds_ref:
                     opaque_ret_conv_suf += indent + ty_info.var_name + "_ref = (uint64_t)" + ty_info.var_name + "_var.inner & ~1;"
                 else:
index 042f5b92f4d92e061dfaa69e74a109e561a972bd..1d01ac6cff1f16a16fc48073f9defd98705acf0a 100755 (executable)
@@ -402,6 +402,9 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}",
         method_comma_separated_arguments = re_match.group(3)
         method_arguments = method_comma_separated_arguments.split(',')
 
+        if method_name.startswith("__"):
+            return
+
         is_free = method_name.endswith("_free")
         if method_name.startswith("COption") or method_name.startswith("CResult"):
             struct_meth = method_name.rsplit("Z", 1)[0][1:] + "Z"
index 912cc1cdce44e892d349291de5a179c064f67a7c..13f4c6c3e1179ef1700a30dccd57510ac72d803c 100755 (executable)
@@ -78,7 +78,15 @@ if [ "$4" = "true" ]; then
 else
        ./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG java $4
 fi
-echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" > src/main/jni/bindings.c
+rm -f src/main/jni/bindings.c
+if [ "$3" = "true" ]; then
+       echo "#define LDK_DEBUG_BUILD" > src/main/jni/bindings.c
+elif [ "$3" = "leaks" ]; then
+       # For leak checking we use release libldk which doesn't expose
+       # __unmangle_inner_ptr, but the C code expects to be able to call it.
+       echo "#define __unmangle_inner_ptr(a) (a)" > src/main/jni/bindings.c
+fi
+echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> src/main/jni/bindings.c
 echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> src/main/jni/bindings.c
 cat src/main/jni/bindings.c.body >> src/main/jni/bindings.c
 javac -h src/main/jni src/main/java/org/ldk/enums/*.java src/main/java/org/ldk/impl/*.java
index a83671db48a27c1d23cd9e3875d5736765afca88..6e77fc347569a5145ef50e6e48b2575c9965b177 100644 (file)
@@ -163,6 +163,7 @@ void __attribute__((constructor)) spawn_stderr_redirection() {
             self.c_file_pfx = self.c_file_pfx + """#define MALLOC(a, _) malloc(a)
 #define FREE(p) if ((uint64_t)(p) > 4096) { free(p); }
 #define CHECK_ACCESS(p)
+#define CHECK_INNER_FIELD_ACCESS_OR_NULL(v)
 """
         if not DEBUG:
             self.c_file_pfx += """#define DO_ASSERT(a) (void)(a)
@@ -319,7 +320,7 @@ void __wrap_free(void* ptr) {
        __real_free(ptr);
 }
 
-static void CHECK_ACCESS(void* ptr) {
+static void CHECK_ACCESS(const void* ptr) {
        DO_ASSERT(!pthread_mutex_lock(&allocation_mtx));
        allocation* it = allocation_ll;
        while (it->ptr != ptr) {
@@ -336,6 +337,13 @@ static void CHECK_ACCESS(void* ptr) {
        }
        DO_ASSERT(!pthread_mutex_unlock(&allocation_mtx));
 }
+#define CHECK_INNER_FIELD_ACCESS_OR_NULL(v) \\
+       if (v.is_owned && v.inner != NULL) { \\
+               const void *p = __unmangle_inner_ptr(v.inner); \\
+               if (p != NULL) { \\
+                       CHECK_ACCESS(p); \\
+               } \\
+       }
 
 void* __real_realloc(void* ptr, size_t newlen);
 void* __wrap_realloc(void* ptr, size_t len) {
index 270eeccc85c30ad486e782abc82509f5b62c35b4..8a83ae4a44ff339f9821c1866d5d2545817ca532 100644 (file)
@@ -124,6 +124,7 @@ void free(void *ptr);
 #define DO_ASSERT(a) (void)(a)
 #define CHECK(a)
 #define CHECK_ACCESS(p)
+#define CHECK_INNER_FIELD_ACCESS_OR_NULL(v)
 """
         else:
             self.c_file_pfx = self.c_file_pfx + """
@@ -189,6 +190,13 @@ static void CHECK_ACCESS(void* ptr) {
                }
        }
 }
+#define CHECK_INNER_FIELD_ACCESS_OR_NULL(v) \\
+       if (v.is_owned && v.inner != NULL) { \\
+               const void *p = __unmangle_inner_ptr(v.inner); \\
+               if (p != NULL) { \\
+                       CHECK_ACCESS(p); \\
+               } \\
+       }
 
 void* __wrap_malloc(size_t len) {
        void* res = __real_malloc(len);