C和C++安全编码笔记:总结
《C和C++安全编码》(原书第2版)这本书是2013年出版的。
这里是基于之前所有笔记的简单总结,笔记列表如下:
字符串:https://blog.csdn.net/fengbingchun/article/details/105325508
指针诡计:https://blog.csdn.net/fengbingchun/article/details/105458861
动态内存管理:https://blog.csdn.net/fengbingchun/article/details/105921174
整数安全:https://blog.csdn.net/fengbingchun/article/details/106444980
格式化输出:https://blog.csdn.net/fengbingchun/article/details/106728792
并发:https://blog.csdn.net/fengbingchun/article/details/106962487
文件I/O:https://blog.csdn.net/fengbingchun/article/details/107138261
下面是对每章中关键语句的摘记:
1. 字符串:
在获取一个数组的大小时,不要对一个指针应用sizeof运算符。
每个UTF-8字符由1~4个字节表示。
宽字符串字面值除了以字面L作为前缀外,其它的表示方式与字符串字面值相同。
不要试图修改字符串字面值。
不要指定一个用字符串字面值初始化的字符数组的界限。
在标准C++的string类中,其内部表示并不一定非得是以空字符结尾的,虽然所有常见的实现都是以空字符结尾的。
存储在unsigned char类型对象中的值,保证会当作一个纯粹的二进制表示法来表示属性值。
任何类型的非二进制位域(non-bit-field)的对象都可以复制到一个unsigned char数组中(例如,通过memcpy()),并每次1个字节地检查它们的表示形式。
保证字符串的存储空间具有容纳字符数据和空终结符的足够空间。
不要从一个无界源复制数据到定长数组。
不要使用废弃或过时的函数。
如果一个字符串没有以空字符结尾,程序可能会被欺骗,导致在数组边界之外读取或写入数据。
空终止字符之所以是必要的,是因为前面这些函数以及其它由C标准定义的字符串处理函数,都依赖于它的存在来标记字符串的结尾。
空字符结尾的字符串是用字符数组实现的。
C11附录K边界检查接口:设计目的主要是实现现有函数的更安全的替代品。例如,C11附录K定义了strcpy_s、strcat_s、strncpy_s和strncat_s函数,分别作为strcpy、strcat、strncpy和strncat的替代品,适用于源字符串长度未知的或保证小于已知目标缓冲区大小的情况。
basic_string类实现了”由被调用者分配,由被调用者释放”的内存管理策略。
注意std::string的下标成员std::string::operator[](不执行边界检查)不会抛出异常。
永远不要使用gets(),它不对缓冲区溢出进行任何检测。
如果字符数组不是正确地以空字符结尾的,strlen()函数可能会返回一个错误的超大的数值,使用它时,就可能会导致漏洞。
任何到达某个跨越信任边界的程序接口的数据都需要验证。
2. 指针诡计(pointer subterfuge):是通过修改指针值来利用程序漏洞的方法的统称。
atexit()是C标准定义的一个通用工具函数。atexit()可以注册无参函数,并在程序正常结束后调用该函数。atexit()通过向一个退出时将被调用的已有函数的数组中添加指定的函数完成工作。
防止指针诡计的最佳方式就是消除”允许内存被不正确地覆写”的漏洞。
3. 动态内存管理:
free(void* p):如果p是一个空指针,则不执行任何操作。
对齐:完整的对象类型有对齐(alignment)要求,这种要求对可以分配该类型对象的地址施加限制。对齐是实现定义的整数值,它表示可以在一个连续的地址之间分配给指定的对象的字节数量。对象类型规定了每一个该类型对象的对齐要求。
每个有效对齐值都是2的一个非负整数幂。
不要假定内存分配函数初始化内存。
不要引用未初始化的内存。
内存分配函数的返回值表示分配失败或成功。如果请求的内存分配失败,那么aligned_alloc、calloc、malloc和realloc函数返回空指针。
空指针的解引用通常会导致段错误,但并非总是如此。许多嵌入式系统有映射到地址0处的寄存器,因此覆写它们会产生不可预知的后果。在某些情况下,解引用空指针会导致任意代码的执行。
不要执行零长度分配。
连续调用分配函数分配的存储的顺序、连续性、初始值都是不确定的。
C++在发起一个为零的请求时行为与C不同,它返回一个非空指针。
通常情况下,分配函数无法分配存储时抛出一个异常表示失败,这个异常将匹配类型为std::bad_alloc的异常处理器。
如果用std::nothrow参数调用new,当分配失败时,分配函数不会抛出一个异常。相反,它将返回一个空指针。
提供给一个释放函数的第一个参数的值可以是一个空指针值,如果是这样的话,并且如果释放函数是标准库提供的,那么该调用没有任何作用。
C++的内存分配和释放函数分配和释放内存的方式可能不同于C内存分配和释放函数分配和释放内存的方式。因此,在同一资源上混合调用C++内存分配和释放函数及C内存分配和释放函数是未定义的行为,并可能会产生灾难性的后果。
new和operator new():可以直接调用operator new()分配原始内存,但不调用构造函数。
释放函数必须避免抛出异常。
一个明显的可以减少C和C++程序中漏洞数量的技术就是在指针所引用的内存被释放后,将此指针设置为NULL。如果指针被设置为NULL,内存可以被”释放”多次而不会导致不良后果。
4. 整数安全:
特定于编译器和平台的整数极值记录在<limits.h>头文件中。牢记这些值都是特定于平台的。出于可移植性的考虑,在代码中应该使用具名常量而不是实际的值。
C标准允许的负数表示方法有三种,分别是原码表示法(sign and magnitude)、反码表示法(one’s complement)和补码表示法(two’s complement)。若要取一个原码的相反数,只要改变符号位。若要取一个反码的相反数,需要改变每一位(包括符号位)。若要取一个补码的相反数,首先构造反码的相反数,然后再加1(在需要时进位)。
用补码表示的一个给定类型最小负值的相反数不能以那种类型表示。
在把char型用于数值时仅使用明确的signed char或unsigned char型。
整数提升保留值,其中包括符号。如果在所有的原始值中,较小的类型可以被表示为一个int,那么:原始值较小的类型会被转换成int;否则,它被转换成unsigned int。
之所以需要整数类型提升,主要是为了防止运算过程中中间结果发生溢出而导致算术错误,也为了在该架构中以自然的大小执行操作。
当从一个无符号类型转换为有符号类型时,应验证范围。
当从一个有符号类型转换到精度较低的有符号类型时,应验证范围。从较高精度的有符号类型转换为较低精度的有符号类型需要同时对上限和下限进行检查。
从有符号类型转换为无符号类型时,应验证取值范围。
唯一的对所有数据值和所有符号标准的实现都保证安全的整数类型转换是转换为符号相同而宽度更宽的类型。
在C中有符号溢出是未定义的行为,允许实现默默地回绕(最常见的行为)、陷阱、饱和(固定在最大值/最小值中),或执行实现选择的其它任何行为。
使用静态断言static_assert来测试一个常数表达式的值。
不要移动一个负的位数或移动比操作数中存在的位数更多的位。
移位运算符和其它位运算符应仅用于无符号整数操作数。
应使用无符号整数表示不可能是负数的整数值,而且应使用有符号整数值表示可以为负的值。在一般情况下,应该使用完全可以代表任何特定变量可能值的范围的最小的有符号或无符号类型,以节省内存。
5. 格式化输出:
格式化输出函数是由一个格式字符串和可变数目的参数构成的。
变参函数是通过使用一个部分参数列表后跟一个省略号进行声明的。省略号必须出现在参数列表的最后。参数列表的终止条件是函数的实现者和使用者之间的一个契约。
格式字符串:是由普通字符(ordinary character)(包括%)和转换规范(conversion specification)构成的字符序列。当参数多于转换规范时,多余的将被忽略,而当参数不足时,则结果是未定义的。
为了消除格式字符串漏洞,推荐在可能的情况下使用iostream代替stdio,在没有条件的情况下则要尽量使用静态格式字符串。
6. 并发:
并发是一种系统属性,它是指系统中几个计算同时执行,并可能彼此交互。一个并发程序通常使用顺序线程和(或)进程的一些组合来执行计算,其中每个线程和进程执行可以在逻辑上并行执行的计算。
多线程不一定是并发的。
所有的并行程序都是并发的,但不是所有的并发程序都是并行的。这意味着并发程序既可以用交错、时间分片的方式执行又可以并行执行。
对不能缓存的数据使用volatile。当一个变量被声明为volatile时,就会禁止编译器对该内存位置的读取和写入顺序进行重新排列。
在重组程序方面,编译器具有非常大的自由度。
C和C++都支持几种不同类型的同步原语,包括互斥变量(mutex variable)、条件变量(condition variable)和锁变量(lock variable)。
锁机制导致一个或多个线程等待,直到另一个线程退出临界区。
一个线程锁定一个互斥量后,任何后续试图锁定该互斥量的线程都将被阻止,直到此互斥量被解锁为止。
互斥量可以包装在临界区,以使它们序列化,从而使程序是线程安全的。互斥量不与任何其它数据关联。它们只是作为锁对象。
在用C++编程时,如果发生临界区抛出异常,或退出时没有明确地对互斥量解锁,我们建议使用锁卫士缓解这些问题。
原子操作是不可分割的。也就是说,一个原子操作不能被任何其它的操作中断,当正在执行原子操作时,它访问的内存,也不可以被任何其它机制改变。
原子对象不存在数据竞争,虽然它们仍然可能会受到竞争条件的影响。
为了使一个函数成为线程安全的,它必须同步访问共享资源。
7. 文件I/O:
特殊文件:包括目录、符号链接、命名管道、套接字和设备文件。
文本流stdin、stdout和stderr是FILE指针类型的表达式。
文件描述符是每一个进程为了文件访问的目的,用来识别一个打开的文件的唯一的非负整数。文件描述符只是一个标识符或句柄,它实际上并没有描述什么。
超级UID(root)拥有一个为0的UID,并可以访问任何文件。
文件权限一般都用八进制值的向量表示。
权限字符串的第一个字符表示文件类型:普通-、目录d、符号链接l、设备b/c、套接字s或FIFO f/p。
目录内的特殊文件名”.”指的是目录本身,”..”指的是目录的父目录。作为一种特例,在根目录中,”..”可能指的是根目录本身。
符号链接是特殊的文件,其中包含了实际文件的路径名。
对同步原语的使用要求我们小心翼翼地将临界区的大小减到最小。
当宣告一个函数为线程安全的时候,就意味着作者相信这个函数可以被并发线程调用,同时该函数不会导致任何竞争条件问题。
GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:

