完成本文,使用了两个工具

 1. strace

 2. google code search .

 

----

  1. swap分区有一个大小为PAGE_SIZE的页面,称为signature页,上面记录swap分区的基本信息。
    static struct swap_header_v1 {
    char bootbits[1024]; /* Space for disklabel etc. */
    unsigned int version;
    unsigned int last_page;
    unsigned int nr_badpages;
    unsigned int padding[125];
    unsigned int badpages[1];
    } *p;
  2. check_blocks()会 对整个文件进行一次顺序读,在v1生成一个磁盘块“好块”和“坏块”的位图。在v2中,“好块”无需记录,只记录坏块。一个磁盘的坏块一般来说极少,为了 节省空间,因此记录方法不再是位图,改而用数组的方式。
    p->badpages[badpages] = page; // page为坏块号

    这里需要注意的是,在 swap_header_v1的定义中,p->badpages数组大小为1,这里实际上产生了越界。但是,从C语言的知识我们知道,即使越界,只 要编译器没有检测出来,并且实际访问的“越界区”是我们可访问的区域,则不会有任何问题。上面这句代码是一种“可控的、有意识的越界”。可控的边界在哪里 呢?

    #define MAX_BADPAGES    ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))  // 637 bad pages over i386
    结合swap_header_v1的定义,上面的公式不难理解 bootbits占1024字节,随后4个变量分别占4、4、4、4*125字节,SIGNATURE占10字节,剩余的都给badpages了。超过了 MAX_BADPAGES,则会引发越界访问。
  3. swap 分区格式有两个版本,姑且称为v0和v1,版本可以在命令行中指定,如果缺省,则mkswap根据swap分区设备/文件大小自动设定。
    write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
  4. 通过上述步骤,signature页的内容都被初始化好 了,现在写回到块设备中去:
            offset = ((version == 0) ? 0 : 1024);
    if (lseek(DEV, offset, SEEK_SET) != offset)
    error_msg_and_die("unable to rewind swap-device");
    if (write(DEV, (char *) signature_page + offset, pagesize - offset)
    != pagesize - offset)
    error_msg_and_die("unable to write signature page");
    对于v0,signature页被写到设备头,对于 v1,signature页被写到偏移为1024字节处。

 

附mkswap源码

 

 

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

Ray的生活博客: http://raywill.blog.sohu.com

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

 

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