You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*<2A><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>do_execve2,exec.c<><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><D8B7><EFBFBD>û<EFBFBD>иĶ<D0B8>
* do_execve2<65><32>Ҫʵ<D2AA><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD>ʽִ<CABD>п<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ֻ<EFBFBD><D6BB>Ҫ<EFBFBD><D2AA><EFBFBD>պ<EFBFBD><D5BA><EFBFBD>do_no_page<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>my_do_no_page<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD>do_no_page<67><65>ȫһ<C8AB><D2BB>
* <20><><EFBFBD><EFBFBD>дһ<D0B4><D2BB><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD>ȵ<EFBFBD>do_no_page<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD>ӡ<EFBFBD><D3A1>Ϣ
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ԭ<EFBFBD>ȵ<EFBFBD>do_no_page<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>һ<EFBFBD>ζ<EFBFBD><CEB6><EFBFBD><EFBFBD>ӡ<EFBFBD><D3A1>Ϣ
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7>б<EFBFBD>do_execve2<65><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>صĹ<D8B5><C4B9><EFBFBD>
*/
int do_execve2(unsigned long* eip, long tmp, char* filename,
char** argv, char** envp)
{
struct m_inode* inode;
struct buffer_head* bh;
struct exec ex;
unsigned long page[MAX_ARG_PAGES];
int i, argc, envc;
int e_uid, e_gid;
int retval;
int sh_bang = 0;
unsigned long p = PAGE_SIZE * MAX_ARG_PAGES - 4;
if ((0xffff & eip[1]) != 0x000f)
panic("execve2 called from supervisor mode");
for (i = 0; i < MAX_ARG_PAGES; i++) /* clear page-table */
page[i] = 0;
if (!(inode = namei(filename))) /* get executables inode */
return -ENOENT;
argc = count(argv);
envc = count(envp);
restart_interp:
if (!S_ISREG(inode->i_mode)) { /* must be regular file */
retval = -EACCES;
goto exec_error2;
}
i = inode->i_mode;
e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
if (current->euid == inode->i_uid)
i >>= 6;
else if (current->egid == inode->i_gid)
i >>= 3;
if (!(i & 1) &&
!((inode->i_mode & 0111) && suser())) {
retval = -ENOEXEC;
goto exec_error2;
}
if (!(bh = bread(inode->i_dev, inode->i_zone[0]))) {
retval = -EACCES;
goto exec_error2;
}
ex = *((struct exec*)bh->b_data); /* read exec-header */
if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
/*
* This section does the #! interpretation.
* Sorta complicated, but hopefully it will work. -TYT
*/
char buf[1023], * cp, * interp, * i_name, * i_arg;
unsigned long old_fs;
strncpy(buf, bh->b_data + 2, 1022);
brelse(bh);
iput(inode);
buf[1022] = '\0';
if (cp = strchr(buf, '\n')) {
*cp = '\0';
for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);
}
if (!cp || *cp == '\0') {
retval = -ENOEXEC; /* No interpreter name found */
goto exec_error1;
}
interp = i_name = cp;
i_arg = 0;
for (; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
if (*cp == '/')
i_name = cp + 1;
}
if (*cp) {
*cp++ = '\0';
i_arg = cp;
}
/*
* OK, we've parsed out the interpreter name and
* (optional) argument.
*/
if (sh_bang++ == 0) {
p = copy_strings(envc, envp, page, p, 0);
p = copy_strings(--argc, argv + 1, page, p, 0);
}
/*
* Splice in (1) the interpreter's name for argv[0]
* (2) (optional) argument to interpreter
* (3) filename of shell script
*
* This is done in reverse order, because of how the
* user environment and arguments are stored.
*/
p = copy_strings(1, &filename, page, p, 1);
argc++;
if (i_arg) {
p = copy_strings(1, &i_arg, page, p, 2);
argc++;
}
p = copy_strings(1, &i_name, page, p, 2);
argc++;
if (!p) {
retval = -ENOMEM;
goto exec_error1;
}
/*
* OK, now restart the process with the interpreter's inode.
*/
old_fs = get_fs();
set_fs(get_ds());
if (!(inode = namei(interp))) { /* get executables inode */
set_fs(old_fs);
retval = -ENOENT;
goto exec_error1;
}
set_fs(old_fs);
goto restart_interp;
}
brelse(bh);
if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
ex.a_text + ex.a_data + ex.a_bss > 0x3000000 ||
inode->i_size < ex.a_text + ex.a_data + ex.a_syms + N_TXTOFF(ex)) {
retval = -ENOEXEC;
goto exec_error2;
}
if (N_TXTOFF(ex) != BLOCK_SIZE) {
printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
retval = -ENOEXEC;
goto exec_error2;
}
if (!sh_bang) {
p = copy_strings(envc, envp, page, p, 0);
p = copy_strings(argc, argv, page, p, 0);
if (!p) {
retval = -ENOMEM;
goto exec_error2;
}
}
/* OK, This is the point of no return */
if (current->executable)
iput(current->executable);
current->executable = inode;
for (i = 0; i < 32; i++)
current->sigaction[i].sa_handler = NULL;
for (i = 0; i < NR_OPEN; i++)
if ((current->close_on_exec >> i) & 1)
sys_close(i);
current->close_on_exec = 0;
free_page_tables(get_base(current->ldt[1]), get_limit(0x0f));
free_page_tables(get_base(current->ldt[2]), get_limit(0x17));
if (last_task_used_math == current)
last_task_used_math = NULL;
current->used_math = 0;
p += change_ldt(ex.a_text, page) - MAX_ARG_PAGES * PAGE_SIZE;
p = (unsigned long)create_tables((char*)p, argc, envc);
current->brk = ex.a_bss +
(current->end_data = ex.a_data +
(current->end_code = ex.a_text));
current->start_stack = p & 0xfffff000;
current->euid = e_uid;
current->egid = e_gid;
/* <20>޸IJ<DEB8><C4B2><EFBFBD> */
unsigned long No_Page_Addr;
unsigned long Addr_End = (current->brk - 1) & 0xfffff000;
for (No_Page_Addr = 0; No_Page_Addr <= Addr_End; No_Page_Addr += 0x1000)
my_do_no_page(4, No_Page_Addr + current->start_code); /* <20><><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ4<CEAA><34>6<EFBFBD><36><EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>4<EFBFBD><34>ʾ<EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>6<EFBFBD><36>ʾ<EFBFBD><CABE>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
/* <20>޸IJ<DEB8><C4B2><EFBFBD> */
i = ex.a_text + ex.a_data;
while (i & 0xfff)
put_fs_byte(0, (char*)(i++));
eip[0] = ex.a_entry; /* eip, magic happens :-) */
eip[3] = p; /* stack pointer */
return 0;
exec_error2:
iput(inode);
exec_error1:
for (i = 0; i < MAX_ARG_PAGES; i++)
free_page(page[i]);
return(retval);
}