zoukankan      html  css  js  c++  java
  • 安全编码 笔记简单摘要《C和C++安全编码(原书第2版)》

    常见字符串操作错误

    场景

    注解

    无界字符串复制

    1、无界字符串复制发生于从源数据复制数据到一个定长的字符数组时

    2、复制和连接字符串。复制和连接字符串时也容易出现错误,因为执行这个功能的许多标准库调用,如strcpy()  strcat()和sprJntf()函数,执行无界复制操作。

    主要考虑目的数据的可容纳空间大小。

    差一错误(off-by-one error)

    差一错误与无界 字符串复制有相似之处.即都涉及对数组的越界写问题。

    复制循环多一次或少一次。

    空字符结尾错误

    空字符结尾的字符串的另一个常见问题,根据C标准,strncpy()函数从源数组复制不超过n个字符。

    字符串未能正确的以空字符结尾。

    字符串截断

    目标字符数组长度不足以容纳一个字符串内容时。

     

    • 要检测和处理输入输出错误
    • 容易发生缓冲区溢出的问题

    □将字符串定义为以空字符结尾的字符数组

    □未进行隐式的边界检査

    □提供了未强制性边界检査的标准字符串函数调用

     

    字符串漏洞缓解办法:

    《C安全编码标准》[Seacord 2008], 44 STR01-C.采用并实现一个管理字符串的一致计划” 建议选择一种方法来处理字符串并在项目中始终如一地执行。否则,决定权就落到了单个程序员身上,他们很可能采取不同、不一致的方法。

    atexit函数 cyg_libc_invoke_atexit_handlers由exit函数调用,该函数调用被atexit注册过的函数。

    常见的与内存管理相关 的编程缺陷包括:初始化错误、未检查返回值、对空指针或无效指针解引用、引用已释放的 内存、对同一块内存释放多次、内存泄漏和零长度分配。

    常见内存管理错误

    现象

    备注

    初始化错误

    通常用函数malloc(〉分配内存块。由malloc()返回的空间中的值是不确定的。

    1、一个常见的错误是不正确地假设malloc()把分配的内存的所有位都初始化为零。《C安全编码标 准》[Seacord 2008] "MEM09-C.不要假定内存分配函数初始化内存”进一步描述了这个问题。 未能遵循这一建议可能会导致违反“EXP33・C.不要引用未初始化的内存”。

    2、正如《C安全编码标准》[Seacord 2008]中的MEM03-C推荐的:“清 除存储在可重复使用的资源中的敏感信息”清除或覆写内存通常是通过调用C标准的 memset() 数来完成的。遗憾的是,如果不在写后访问内存,编译器优化可能会默默地删 除对memset()的调用。为了避免这种可能性,你可以使用C标准附录K (如果可用)中 定义的memset_s()函数。不同于memset(), memset_s()函数假定被设置的内存可能 会在未来被访问,因此这个函数调用不能被优化掉。详情参见《C安全编码标准》[Seacord 2008] “MSC06・C.处理敏感数据时,要注意编译器优化"以获得更多信息。

    free与malloc都不需要清除内存。

    未检查返回值

    编写应用程序的程序员必须确定何时发生了错误,并以适当的方式处理该错误。因此, 《C安全编码标准》[Seacord 2008] ° MEM32-C.检测和处理内存分配错误”要求检测并妥善管理这些错误。

     

    NULL或无效指针的访问(解引用)

    确保malloc返回的不是空指针。不要执行0长度分配

     

    引用已释放的内存

     

    free无法把它的指针参数设置为NULL。因为它需要一个void **类型的参数,而不是void *类型的参数

    多次释放内存

     

    释放(double-free)这个错误是危险的,因为它会以一种不会立即显现的方式破坏内存管理 器中的数据结构。因为许多程序员没有意识到,多次释放相同的内存会导致可以利用的漏洞, 从而加剧了这个问题的危险性。

    内存泄漏、0长度分配

    c标准规定:

    如果所要求的空间大小是零,其行为是实现定义的:要么返回一个空指针,要么除了不 得使用返回的指针来访问对象以外,行为与大小仿佛是某个非零值。

    不要分配0 字节

    基于堆的内存管理缺陷缓解

    措施

    实践

    局限

    空指针

    指针所引用的内存被释放后,将此指针设置为NULL。

    如果多个指针指向同一个数据结构,这样的规避还是无法避免因覆写已经释放内存,和双重释放而引起的漏洞

    采取一致的内存管理约定

    • 使用同样的模式分配和释放内存。
    • 在同一个模块中,在同一个抽象层次中分配和释放内存。
    • 让分配和释放配对。

    c++中构造负责所有内存的分配,析构函数进行所有内存的释放。

    在子例程中释放内存会导致 混乱:究竟内存是否被释放了?何时释放的?在哪儿释放的?

    phkmalloc,随机化,OpenBSD,jemalloc,静态分析,动态分析。

    PurifyPlus。Valgrind。

     

    摘抄自读书笔记,有同样心得的网友可以交流分享下。

    同时可以参考书籍:

    sei-cert-c-coding-standard-2016-v01

    https://github.com/fogcell/learnfist/blob/master/pdf_book/sei-cert-c-coding-standard-2016-v01.pdf

  • 相关阅读:
    事件对象
    事件方法on()
    each()遍历
    链接式操作
    理解选取更新范围
    net3.5 无网络环境安装
    visual studio 2017 报错 无法下载安装文件。请检查Internet连接,然后重试
    删除数据恢复数据语句 Oracle
    sqlserver还原数据库(mdf与ldf文件如何还原到SQLserver数据库)
    sqlserver2012卸载
  • 原文地址:https://www.cnblogs.com/fogcell/p/11661817.html
Copyright © 2011-2022 走看看