《评人工智能如何走向新阶段》后记(再续2)
由AI科技大本营下载自视觉中国从朋友那里获知,有一块供大家自由议论人工智能的园地(内部的),我通过有关关系进入后,一览之余,果然生动活泼,没有学究气,从已发表的30条议论来看。有原…

Dokku和Docker的完美配合
看到一篇不错的文章,收藏一下: 【编者的话】本文作者介绍了如何在单机上将Dokku和Docker结合。Dokku是一个小型的PaaS平台,只需使用Git将代码push到对应的仓库上就能自动触发部署,构建过程非常简单。但是Dokku对于用户来说&#x…

iOS封装分页效果
#import <UIKit/UIKit.h> interface WPageTitleView : UIView property (nonatomic,assign) NSInteger selectedIndex; //添加参数数组 property (nonatomic,strong) NSArray *titles; property (nonatomic,copy) void (^buttonSelected)(NSInteger index); end #impo…

Windows/Linux TCP Socket网络编程简介及测试代码
典型的网络应用是由一对程序(即客户程序和服务器程序)组成的,它们位于两个不同的端系统中。当运行这两个程序时,创建了一个客户进程和一个服务器进程,同时它们通过从套接字(socket)读出和写入数据在彼此之间进行通信。开发者创建一个网络应用…

