安全工具扫描问题 - 无防护的 Java 写入

问题描述

我有一个如下格式的java文件

 class Demo {
      private static Logger logger;
      ...
      ...
      public static void main(){
        // code to initialize logger
        demoMethod()
      }

      private int demoMethod { 
          
          synchronized (tmpObj) {
            ...
            helperMethod(tmpParam);
            // some more logic of demoMethod related to file reading
            
            logger.log("message from demo method");
            ...
            //there is more logic that involves more loggers
          }
      }

      private int helperMethod(int tmp){
          //some logic of helperMethod related to Files
          if(condition) {
             logger.log("message from helperMethod");
          }
          return 1;
      }
 }

从上面的代码蓝图可以看出,我在 demoMethod(它有一个同步块)和 helpMethod 中都有记录器。现在我遇到的问题是

Unguarded read missing_lock:在没有持有锁 TempClassName.tmpObj 的情况下访问记录器在其他地方,记录器在 12 次中有 8 次被持有 TempClassName.tmpObj 访问。

我不太确定是什么导致了这个问题,因为我使用的记录器是线程安全的。任何人都可以就可能导致此问题的原因提供更多见解。

解决方法

此报告的主要原因是:“在其他地方,12 次中有 8 次使用 TempClassName.tmpObject 访问记录器。”也就是说,在源代码中的 12 个文本位置访问(读取或写入,但不包括初始化)成员 logger,并且对于其中的 8 个位置,已知 tmpObject 锁由正在执行的线程。因此,该工具得出结论,程序员的意图是 tmpObject 必须持有才能访问 logger。显然,12 个中有 8 个高于将关联视为不仅仅是巧合的可配置阈值。因此,该工具会将与模式的偏差报告为可能的错误。我天真地希望 logger 总共有 4 个报告,您引用的就是其中一个(尽管可能会因存在不同的可能调用路径而变得复杂)。

这可能是误报。这个检查器对同步问题没有深入的理解,它只是从它在代码中发现的模式推断出来。如果,如您所说,Logger 类是线程安全的,并且 logger 成员本身没有读/写或写/写危险,那么它应该可以安全地将此报告视为虚假消息。

此外,请注意,在您提供的代码片段中,helperMethodprivate,仅被调用一次,并且该调用站点本身位于 synchronized 块内。如果真实代码没有任何其他调用点,那么这可能只是 Coverity 工具中的一个错误,因为 helperMethod 中的访问总是在持有锁时发生,并且该工具应该意识到这一点事实。

但还有一个问题:你引用的消息引用了tmpObject,而你发布的代码引用了tmpObj,它们是不同的名称。这只是您帖子中的一个错字,还是真正的代码实际上有两个不同的“临时对象”在四处乱跑造成混乱?如果是这样,那可能才是真正的问题。

撇开这份报告的细节不谈,请注意 Java 并发性比起初看起来要困难得多和微妙得多。如果您不精通该主题(首先,您是否对“之前发生过”有深入了解?),请在驳回报告之前咨询正在研究或进行一些额外研究的人。这个检查器的理解可能很肤浅,但根据我的经验,在它标记的任何代码中仔细检查并发的使用通常是值得的。

披露:我之前受雇于 Synopsys/Coverity,并帮助构建 Coverity 工具。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...