CERT.EXIT.HANDLER_TERMINATE

不要从注册退出处理程序的函数中调用退出函数。

CERT.EXIT.HANDLER_TERMINATE 检查器会标记从退出处理程序函数中调用退出函数的代码。除调用 exit() 和 quick_exit() 之外,此检查器还会按照 CERT 规则 ENV32-C 的规定,标记对 longjmp() 的调用。

请注意,此检查器只会标记退出处理程序和安装该处理程序的调用处于同一编译单元的情况。

漏洞与风险

从已经进一步调用任何退出函数的退出处理程序函数调用退出函数可能会导致嵌套调用,嵌套调用退出函数属于未定义的行为。

缓解与预防

确保所有退出处理程序正常返回。

漏洞代码示例

复制
    #include <stdlib.h>

    void exit1(void)
    {
        return;
   }

    void exit2(void)
    {
       extern int some_condition;
       if (some_condition) {
           exit(0);
       }
       return;
   }

   int main(void)
   {
       if (atexit(exit1) != 0) {
           /* Handle error */
       }
       if (atexit(exit2) != 0) {
           /* Handle error */
       }
       return 0;
   }    

此不符合要求的代码示例标记了第 12 行中的 CERT.EXIT.HANDLER_TERMINATE 缺陷,因为从退出处理程序函数调用了退出,且退出处理程序函数 exit2 未正常返回。

修正代码示例

复制
   #include <stdlib.h>
  
   void exit1(void)
   {
       /* ...清理代码...*/
       return;
   }

   void exit2(void)
  {
      extern int some_condition;
      if (some_condition) {
          /* ...更多清理代码...*/
      }
      return;
  }

  int main(void)
  {
      if (atexit(exit1) != 0) {
          /* Handle error */
      }
      if (atexit(exit2) != 0) {
          /* Handle error */
      }
      /* ...程序代码...*/
      return 0;
  }

之前代码段中的问题得到了修复。在以上符合要求的示例中,退出处理程序函数 exit1 和 exit2 均正常返回。

外部指导