结构体、联合体的安全规范

65 篇文章 1 订阅

2  结构体、联合体的安全规范

    规则18 4:不允许使用联合体。这是一个不太近情理的规定,在具体阐述为何《MIS—RA—C:2004》如此“痛恨”联合体之前,首先需要明确与联合体相关的细节:

    ①联合体的末尾有多少个填充单元?

    ②联合体中的各个成员如何对齐?

    ③多字节的数据类型高低字节如何排放顺序?

    ④如果包含位字段(bit—field),各位如何排放顺序?

    针对细节3举个例子。

程序段2.1

typedef union{

    uilat32_t word;

    uint8_t bytes[4];

}word_msg_t;

unit32_t read_nasg(void){

  word_rnsg_t tmp;

/*注:tmp bvte[0]对府干tmp.word的高8位,tmp  byter[1]对应于

tmp.word的次高8位,依次类推。*/

tmp.bytes[O]=read_byte();

tmp.bytes[1]=read_byte();

tmp.bytes[2]=read_byte();

tmp.bytes[3]=read_byte();

retlarn(trap.word);

}

    以上代码格式在各种通信协议中使用的频率很高,接收端接收到的数据一般都以字节为单位存放,主控程序需要根据相应的协议将接收到的多个字节进行组合。为了实现相同的功能,《MISRA-C:2004》推荐了read_msg()函数的另外一种写法。

程序段2.2

uint32_trcad_msg(void){

uint32_t word;

Word=((unit32_t)read_byte())<<24;

word=word│(((unit32_t)read_byte())<<16);

word=word│(((unit32_t)read_byted_byte<<8);

word=word│(((unit32_t)read_byte());

return(word):

}

    无论从程序的清晰程度还是执行效率来讲,程序段2.1都优于程序段2.2。然而,程序段2.1在Intel 80x86/Pentlurn体系(1ittle—endian,存储多字节整数的时候低字节存放在低地址,高字节存放在高地址)CPU中和在Mo—torola 68K体系(big—endian,存储多字节整数的时候高字节存放在低地址,低字节存放在高地址)cPu中的执行结果完全不一样。假设read_byte()函数返回的数据依次是0x01、0x02、0x03和0x04,则在Intel体系中,程序段2.1

中read_msg()函数的返回值是0x432l;在Motorola体系中,read_msg()的返回值是0x1234。

    无论在Intel体系还是Motorola体系中,程序段2.2中read_msg()的返回值都是0x1 234。

    以上是联合体中多字节整型字节排放顺序不定导致漏洞的一个例子。倘若不明确联合体末尾填充的细节,或者不清楚联合体成员的对齐方式,或者不注意联合体中位字段成员的位排列次序,都有可能导致错误。作为将安全性放在第一位的C标准,MlSRA—C禁止使用联合体并非不可理喻。

    然而,联合体毕竟是C语言的一个重要元素,所以MISRA—C主张禁止使用联合体的同时,也为效率和资源要求比较苛刻的情况开了一扇门,程序员在明确联合体各个实现细节的前提下,在万不得已的时候,仍可谨慎使用联合体,在不同体系的CPU间移植程序的时候要注意做相应的修改。

    此外,《MISRA—C:2004》中也对结构体和联合体的编程风格作了限定。

    规则18 1:所有结构体和联合体的定义必须保证完整性。

    由于涉及ISOC中类型定义完整性等概念,碍于篇幅的原因,此处就不再赘述,读者可以参阅《MISRA-C:2004》一书和ISOC标准以了解更多信息,完善自己的编程风格。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值