⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 012_mm_mprotect_c.html

📁 重读linux 2.4.2o所写的笔记
💻 HTML
字号:
  <html lang="zh-CN" xmlns:gdoc="">  <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <style type="text/css">/* default css */table {  font-size: 1em;  line-height: inherit;}div, address, ol, ul, li, option, select {   margin-top: 0px;  margin-bottom: 0px;}p {  margin: 0px;}body {        margin: 0px;          padding: 0px;    font-family: Verdana, sans-serif;  font-size: 10pt;  background-color: #ffffff;}h6 { font-size: 10pt }h5 { font-size: 11pt }h4 { font-size: 12pt }h3 { font-size: 13pt }h2 { font-size: 14pt }h1 { font-size: 16pt }blockquote {padding: 10px; border: 1px #DDD dashed }a img {border: 0}div.google_header, div.google_footer {  position: relative;  margin-top: 1em;  margin-bottom: 1em;}/* end default css */  /* default print css */    @media print {    body {       padding: 0;       margin: 0;     }    div.google_header, div.google_footer {      display: block;      min-height: 0;      border: none;    }    div.google_header {      flow: static(header);    }    /* used to insert page numbers */    div.google_header::before, div.google_footer::before {      position: absolute;      top: 0;    }    div.google_footer {      flow: static(footer);    }    /* always consider this element at the start of the doc */    div#google_footer {      flow: static(footer, start);    }    span.google_pagenumber {      content: counter(page);    }    span.google_pagecount {      content: counter(pages);    }  }  @page {    @top {      content: flow(header);    }    @bottom {      content: flow(footer);    }  }  /* end default print css */ /* custom css *//* end custom css */  /* ui edited css */    body {    font-family: Verdana;        font-size: 10.0pt;    line-height: normal;    background-color: #ffffff;  }    .documentBG {    background-color: #ffffff;  }  /* end ui edited css */</style>   </head>  <body  revision="dcbsxfpf_53ct2cm7f4:4">      <table align=center cellpadding=0 cellspacing=0 height=5716 width=768>
  <tbody>
  <tr>
    <td height=5716 valign=top width=100%>
      <pre>2006-5-23   <br>mm/mprotect.c<br><br>  本模块只提供一个系统调用,而无其他接口。这个系统调用就是sys_mprotect.<br>系统调用sys_mprotect(unsigned long start, size_t len, unsigned long prot)<br>改变地址范围[start,addr+len-1]涉及到的物理页面的保护方式。对于i386就是<br>改变pte中的__pgprot。<br>  其中prot可用的参数有:<br>  PROT_WRITE/PROT_READ/PROT_EXEC<br>  PROT_NONE:此段内存不能被访问.<br>  新设置的属性会完全取代现有属性,而不是叠加到现有属性上.<br>  <br>  此系统调用实现起来也不复杂,思路也常见了:遍历涉及到的vma,根据属性的改<br>变进行fixup(这个东西看到好几次了),同时设置所涉及之pte的prot属性.<br><br>  不再进行更详尽的分析了,简单看看函数:<br>asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)<br>{<br>	unsigned long nstart, end, tmp;<br>	struct vm_area_struct * vma, * next;<br>	int error = -EINVAL;<br><br>	if (start &amp; ~PAGE_MASK) //起始地址必须位于页边界<br>		return -EINVAL;<br>	len = PAGE_ALIGN(len);//长度扩大到最后一个page的末尾(大于给定范围)<br>	end = start + len;<br>	if (end &lt; start)<br>		return -EINVAL;<br>	if (prot &amp; ~(PROT_READ | PROT_WRITE | PROT_EXEC))//仅容许使用这几位<br>		return -EINVAL;<br>	if (end == start)<br>		return 0;<br><br>	down(&amp;current-&gt;mm-&gt;mmap_sem);<br><br>	vma = find_vma(current-&gt;mm, start);//start&lt;vm_end<br>	error = -EFAULT;<br>	if (!vma || vma-&gt;vm_start &gt; start)<br>		goto out;<br><br>	for (nstart = start ; ; ) {<br>		unsigned int newflags;<br><br>		/* Here we know that  vma-&gt;vm_start &lt;= nstart &lt; vma-&gt;vm_end. */<br><br>		newflags = prot | (vma-&gt;vm_flags &amp; ~(PROT_READ | PROT_WRITE | PROT_EXEC));<br>		if ((newflags &amp; ~(newflags &gt;&gt; 4)) &amp; 0xf) {<br>		//高四位代表内核所授予的权限,VM_MAYREAD,...<br>		//PROT_xxx分别等于VM_XXX,代表当前所拥有的权限<br>		//不能超越VM_MAYxxx,即高4位所代表的权限<br>			error = -EACCES;<br>			break;<br>		}<br><br>		if (vma-&gt;vm_end &gt;= end) {//last vma <br>			error = mprotect_fixup(vma, nstart, end, newflags);<br>			break;<br>		}<br><br>		tmp = vma-&gt;vm_end;<br>		next = vma-&gt;vm_next;<br>		error = mprotect_fixup(vma, nstart, tmp, newflags);<br>		//xxxx_fixup都要求 nstart,tep在vma_start到vma_end之间<br>		<br>		if (error)<br>			break;<br>		nstart = tmp;<br>		vma = next;<br>		if (!vma || vma-&gt;vm_start != nstart) {<br>			error = -EFAULT;<br>			break;<br>		}<br>	}<br>out:<br>	up(&amp;current-&gt;mm-&gt;mmap_sem);<br>	return error;<br>}<br><br>   次函数使用的fixup函数,以及改变pte的prot的部分不再做详细分析,重点注意<br>下面几个问题:  <br>1)pmd_bad<br>static inline void change_pte_range(pmd_t * pmd, unsigned long address,<br>	unsigned long size, pgprot_t newprot)<br>{<br>	pte_t * pte;<br>	unsigned long end;<br><br>	if (pmd_none(*pmd))<br>		return;<br>	if (pmd_bad(*pmd)) { //以前分析过pmd_bad,如果用户页面出了问题<br>		pmd_ERROR(*pmd); //就作记录<br>		pmd_clear(pmd);  //清除pte<br>		return;          //当内核页面bad的时候,可以参考get_pte_slow<br>	}<br>.....<br>}<br><br><br>2.vm flags 到pte prot的转化表 <br>static int mprotect_fixup(struct vm_area_struct * vma, <br>	unsigned long start, unsigned long end, unsigned int newflags)<br>{<br>	pgprot_t newprot;<br>	int error;<br><br>	if (newflags == vma-&gt;vm_flags)<br>		return 0;<br>	newprot = protection_map[newflags &amp; 0xf];//2^4种组合见<br>	        //protection_map<br>	<br>	.....<br>}<br>}<br></pre>
    </td>
  </tr>
  </tbody>
</table>
//protection_map<br>
<br>
.....<br>
}<br>
}</body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -