<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>安全 on kamuszhou&#39;s blog</title>
    <link>https://ykyi.net/tags/%E5%AE%89%E5%85%A8/</link>
    <description>Recent content in 安全 on kamuszhou&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 15 Jun 2012 12:28:26 +0000</lastBuildDate>
    <atom:link href="https://ykyi.net/tags/%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>C语言和它的安全性</title>
      <link>https://ykyi.net/?p=615/</link>
      <pubDate>Fri, 15 Jun 2012 12:28:26 +0000</pubDate>
      <guid>https://ykyi.net/?p=615/</guid>
      <description>&lt;p&gt;原文: &lt;a href=&#34;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&#34;&gt;http://avikivity.blogspot.com/2011/08/c-assembly-and-security.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ykyi.net 翻译。&lt;/p&gt;
&lt;p&gt;我们看下面一个C语言的句子：&lt;/p&gt;
&lt;p&gt;a = b + c&lt;/p&gt;
&lt;p&gt;什么时候这个句子会造成错误呢？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;a, b, c 不是我们想要的值。也就是我们把变量名写错了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写了加法，但是我们要的不是加法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;做了加法后值溢出了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a和b是无符号类型，而c却是有符号类型并且是负数，b+c后得到负数又赋给a.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sizeof(a)比sizeof(b)和sizeof(c)要小。又溢出了！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a是有符号型，b和c是无符号型。b+c后赋给a，溢出后，a变成负值。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a是无符号型，b和c是有符号型；再次溢出。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们不能期望C语言本身能避免所有这些错误，但我们可不可以通过在运行时Trap上述的一些错误改进C语言使之更安全呢？结果时，除非牺牲性能，否则做不到。但我们能牺牲性能吗？&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;♦ 为了处理第(3)种情况，我们需要Trap所以有符号数的加法和所以无符号数的加法指令。&lt;/p&gt;
&lt;p&gt;♦ 为了处理第(4)种情况，需要一个混杂有符号和无符号的加法指令被Trap。&lt;/p&gt;
&lt;p&gt;♦ 为了处理第(5)种情况，需要Trap存储有符号数和无符号数的指令。在Trap中检查寄存器中的值与存入的内存地址是否匹配。&lt;/p&gt;
&lt;p&gt;♦ (6)和(7)与上类似。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这些看似简单的问题在安全，漏洞方面经常出现。我们很难发现并修复这些问题，因为没有所需要的处理器指令。当然我们可以用已经存在的指令模拟它们。但是这样做肯定会损害性能并且使程序的体积增大。因为程序性能是可以被度量的，而度量安全问题则比较困难。结果时留下了很多充满漏洞的代码(exploitable code)。&lt;/p&gt;
&lt;p&gt;不禁要问，为什么我们没有这些指令呢？在上世纪的七，八十年代，正在快速成长的计算机工业界面临的最大问题是性能，而不是安全。那时的代码量很小，也很容易做检查；网络还在最初级的阶段，很小，而且基本上是私有的；基本不存在恶意的攻击。&lt;/p&gt;
&lt;p&gt;C语言在当时的作法是为了能够在适合当时所有的处理器，因此C语言的语义模仿当时的处理器指令集。之后，C语言大获成功，大量的处理器则针对C语言做优化，很多指令直接针对C语言的语义做优化或可以直接对应到C语言的语义。这样，使得C语言更加流行了。&lt;/p&gt;
&lt;p&gt;X86的世界里有两个指令: INTO和BOUND是极好的例子。INTO(INTerrupt on Overflow)可以在一个加法指令或者减法指令之后。INTO可以用来作为上文指到过的Trap有符号加减法的指令。BOUND则对数组操作是否越界做检查。但是BOUND极少被使用。最后，在x86体系过渡到64位体系的过程中，INTO指令和BOUND指令都被只留在历史的尘埃之中了。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
