From a3c9d88233c349410dc50c575f72c4d7beaac162 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Fri, 29 Mar 2019 23:56:53 +0000 Subject: [PATCH] [analyzer] MIGChecker: Add support for more deallocator APIs. Differential Revision: https://reviews.llvm.org/D59914 llvm-svn: 357335 --- clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp | 22 +++++++++++++++++++ clang/test/Analysis/mig.mm | 28 +++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp index 685fd88..2565992 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp @@ -54,11 +54,33 @@ class MIGChecker : public Checker, CALL(3, 1, "mach_vm_deallocate"), CALL(2, 0, "mig_deallocate"), CALL(2, 1, "mach_port_deallocate"), + CALL(1, 0, "device_deallocate"), + CALL(1, 0, "iokit_remove_connect_reference"), + CALL(1, 0, "iokit_remove_reference"), + CALL(1, 0, "iokit_release_port"), + CALL(1, 0, "ipc_port_release"), + CALL(1, 0, "ipc_port_release_sonce"), + CALL(1, 0, "ipc_voucher_attr_control_release"), + CALL(1, 0, "ipc_voucher_release"), + CALL(1, 0, "lock_set_dereference"), + CALL(1, 0, "memory_object_control_deallocate"), + CALL(1, 0, "pset_deallocate"), + CALL(1, 0, "semaphore_dereference"), + CALL(1, 0, "space_deallocate"), + CALL(1, 0, "space_inspect_deallocate"), + CALL(1, 0, "task_deallocate"), + CALL(1, 0, "task_inspect_deallocate"), + CALL(1, 0, "task_name_deallocate"), + CALL(1, 0, "thread_deallocate"), + CALL(1, 0, "thread_inspect_deallocate"), + CALL(1, 0, "upl_deallocate"), + CALL(1, 0, "vm_map_deallocate"), // E.g., if the checker sees a method 'releaseAsyncReference64()' that is // defined on class 'IOUserClient' that takes exactly 1 argument, it knows // that the argument is going to be consumed in the sense of the MIG // consume-on-success convention. CALL(1, 0, "IOUserClient", "releaseAsyncReference64"), + CALL(1, 0, "IOUserClient", "releaseNotificationPort"), #undef CALL }; diff --git a/clang/test/Analysis/mig.mm b/clang/test/Analysis/mig.mm index 59442d3..bc43292 100644 --- a/clang/test/Analysis/mig.mm +++ b/clang/test/Analysis/mig.mm @@ -15,11 +15,15 @@ typedef unsigned vm_address_t; typedef unsigned vm_size_t; typedef void *ipc_space_t; typedef unsigned long io_user_reference_t; +typedef struct ipc_port *ipc_port_t; +typedef unsigned mach_port_t; +typedef uint32_t UInt32; kern_return_t vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t); kern_return_t mach_vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t); void mig_deallocate(vm_address_t, vm_size_t); kern_return_t mach_port_deallocate(ipc_space_t, mach_port_name_t); +void ipc_port_release(ipc_port_t); #define MIG_SERVER_ROUTINE __attribute__((mig_server_routine)) @@ -44,12 +48,17 @@ struct IOExternalMethodDispatch {}; class IOUserClient { public: static IOReturn releaseAsyncReference64(OSAsyncReference64); + static IOReturn releaseNotificationPort(mach_port_t port); MIG_SERVER_ROUTINE - virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, - IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0, void *reference = 0); -}; + virtual IOReturn externalMethod( + uint32_t selector, IOExternalMethodArguments *arguments, + IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0, + void *reference = 0); + MIG_SERVER_ROUTINE + virtual IOReturn registerNotificationPort(mach_port_t, UInt32, UInt32); +}; // Tests. @@ -182,6 +191,13 @@ kern_return_t test_mig_deallocate(vm_address_t address, vm_size_t size) { // expected-note@-1{{MIG callback fails with error after deallocating argument value}} } +MIG_SERVER_ROUTINE +kern_return_t test_ipc_port_release(ipc_port_t port) { + ipc_port_release(port); // expected-note{{Value passed through parameter 'port' is deallocated}} + return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}} + // expected-note@-1{{MIG callback fails with error after deallocating argument value}} +} + // Let's try the C++11 attribute spelling syntax as well. [[clang::mig_server_routine]] IOReturn test_releaseAsyncReference64(IOExternalMethodArguments *arguments) { @@ -206,4 +222,10 @@ class MyClient: public IOUserClient { return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}} // expected-note@-1{{MIG callback fails with error after deallocating argument value}} } + + IOReturn registerNotificationPort(mach_port_t port, UInt32 x, UInt32 y) { + releaseNotificationPort(port); // expected-note{{Value passed through parameter 'port' is deallocated}} + return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}} + // expected-note@-1{{MIG callback fails with error after deallocating argument value}} + } }; -- 2.7.4