代码之家  ›  专栏  ›  技术社区  ›  wishi

安全C和大学-针对缓冲区溢出进行培训

  •  3
  • wishi  · 技术社区  · 16 年前

    我最近完成了C的大学课程。因此,我当然缺乏经验。

    一些大学倾向于教学生安全编程, or at least some elements even a video (取自 here ).

    在C中,复制字符串需要-据我所知-strcpy或string.h函数。你如何在日常编程中安全地使用它? 您是否有一些函数来处理分配以防止缓冲区溢出?这就是 CERT secure coding standard for C 。它提供了示例和合规解决方案:

    int main(int argc, char *argv[]) {
      /* ... */
      char prog_name[128];
      strcpy(prog_name, argv[0]);
      /* ... */
    }
    

    他们的替代方案是:

    int main(int argc, char *argv[]) {
      /* ... */
      char *prog_name = (char *)malloc(strlen(argv[0])+1);
      if (prog_name != NULL) {
        strcpy(prog_name, argv[0]);
      }
      else {
        /* Couldn't get the memory - recover */
      }
      /* ... */
    }
    

    从这里拍摄, 2nd example .

    但据我所知,这只是更具挑战性,更多的代码,更多的工作。为什么没有人改变库本身?或者至少为什么没有人提供一个安全的替代库或函数,以正确的方式处理这个问题?

    感谢您的阅读, wishi

    7 回复  |  直到 16 年前
        1
  •  9
  •   sth    16 年前

    Posix功能(几乎在每个系统上都可用)是 strdup() . strcpy() 如果您不想分配新内存,并且已经有一个要使用的缓冲区,但您更清楚该缓冲区有多大,以及字符串是否适合它,则可以使用。如果您不知道字符串是否适合,则可以 strncpy() 它只复制给定数量的字符。因此,您可以将复制量限制在缓冲区大小。

    除此之外,还有许多以不同方式管理字符串大小的字符串库。

    既然你把它标记为C++: std::string 这为您完成了所有的内存管理,不会给您带来这些问题。

        2
  •  2
  •   user14554 user14554    16 年前

    这个 字母 l(英语字母表中的第十二个字母) (strlcpy,strlcat)函数来自 OpenBSD 通常比 n 函数,它们既更快又更容易安全地使用,但它们是非标准的。然而,它们是BSD许可的,所以你可以在任何程序中包含一个已知的良好实现,这样你就可以跨平台和安全。

    对于Windows,如果你不关心可移植性,你可以使用*_s函数。

        3
  •  2
  •   David Schmitt    16 年前

    使用 strncpy :

    #define BUFSIZE 127
    int main(int argc, char *argv[]) {
      /* ... */
      char prog_name[BUFSIZE + 1];
      strncpy(prog_name, argv[0], BUFSIZE);
      progname[BUFSIZE]= '\0';
      /* ... */
    }
    

    *n* 大多数版本 str* 功能。

        4
  •  1
  •   Uri    16 年前

    如果我理解正确的话,你真正的问题是为什么API函数没有变得更安全。

    一个原因是C库是遗留的(现在更改它为时已晚)。

    然而,主要原因是该库的设计是极简主义的,因此它只做了最少的工作,用户有责任确保它被正确调用。如果它进行了过多的检查,那么每次调用时都会支付一笔费用,即使用户可以出于其他原因保证不会出现问题。这在许多API中非常常见。

    话虽如此,有足够多的库提供更安全的替代方案,它们只是不是标准库的一部分。此外,许多从事高级工作的人都使用C++,C++有许多标准类库。

        5
  •  0
  •   OregonGhost    16 年前

    事实上,微软确实提供了CRT功能的安全替代方案。不过,我认识的每个人都讨厌它们,并禁用了不应该使用旧函数的警告。如果你想要安全的东西,也许你应该使用C++。然后是STL字符串或类似Qt的东西。

    好吧,或者你去像这样的平台。NET或Java,通常不会出现这些问题(您的应用程序可能会崩溃,但无法通过缓冲区溢出将代码注入到应用程序中)。

    编辑: 启用数据执行保护/NX(Vista和.NET的默认设置)后,这对传统平台来说也应该不是问题。

        6
  •  0
  •   EvilTeach    16 年前
    int main
    (
        int argc, 
        char *argV[]
    ) 
    {
       char prog_name[128];
       if (strlen(argV[0]) < sizeof(prog_name))
       {
           strcpy(prog_name, argV[0]);
       }
       else
       {
           printf("%s is too large for the internal buffer\n", argV[0]);
       }
    
       return 0;
    }
    
        7
  •  0
  •   Community CDub    8 年前

    也许你会找到有用的阅读答案 this question