《评人工智能如何走向新阶段》后记(再续3)
由AI科技大本营下载自视觉中国35.阿里巴巴旗下芯片公司平头哥在乌镇互联网大会上宣布开源低功耗微控制芯片(MCU)设计平台,这一平台面向 AIoT 时代的定制化芯片设计需求,目标群体包括芯片设计公司、IP 供应商、高校及科研院所等&am…

ffmpeg 基本用法大全
FFmpegFFmpeg 基本用法本课要解决的问题1.FFmpeg的转码流程是什么?2.常见的视频格式包含哪些内容吗?3.如何把这些内容从视频文件中抽取出来?4.如何从一种格式转换为另一种格式?5.如何放大和缩小视频?6.如何旋转&#x…

快过年了,为过完年跳槽的人准备一份面试题
设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的事情。 1). MVC模式:Model View Control,把模型 视图 控制器 层进行解耦合编写。 2). MV…

Ubuntu上Vim安装NERDTree插件操作步骤
NERDTree是Vim的文件系统浏览器,使用此插件,用户可以直观地浏览复杂的目录层次结构,快速打开文件以进行读取或编辑,以及执行基本的文件系统操作。NERDTree源码在https://github.com/preservim/nerdtree。 这里通过Vundle安装NERD…

《评人工智能如何走向新阶段》后记(再续4)
由AI科技大本营下载自视觉中国41. 在人工智能感知阶段,依靠数据驱动的深度学习算法。目前5种最流行的深度学习架构: ① 递归神经网络(RNN)② 长短期记忆 (LSTM)/门控递归单元(GRU)③卷积神经网络…

