Memory leak in CFNetwork (PACClient/PACQuery) when using NETransparentProxyProvider with Auto Proxy Discovery enabled

Hello,

I have encountered unexpected behavior when running a Network Extension that implements NETransparentProxyProvider. This extension is part of a DLP (Data Loss Prevention) solution. If the "Auto proxy discovery" option is enabled for the Wi-Fi connection on the managed host, the leaks tool reports memory leaks with the following root cycles:

...
      11 (1.03K) ROOT CYCLE: <CFRunLoopSource 0xa430cc540> [192]
         10 (864 bytes) ROOT CYCLE: <std::__shared_ptr_emplace<PAC::PACClient> 0xa430f4000> [224]
            CYCLE BACK TO <CFRunLoopSource 0xa430cc540> [192]
            6 (400 bytes) ROOT CYCLE: <std::__shared_ptr_emplace<PAC::PACQuery> 0xa43118080> [128]
               2 (80 bytes) ROOT CYCLE: 0xa42ca9000 [32]
                  1 (48 bytes) ROOT CYCLE: <__NSMallocBlock__ 0xa42804de0> [48]  CFNetwork  invocation function for block in PAC::PACClient::initialize(void const*, __CFURL cons..."
               1 (32 bytes) ROOT CYCLE: <std::__shared_ptr_pointer<BlockHolderVar<__CFString const*, __CFData const*, std::shared_ptr<__CFArray const>, std::shared_ptr<__CFError>>*, SmartBlockWithArgs<__CFString const*, __CFData const*, std::shared_ptr<__CFArray const>, std::shared_ptr<__CFError>>::Deleter> 0xa4343da80> [32]
               2 (160 bytes) <NSURL 0xa42840310> [112]
                  1 (48 bytes) _clients --> <CFString 0xa42c08fc0> [48]
            1 (160 bytes) <NWConcrete_nw_pac_resolver 0xa4280cb40> [160]
            1 (48 bytes) <CFError 0xa42804ed0> [48]
            1 (32 bytes) <std::__shared_ptr_pointer<__CFError*, Deleter_CFRelease> 0xa4343dc20> [32]
...
      11 (1.03K) ROOT CYCLE: <CFRunLoopSource 0xa43128540> [192]
         10 (864 bytes) ROOT CYCLE: <std::__shared_ptr_emplace<PAC::PACClient> 0xa430f4a80> [224]
            CYCLE BACK TO <CFRunLoopSource 0xa43128540> [192]
            6 (400 bytes) ROOT CYCLE: <std::__shared_ptr_emplace<PAC::PACQuery> 0xa43118880> [128]
               2 (80 bytes) ROOT CYCLE: 0xa428105e0 [32]
                  1 (48 bytes) ROOT CYCLE: <__NSMallocBlock__ 0xa428887b0> [48]  CFNetwork  invocation function for block in PAC::PACClient::initialize(void const*, __CFURL cons..."
               1 (32 bytes) ROOT CYCLE: <std::__shared_ptr_pointer<BlockHolderVar<__CFString const*, __CFData const*, std::shared_ptr<__CFArray const>, std::shared_ptr<__CFError>>*, SmartBlockWithArgs<__CFString const*, __CFData const*, std::shared_ptr<__CFArray const>, std::shared_ptr<__CFError>>::Deleter> 0xa4343f5c0> [32]
               2 (160 bytes) <NSURL 0xa428424c0> [112]
                  1 (48 bytes) _clients --> <CFString 0xa42c0a640> [48]
            1 (160 bytes) <NWConcrete_nw_pac_resolver 0xa4280d7c0> [160]
            1 (48 bytes) <CFError 0xa42888390> [48]
            1 (32 bytes) <std::__shared_ptr_pointer<__CFError*, Deleter_CFRelease> 0xa4343f4c0> [32]
...

The extension creates an nw_connection_t to the remote host for each handled flow like this:

  nw_parameters_t parameters = nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION);
    nw_endpoint_t connectTo = nw_endpoint_create_host([endpoint.hostname UTF8String], [endpoint.port UTF8String]);
    nw_connection_t connection = nw_connection_create(connectTo, parameters);

When "Auto proxy discovery" is disabled, everything works as expected, and no memory leaks or issues are observed. Could you please advise on how to resolve or work around this issue?

Thank you in advance!

Answered by ___Pavel___ in 904151022

Thank you for the help!

The resource leak issue is gone after the update. The issue is no longer reproducible.

Accepted Answer

This is ringing some bells, but I wasn’t able to track down the place where I’ve seen it before.

But the answer here is pretty much always the system. If the system is leaking objects of a type that you’ve never touched, it’s most likely a bug in the system rather than a bug in your code. Normally I’d send you straight off to file a bug, but in this case I think it’d be worthwhile for you to test on the latest system (including the latest macOS 27 beta) to make sure we’ve not fixed it already.

If you do file a bug, please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the help!

The resource leak issue is gone after the update. The issue is no longer reproducible.

Memory leak in CFNetwork (PACClient/PACQuery) when using NETransparentProxyProvider with Auto Proxy Discovery enabled
 
 
Q