API滥用(Apple):尝试释放尚未分配的数据

时间:2014-04-07 02:35:39

标签: objective-c macos static-analysis keychain

An app我正在使用登录钥匙串中的简单密码项工作。我注意到有一个SecKeychainItemRef从未被释放。 official documentation on SecKeychainFindGenericPassword()读取:

  

返回时,指向通用密码的项目对象的指针。您有责任发布对此对象的引用。

经过一些快速更改后,静态代码分析器声称:

  1. 假设'结果'等于noErr
  2. 假设'项目'是非空的
  3. 尝试释放尚未分配的数据
  4. 我对我如何假设结果等于noErr感到茫然,因为有一个else子句。不太确定我假设item是非null的,也不确定我如何释放未分配的数据,因为它已被选中(if (item))。

    警告和代码列表

    的屏幕截图

    Screenshot of the warning and code listing

    代码清单

    这是关于GitHub的Hermes项目的part of

    BOOL KeychainSetItem(NSString* username, NSString* password) {
      SecKeychainItemRef item;
      OSStatus result = SecKeychainFindGenericPassword(
        NULL,
        strlen(KEYCHAIN_SERVICE_NAME),
        KEYCHAIN_SERVICE_NAME,
        [username length],
        [username UTF8String],
        NULL,
        NULL,
        &item);
    
      if (result == noErr) {
        result = SecKeychainItemModifyContent(item, NULL, [password length],
                                              [password UTF8String]);
        return result == noErr;
      } else {
        result = SecKeychainAddGenericPassword(
          NULL,
          strlen(KEYCHAIN_SERVICE_NAME),
          KEYCHAIN_SERVICE_NAME,
          [username length],
          [username UTF8String],
          [password length],
          [password UTF8String],
          NULL);
    
        return result == noErr;
      }
    }
    

    BOOL KeychainSetItem(NSString* username, NSString* password) {
      SecKeychainItemRef item = nil;
      OSStatus result = SecKeychainFindGenericPassword(
        NULL,
        strlen(KEYCHAIN_SERVICE_NAME),
        KEYCHAIN_SERVICE_NAME,
        [username length],
        [username UTF8String],
        NULL,
        NULL,
        &item);
    
      if (result == noErr) {
        result = SecKeychainItemModifyContent(item, NULL, [password length],
                                              [password UTF8String]);
      } else {
        result = SecKeychainAddGenericPassword(
          NULL,
          strlen(KEYCHAIN_SERVICE_NAME),
          KEYCHAIN_SERVICE_NAME,
          [username length],
          [username UTF8String],
          [password length],
          [password UTF8String],
          NULL);
      }
    
      if (item) {
        SecKeychainItemFreeContent(NULL, item);
      }
      return result == noErr;
    }
    

1 个答案:

答案 0 :(得分:1)

SecKeychainItemRef个变量 CoreFoundation引用计数。从静态代码分析器的角度来看,在SecKeychainItemFreeContent()上调用SecKeychainItemRef相当于释放未分配的数据,因为它没有被SecKeychain函数分配。

通过CFRelease()变量(而不是SecKeychainItemRef)调用SecKeychainItemFreeContent(),所有错误都消失了。