电视游戏会是未来客厅娱乐的主角吗?
在时下流行的多屏生态概念中,电视虽为最大屏幕,但与智能手机、平板等小屏相比,属于相对较弱的一环。无移动性、自身交互性不足,在一定程度上影响着它在移动时代的发展。而作为最能体现其“吸睛能力”的——大屏娱乐功能࿰…

王爽著的《汇编语言》第3版笔记
王爽著的《汇编语言》(第3版)于2013年出版,虽然是2013年出版的,但书中部分内容感觉已过时: (1). 基于intel 8086 CPU介绍,intel 8086是英特尔公司上个世纪生产的芯片,是16位的,早已停产; (2).…

iOS 倒计时方法
//启动计时器 double delayInSeconds 10.0; dispatch_time_t popTime dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ //执行事件 NSLog("计时器结束了"); UIAlertController …

《评人工智能如何走向新阶段》后记(再续5)
由AI科技大本营下载自视觉中国51.今年发表的由俄罗斯“脑机接口”公司(Neurobotics)和莫斯科物理技术学院(MIPT)研究的一种全新“脑机接口”算法。利用“脑机接口”将人脑(EEG)神经元与脑外深度学习网络连接…

不说12306你会Die啊?当然不会,但会憋死
别嫌这标题话粗啊,只是突然想起了某小品中的一句台词儿而已。又是一年春运时,几十亿人口开始了兴奋着、痛苦着的大迁徙。12306开通有几年了吧,我今年才第一次用。因为父母要回老家,不想排队那么辛苦,所以才尝试一把网络…

汇编程序设计与计算机体系结构软件工程师教程笔记:处理器、寄存器简介
《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错,书中介绍了三种汇编器GAS、NASM、MASM异同,全部示例代码都放在了GitHub上,…
iOS 发布APP关于IDFA的相关内容
您的 App 正在使用广告标识符 (IDFA)。您必须先提供关于 IDFA 的使用信息或将其从 App 中移除,然后再上传您的二进制文件。 如果出现下边这两张图,你就会感到蛋蛋的忧伤 还有这个 怎么解决? 1,查看你所集成的SDK,看看…

《评人工智能如何走向新阶段》后记(再续6)
由AI科技大本营下载自视觉中国61. 在2019深度学习开发者峰会上,百度发布基于飞桨的图学习框架(PaddleGraphLearning,PGL)。近年来深度神经网络推动了人工智能的发展,但在实际场景中有大量数据是在非欧式空间的…

