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

📄

📁 华中科技大学96级学生linux内核实习报告
💻
📖 第 1 页 / 共 5 页
字号:
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>  </blockquote></blockquote><p><strong><font FACE="隶书" SIZE="5">三 代码分析(Code analysis)</font></strong></p><blockquote>  <blockquote>    <p></font><font face="宋体" size="3" color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;     函数首先定义了一个结构变量:struct linux_binprm bprm,用以存放一些将要被执行的程序的参数值,然后程序调用     open_namei     函数打开文件(。。。。)然后程序检查参数堆栈的设置是否正确.</font><font FACE="宋体" size="3"><font color="#00FF40"><br>    </font><font color="#8000FF">/* this function is from file linux/fs/exec.c */ </font><br>    </font><font FACE="宋体" COLOR="#007f7f" size="3">/* sys_execve() executes a new     program. */ <br>    <br>    <strong>int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs *regs)<br>    { <br>    &nbsp;&nbsp;&nbsp; struct linux_binprm bprm;<br>    &nbsp;&nbsp;&nbsp; int retval;<br>    &nbsp;&nbsp;&nbsp; int i;<br>    &nbsp;&nbsp;&nbsp; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);<br>    &nbsp; <br>    &nbsp; /* clear page-table */&nbsp;&nbsp;&nbsp;<br>    &nbsp; for (i=0 ; i&lt;MAX_ARG_PAGES ; i++)     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     <br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;     bprm.page[i] = 0;<br>    &nbsp;&nbsp; retval = open_namei(filename, 0, 0, &amp;bprm.inode, NULL);<br>    &nbsp;&nbsp;&nbsp; if (retval) <br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br>    &nbsp;&nbsp;&nbsp; bprm.filename = filename; <br>    &nbsp;&nbsp;&nbsp; bprm.sh_bang = 0;<br>    &nbsp;&nbsp;&nbsp; bprm.loader = 0; <br>    &nbsp;&nbsp;&nbsp; bprm.exec = 0; <br>    &nbsp;&nbsp;&nbsp; bprm.dont_iput = 0;<br>    &nbsp;&nbsp;&nbsp; if ((bprm.argc = count(argv)) &lt; 0)<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return bprm.argc;<br>    &nbsp;&nbsp;&nbsp; if ((bprm.envc = count(envp)) &lt; 0) <br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return bprm.envc;<br>    &nbsp;&nbsp;&nbsp; retval = prepare_binprm(&amp;bprm); <br>    &nbsp;&nbsp;&nbsp; if(retval&gt;=0) {<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bprm.p =     copy_strings(1,&amp;bprm.filename, bprm.page, bprm.p, 2);<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bprm.exec = bprm.p;<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bprm.p =     copy_strings(bprm.envc,envp,bprm.page, bprm.p,0);<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font FACE="宋体" size="4" COLOR="#007f7f">bprm.p = copy_strings(bprm.argc,argv,bprm.page,     bprm.p,0);<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!bprm.p) <br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;     retval = -E2BIG; <br>    &nbsp;&nbsp;&nbsp; }<br>    &nbsp;&nbsp;&nbsp; if(retval&gt;=0)<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval = search_binary_handler(&amp;bprm,regs);<br>    &nbsp;&nbsp;&nbsp; if(retval&gt;=0) /* execve success */<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retval;<br>    &nbsp;&nbsp;&nbsp; /* Something went wrong, return the inode and free the argument pages*/<br>    &nbsp;&nbsp;&nbsp; if(!bprm.dont_iput) <br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; iput(bprm.inode);<br>    &nbsp;&nbsp;&nbsp; for (i=0 ; i&lt;MAX_ARG_PAGES ; i++)<br>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_page(bprm.page[i]); <br>    &nbsp;&nbsp;&nbsp; return(retval);</font></strong><font FACE="宋体" size="3"></p>    </font><font FACE="宋体" COLOR="#007f00" size="4"><p></font><font FACE="宋体" size="4"><font color="#008080"><strong>}</strong></font></p>    </font><font FACE="宋体" SIZE="2" COLOR="#7f0000"><p></font><strong><font face="宋体" size="5" color="#000000">&nbsp;&nbsp;&nbsp;&nbsp; </font><font face="宋体" color="#000000" size="4">如上面的原代码所示:sys_execve     的执行将会被转为函数 do_execve 的执行,此函数共需要 4 个参数:filename,     argv,envp,regs.其中filename为所要执行程序的文件名,它必须是一个有效的用户可执行的程序文件,并使该可执行程序有正确的内容。<br>    &nbsp;&nbsp;&nbsp;&nbsp; 程序中用到一个重要的数据结构:linux_binprm,此结构在     linux/include/linux/binfmts.h 中有定义如下:</font></strong><font FACE="宋体" SIZE="2" COLOR="#7f0000"></p>    </font><p> <img src="dot2.jpg" alt="dot2.bmp (406 bytes)" WIDTH="10" HEIGHT="11"> <font color="#0080C0" face="宋体"><strong><em><big>linux_binprm 结构:</big><br>    </em></strong></font><br>    <font FACE="宋体" SIZE="2">/*This structure is used to hold the arguments that are used     when loading binaries.&nbsp;&nbsp; */</font><br>    <font FACE="宋体" size="3">struct linux_binprm{<br>    &nbsp;&nbsp;&nbsp; char buf[128];<br>    &nbsp;&nbsp;&nbsp; unsigned long page[MAX_ARG_PAGES];<br>    &nbsp;&nbsp;&nbsp; unsigned long p;<br>    &nbsp;&nbsp;&nbsp; int sh_bang;<br>    &nbsp;&nbsp;&nbsp; struct inode * inode;<br>    &nbsp;&nbsp;&nbsp; int e_uid, e_gid;<br>    &nbsp;&nbsp;&nbsp; int argc, envc;<br>    &nbsp;&nbsp;&nbsp; char * filename; /* Name of binary */<br>    &nbsp;&nbsp;&nbsp; unsigned long loader, exec;<br>    &nbsp;&nbsp;&nbsp; int dont_iput; /* binfmt handler has put inode */<br>    };</font></p>    <font FACE="宋体" SIZE="3" COLOR="#007f00"><p> </p>    <p></font><font color="#000000"><font FACE="宋体" size="3">/*<br>    </font><font FACE="宋体" SIZE="2">* </font><font FACE="宋体" size="3">MAX_ARG_PAGES     规定了设定或保存运行程序的参数和框架(或者叫“外壳”)而必 *     须得到的内存页的数量。32 个应该是足够的。<br>    *</font><font FACE="宋体" SIZE="2">/<br>    </font></font><font FACE="宋体" color="#000000" size="3">#define MAX_ARG_PAGES 32</font><font FACE="宋体" SIZE="2" COLOR="#007f00"></p>    </font><font FACE="宋体" SIZE="3" COLOR="#007f00"><p><img src="dot2.jpg" alt="dot2.bmp (278 bytes)" WIDTH="10" HEIGHT="11"></font><em><strong><font FACE="宋体" SIZE="3" color="#0080FF">     </font><font FACE="宋体" color="#0080C0" size="4">pt_regs 结构:</font></strong></em><br>    <font FACE="宋体" SIZE="3" COLOR="#007f00"><br>    /* this info is in file linux/include/asm/ptrace.h */</font><br>    <font FACE="宋体" SIZE="2">/* this struct defines the way the registers are stored on     the <br>    &nbsp;&nbsp; stack during a system call. */<br>    <br>    struct pt_regs {<br>    &nbsp;&nbsp;&nbsp; long ebx;<br>    &nbsp;&nbsp;&nbsp; long ecx;<br>    &nbsp;&nbsp;&nbsp; long edx;<br>    &nbsp;&nbsp;&nbsp; long esi;<br>    &nbsp;&nbsp;&nbsp; long edi;<br>    &nbsp;&nbsp;&nbsp; long ebp;<br>    &nbsp;&nbsp;&nbsp; long eax;<br>    &nbsp;&nbsp;&nbsp; unsigned short ds, __dsu;<br>    &nbsp;&nbsp;&nbsp; unsigned short es, __esu;<br>    &nbsp;&nbsp;&nbsp; unsigned short fs, __fsu;<br>    &nbsp;&nbsp;&nbsp; unsigned short gs, __gsu;<br>    &nbsp;&nbsp;&nbsp; long orig_eax;&nbsp;&nbsp;&nbsp; <br>    &nbsp;&nbsp;&nbsp; long eip;<br>    &nbsp;&nbsp;&nbsp; unsigned short cs, __csu;<br>    &nbsp;&nbsp;&nbsp; long eflags;<br>    &nbsp;&nbsp;&nbsp; long esp;<br>    &nbsp;&nbsp;&nbsp; unsigned short ss, __ssu;<br>    };</p>    <p></font><font FACE="宋体" size="3"><img src="dot2.jpg" alt="dot2.bmp (278 bytes)" WIDTH="10" HEIGHT="11"> </font><font FACE="宋体" color="#0080C0" size="4"><em><strong>函数 open_namei():</strong></em></font><font FACE="宋体" size="3"></p>    <p></font><font FACE="宋体" SIZE="2">/*this function is in file linux/fs/namei.c */</p>    </font><blockquote>      <font FACE="宋体" SIZE="2"><blockquote>        <p><br>        * open_namei()<br>        *<br>        * namei for open - this is in fact almost the whole open-routine.<br>        *<br>        * Note that the low bits of &quot;flag&quot; aren't the same as in the open<br>        * system call - they are 00 - no permissions needed<br>        * 01 - read permission needed<br>        * 10 - write permission needed<br>        * 11 - read/write permissions needed<br>        * which is a lot more logical, and also allows the &quot;no perm&quot; needed<br>        * for symlinks (where the permissions are checked later).&nbsp; */<br>        int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode,         struct inode * base)<br>        {<br>        <em>const char * basename;<br>        int namelen,error;<br>        &nbsp;&nbsp;&nbsp; struct inode * dir, *inode;<br>        &nbsp;&nbsp;&nbsp; mode &amp;= S_IALLUGO &amp; ~current-&gt;fs-&gt;umask;<br>        &nbsp;&nbsp;&nbsp; mode |= S_IFREG;<br>        &nbsp;&nbsp;&nbsp; error = dir_namei(pathname, &amp;namelen, &amp;basename, base,         &amp;dir);<br>        &nbsp;&nbsp;&nbsp; if (error)<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return error;<br>        &nbsp;&nbsp;&nbsp; if (!namelen) { /* special case: '/usr/' etc */<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (flag &amp; 2) {<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iput(dir);<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EISDIR;<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>        &nbsp;&nbsp;&nbsp; /* thanks to Paul Pluzhnikov for noticing this was missing.. */<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((error = permission(dir,ACC_MODE(flag))) !=         0) {<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iput(dir);<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return error;         &nbsp;&nbsp;&nbsp; <br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *res_inode=dir;<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>        &nbsp;&nbsp;&nbsp; }<br>        &nbsp;&nbsp;&nbsp; dir-&gt;i_count++; /* lookup eats the dir */<br>        &nbsp;&nbsp;&nbsp; if (flag &amp; O_CREAT) {<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         down(&amp;dir-&gt;i_sem);<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error = lookup(dir,         basename, namelen, &amp;inode);<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!error) {<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;         if (flag &amp; O_EXCL) {<br>        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

⌨️ 快捷键说明

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