CONC.NO_LOCK

缺少锁定

CONC.NO_LOCK 检查器会标记没有与解锁调用对应的锁定的情况。

漏洞与风险

如果代码尝试解锁给定线程中未锁定的变量或互斥,则可能会导致意外的行为。

缓解与预防

除非由给定线程锁定,否则请勿解锁资源。

漏洞代码示例

复制
  #include <pthread.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
 
  pthread_t tid[2];
 
  void *trythis(void *arg)
 {
     pthread_mutex_t lock;
     if (pthread_mutex_init(&lock, NULL) != 0) {
         printf("\n mutex init has failed\n");
         return NULL;
     }

     pthread_mutex_unlock(&lock);

     return NULL;
 }

 int main(void)
 {
     int i = 0;
     int error;

     error = pthread_create(&(tid[i]),
                            NULL,
                            &trythis, NULL);
     if (error != 0)
         printf("\nThread can't be created :[%s]",
                strerror(error));

     pthread_join(tid[0], NULL);

     return 0;
 }

在此不符合要求的示例中,当代码尝试解锁未锁定的互斥时,Klocwork 会在第 27 行报告 CONC.NO_LOCK 缺陷。

修正代码示例

复制
  #include <pthread.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
 
  pthread_t tid[2];
 
  void *trythis(void *arg)
 {
     pthread_mutex_t lock;
     if (pthread_mutex_init(&lock, NULL) != 0) {
         printf("\n mutex init has failed\n");
         return NULL;
     }

     pthread_mutex_lock(&lock);
     pthread_mutex_unlock(&lock);

     return NULL;
 }

 int main(void)
 {
     int i = 0;
     int error;

     error = pthread_create(&(tid[i]),
                            NULL,
                            &trythis, NULL);
     if (error != 0)
         printf("\nThread can't be created :[%s]",
                strerror(error));

     pthread_join(tid[0], NULL);

     return 0;
 }

在此修正代码示例中,代码沿特定线程正确解锁已锁定的互斥。

扩展

此检查器可进行扩展。相关的知识库记录类型包括:

  • CREATETHREAD
  • LOCK_START
  • UNLOCK_START

有关详情,请参阅调整 C/C++ 分析。