Android APP测试的日志文件抓取
1 log文件分类简介 实时打印的主要有:logcat main,logcat radio,logcat events,tcpdump,还有高通平台的还会有QXDM日志 状态信息的有:adb shell cat /proc/kmsg ,adb shell dmesg,…

汇编程序设计与计算机体系结构软件工程师教程笔记:指令
《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错,书中介绍了三种汇编器GAS、NASM、MASM异同,全部示例代码都放在了GitHub上,…

IOS视频编辑功能详解上篇-添加水印
前言 用代码在简单视频编辑中,主要就是加美颜、水印(贴图)、视频截取、视频拼接、音视频的处理,在美颜中,使用GPUImage即可实现多种滤镜、磨皮美颜的功能,并且可以脸部识别实时美颜等功能,这个…

《评人工智能如何走向新阶段》后记(再续7)
由AI科技大本营下载自视觉中国66. 谷歌近来研发用于基因科学的人工智能AlphaFold,根据基因序列预测生命基本分子一蛋白质的三维结构(AlphaFold与下国际围棋的AlphaGo似孪生兄弟),这是用来预测蛋白质折叠结构的能力或设计新的蛋白质…

Linux多线程实践(6) --Posix读写锁解决读者写者问题
Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_r…

iOS-直播开发(开发从底层做起)
代码链接: Github: https://github.com/jessonliu/JFLivePlaye 技术部分------ ⬇️ 脑涂: ![ 直播思维导图.png ] 视频直播的大概流程就上脑涂上所画的, 还有一些没列出来, 比如, 聊天, 送礼, 踢出, 禁言, 等等一系列功能, 但本文只是针对视频直播的简单实现! 下边来说一下以…

汇编程序设计与计算机体系结构软件工程师教程笔记:函数、字符串、浮点运算
《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错,书中介绍了三种汇编器GAS、NASM、MASM异同,全部示例代码都放在了GitHub上,…
《庆余年》值得一看吗?Python告诉你谁在关注 | CSDN原力计划
扫码参与CSDN“原力计划”作者 | A字头来源 | 数据札记倌庆余年电视剧终于在前两天上了,这两天赶紧爬取数据看一下它的表现。庆余年《庆余年》是作家猫腻的小说。这部从2007年就开更的作品拥有固定的书迷群体,也在文学IP价值榜上有名。期待已久的影视版的…

《C语言及程序设计》实践项目——画分支结构流程图
返回:贺老师课程教学链接 【单分支结构流程图-大值】问题:画流程图,输入两个整数a和b,输出其中的大值。提示:当a<b时,交换a和b,最后输出的a一定是其中的大值。流程图中可以直接给出交换a和b…

汇编程序设计与计算机体系结构软件工程师教程笔记:内联汇编与宏
《汇编程序设计与计算机体系结构: 软件工程师教程》这本书是由Brain R.Hall和Kevin J.Slonka著,由爱飞翔译。中文版是2019年出版的。个人感觉这本书真不错,书中介绍了三种汇编器GAS、NASM、MASM异同,全部示例代码都放在了GitHub上,…
无需标注数据,利用辅助性旋转损失的自监督GANs,效果堪比现有最好方法
作者 | Ting Chen译者 | 王红成出品 | AI科技大本营(ID:rgznai100)本文作者提出了一种自检督方式的生成对抗网络,通过辅助性的旋转损失来达到目的。因为通常主流方法来生成自然图像都是通过条件GAN来完成,但是这就需要很多的标签数…

iOS环信聊天界面中点击头像和消息的几种状态
/*环信自带头像点击事件*/ - (void)messageViewController:(EaseMessageViewController *)viewControllerdidSelectAvatarMessageModel:(id<IMessageModel>)messageModel {内容可以根据需要自己添加 }/*!methodbrief 点击了简历消息 (lyq添加)discussion 点击了简历消息,…

ASP.NET将Session保存到数据库中
因为ASP.NET中Session的存取机制与ASP相同,都是保存在进行中, 一旦进程崩溃,所有Session信息将会丢失,所以我采取了将Session信息保存到SQL Server中,尽管还有其它的几个方式(本文不作介绍)&…