static int check_table(probectl *P, PROBETYPE *ptr) { PROBETYPE *x; int i, j; for (x = ptr, i = 0; i < _SS(NR_syscalls); i++, x++) { #ifdef OSI_PROBE_DEBUG if (probe_debug & 0x0040) { for (j = 0; j < 4; j++) { if (_SS(P->debug_ignore_NR[j]) == _SX(i + P->offset)) break; } if (j < 4) continue; } #endif for (j = 0; j < 8; j++) { if (_SS(probe_ignore_syscalls[j]) == _SX(i) + P->offset) break; } if (j < 8) continue; if (*x <= ktxt_lower_bound) { #ifdef OSI_PROBE_DEBUG if ((probe_debug & 0x0008) && DEBUG_IN_RANGE(P,ptr)) printk("<7>check 0x%lx -> %d [0x%lx]\n", (unsigned long)ptr, i, (unsigned long)*x); #endif return i; } } #ifdef OSI_PROBE_DEBUG if ((probe_debug & 0x0008) && DEBUG_IN_RANGE(P,ptr)) printk("<7>check 0x%lx -> ok\n", (unsigned long)ptr); #endif return -1; }
void upgradevlan(UINT num, char **arg) { bool ok; KAKUSHI *k = NULL; MS_DRIVER_VER ver; if (num < 1) { return; } InitWinUi(L"VPN", _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE")); if (MsIsNt()) { k = InitKakushi(); } CiInitDriverVerStruct(&ver); ok = MsUpgradeVLan(VLAN_ADAPTER_NAME_TAG, VLAN_CONNECTION_NAME, arg[0], &ver); FreeKakushi(k); FreeWinUi(); if (ok == false) { _exit(1); } else { _exit(0); } }
// Get an error string char *GetErrorStr(UINT err) { char *ret; char name[MAX_SIZE]; Format(name, sizeof(name), "ERR_%u", err); ret = GetTableStr(name); if (StrLen(ret) != 0) { return ret; } else { return _SS("ERR_UNKNOWN"); } }
// Initialize void InitNM() { if (nm != NULL) { // Already initialized return; } nm = ZeroMalloc(sizeof(NM)); InitWinUi(_UU("NM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE")); nm->Cedar = NewCedar(NULL, NULL); InitCM(false); InitSM(); }
bool LanguageTranslator::ConstBuffer_BeginExecute(ShaderScriptContext* c, const ASTCommand* command) { ConstMultiStringHelper h(command->GetParameters().AsString()); String name; String modName; bool determineContext = true; auto it = h.Iterate(); if (it.HasNext(name)) { StringPair semantic = StringUtils::Split(name, ':'); if (semantic.second != StringUtils::Null) { AutoParamName apn = Helper::GetAutoParam(semantic.second); if (apn != AutoParamName::AUTO_INVALID_PARAM) { name = std::move(semantic.first); c->shader->AddSemanticBinding("_" + name, apn); determineContext = false; } } } modName = "_"; modName += name; if (determineContext) { String context; String contextStr = _SS(TAG_CONTEXT); if (command->GetParameters().Find(contextStr, context)) { modName += "__"; modName += ShaderParameter::GetContextKey(Helper::GetContextFromName(context)); } } c->cbIsAutoParam = !determineContext; LanguageTranslator::Instance().BeginBuffer(c, name, modName); return true; }
/* * Helper function to process the load operation. */ static int xout_load_object(struct linux_binprm * bpp, struct pt_regs *rp, int executable) { struct xexec *xexec = (struct xexec *)bpp->buf; struct xext *xext = (struct xext *)(xexec + 1); struct xseg *seglist; struct file *fp = NULL; u_long addr, lPers; int nsegs, ntext, ndata; int pageable = 1, err = 0, i; #ifdef CONFIG_BINFMT_XOUT_X286 struct file *file; #endif lPers = abi_personality((char *)_BX(rp)); if (lPers == 0) lPers = PER_XENIX; if (xexec->x_magic != X_MAGIC) { return -ENOEXEC; } switch (xexec->x_cpu & XC_CPU) { case XC_386: break; #if defined(CONFIG_BINFMT_XOUT_X286) case XC_8086: case XC_286: case XC_286V: case XC_186: if (!Emulx286) return -ENOEXEC; file = open_exec(Emulx286); if (file) { fput(bpp->file); bpp->file = file; kernel_read(bpp->file, 0L, bpp->buf, sizeof(bpp->buf)); } return -ENOEXEC; #endif default: dprintk(KERN_DEBUG "xout: unsupported CPU type (%02x)\n", xexec->x_cpu); return -ENOEXEC; } /* * We can't handle byte or word swapped headers. Well, we * *could* but they should never happen surely? */ if ((xexec->x_cpu & (XC_BSWAP | XC_WSWAP)) != XC_WSWAP) { dprintk(KERN_DEBUG "xout: wrong byte or word sex (%02x)\n", xexec->x_cpu); return -ENOEXEC; } /* Check it's an executable. */ if (!(xexec->x_renv & XE_EXEC)) { dprintk(KERN_DEBUG "xout: not executable\n"); return -ENOEXEC; } /* * There should be an extended header and there should be * some segments. At this stage we don't handle non-segmented * binaries. I'm not sure you can get them under Xenix anyway. */ if (xexec->x_ext != sizeof(struct xext)) { dprintk(KERN_DEBUG "xout: bad extended header\n"); return -ENOEXEC; } if (!(xexec->x_renv & XE_SEG) || !xext->xe_segsize) { dprintk(KERN_DEBUG "xout: not segmented\n"); return -ENOEXEC; } if (!(seglist = kmalloc(xext->xe_segsize, GFP_KERNEL))) { printk(KERN_WARNING "xout: allocating segment list failed\n"); return -ENOMEM; } err = kernel_read(bpp->file, xext->xe_segpos, (char *)seglist, xext->xe_segsize); if (err < 0) { dprintk(KERN_DEBUG "xout: problem reading segment table\n"); goto out; } if (!bpp->file->f_op->mmap) pageable = 0; nsegs = xext->xe_segsize / sizeof(struct xseg); ntext = ndata = 0; for (i = 0; i < nsegs; i++) { switch (seglist[i].xs_type) { case XS_TTEXT: if (isnotaligned(seglist+i)) pageable = 0; ntext++; break; case XS_TDATA: if (isnotaligned(seglist+i)) pageable = 0; ndata++; break; } } if (!ndata) goto out; /* * Generate the proper values for the text fields * * THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD * SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD. */ /* * Flush the executable from memory. At this point the executable is * committed to being defined or a segmentation violation will occur. */ if (executable) { dprintk(KERN_DEBUG "xout: flushing executable\n"); flush_old_exec(bpp); if ( (lPers & 0xFF) == (current->personality & 0xFF) ) set_personality(0); set_personality(lPers); #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_UNIMPL, "Personality %08X assigned\n", (unsigned int)current->personality); #endif #ifdef CONFIG_64BIT set_thread_flag(TIF_IA32); clear_thread_flag(TIF_ABI_PENDING); #endif current->mm->mmap = NULL; #ifdef set_mm_counter #if _KSL > 14 set_mm_counter(current->mm, file_rss, 0); #else set_mm_counter(current->mm, rss, 0); #endif #else current->mm->rss = 0; #endif #if _KSL > 10 if ((err = setup_arg_pages(bpp, STACK_TOP, EXSTACK_DEFAULT)) < 0) #else if ((err = setup_arg_pages(bpp, EXSTACK_DEFAULT)) < 0) #endif { send_sig(SIGSEGV, current, 1); return (err); } bpp->p = (u_long)xout_create_tables((char *)bpp->p, bpp, (xexec->x_cpu & XC_CPU) == XC_386 ? 1 : 0); current->mm->start_code = 0; current->mm->end_code = xexec->x_text; current->mm->end_data = xexec->x_text + xexec->x_data; current->mm->start_brk = current->mm->brk = xexec->x_text + xexec->x_data + xexec->x_bss; #if _KSL > 28 install_exec_creds(bpp); #else compute_creds(bpp); #endif current->flags &= ~PF_FORKNOEXEC; #if _KSL < 15 #ifdef CONFIG_64BIT __asm__ volatile ( "movl %0,%%fs; movl %0,%%es; movl %0,%%ds" : :"r" (0)); __asm__ volatile ( "pushf; cli; swapgs; movl %0,%%gs; mfence; swapgs; popf" : :"r" (0)); write_pda(oldrsp,bpp->p); _FLG(rp) = 0x200; #else __asm__ volatile ( "movl %0,%%fs ; movl %0,%%gs" : :"r" (0)); _DS(rp) = _ES(rp) = __USER_DS; #endif _SS(rp) = __USER_DS; _SP(rp) = bpp->p; _CS(rp) = __USER_CS; _IP(rp) = xexec->x_entry; set_fs(USER_DS); #else start_thread(rp, xexec->x_entry, bpp->p); #endif #ifdef CONFIG_64BIT __asm__ volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); _SS(rp) = __USER32_DS; _CS(rp) = __USER32_CS; #endif dprintk(KERN_DEBUG "xout: entry point = 0x%x:0x%08lx\n", xext->xe_eseg, xexec->x_entry); } /* * Scan the segments and map them into the process space. If this * executable is pageable (unlikely since Xenix aligns to 1k * boundaries and we want it aligned to 4k boundaries) this is * all we need to do. If it isn't pageable we go round again * afterwards and load the data. We have to do this in two steps * because if segments overlap within a 4K page we'll lose the * first instance when we remap the page. Hope that's clear... */ for (i = 0; err >= 0 && i < nsegs; i++) { struct xseg *sp = seglist+i; if (sp->xs_attr & XS_AMEM) { err = xout_amen(fp, sp, pageable, &addr, xexec, rp, (!ntext && ndata == 1)); } } /* * We better fix start_data because sys_brk looks there to * calculate data size. * Kernel 2.2 did look at end_code so this is reasonable. */ if (current->mm->start_data == current->mm->start_code) current->mm->start_data = current->mm->end_code; dprintk(KERN_DEBUG "xout: start code 0x%08lx, end code 0x%08lx," " start data 0x%08lx, end data 0x%08lx, brk 0x%08lx\n", current->mm->start_code, current->mm->end_code, current->mm->start_data, current->mm->end_data, current->mm->brk); if (pageable) goto trap; if (err < 0) goto trap; for (i = 0; (err >= 0) && (i < nsegs); i++) { struct xseg *sp = seglist + i; u_long psize; if (sp->xs_type == XS_TTEXT || sp->xs_type == XS_TDATA) { dprintk(KERN_DEBUG "xout: read to 0x%08lx from 0x%08lx," " length 0x%8lx\n", sp->xs_rbase, sp->xs_filpos, sp->xs_psize); if (sp->xs_psize < 0) continue; /* * Do we still get the size ? Yes! [joerg] */ psize = kernel_read(bpp->file, sp->xs_filpos, (char *)((long)sp->xs_rbase), sp->xs_psize); if (psize != sp->xs_psize) { dprintk(KERN_DEBUG "xout: short read 0x%8lx\n",psize); err = -1; break; } } } /* * Generate any needed trap for this process. If an error occured then * generate a segmentation violation. If the process is being debugged * then generate the load trap. (Note: If this is a library load then * do not generate the trap here. Pass the error to the caller who * will do it for the process in the outer lay of this procedure call.) */ trap: if (executable) { if (err < 0) { dprintk(KERN_DEBUG "xout: loader forces seg fault " "(err = %d)\n", err); send_sig(SIGSEGV, current, 0); } #ifdef CONFIG_PTRACE /* --- Red Hat specific handling --- */ #else else if (current->ptrace & PT_PTRACED) send_sig(SIGTRAP, current, 0); #endif err = 0; } out: kfree(seglist); dprintk(KERN_DEBUG "xout: binfmt_xout: result = %d\n", err); /* * If we are using the [2]86 emulation overlay we enter this * rather than the real program and give it the information * it needs to start the ball rolling. */ /* * Xenix 386 programs expect the initial brk value to be in eax * on start up. Hence if we succeeded we need to pass back * the brk value rather than the status. Ultimately the * ret_from_sys_call assembly will place this in eax before * resuming (starting) the process. */ return (err < 0 ? err : current->mm->brk); }
// Create Cedar object CEDAR *NewCedar(X *server_x, K *server_k) { CEDAR *c; char tmp[MAX_SIZE]; char tmp2[MAX_SIZE]; char *beta_str; CedarForceLink(); c = ZeroMalloc(sizeof(CEDAR)); c->CurrentActiveLinks = NewCounter(); c->AcceptingSockets = NewCounter(); c->CedarSuperLock = NewLock(); c->CurrentRegionLock = NewLock(); StrCpy(c->OpenVPNDefaultClientOption, sizeof(c->OpenVPNDefaultClientOption), OVPN_DEF_CLIENT_OPTION_STRING); #ifdef BETA_NUMBER c->Beta = BETA_NUMBER; #endif // BETA_NUMBER InitNoSslList(c); c->AssignedBridgeLicense = NewCounter(); c->AssignedClientLicense = NewCounter(); c->CurrentTcpQueueSizeLock = NewLock(); c->QueueBudgetLock = NewLock(); c->FifoBudgetLock = NewLock(); Rand(c->UniqueId, sizeof(c->UniqueId)); c->CreatedTick = Tick64(); c->lock = NewLock(); c->ref = NewRef(); c->OpenVPNPublicPortsLock = NewLock(); c->CurrentTcpConnections = GetNumTcpConnectionsCounter(); c->ListenerList = NewList(CompareListener); c->UDPEntryList = NewList(CompareUDPEntry); c->HubList = NewList(CompareHub); c->ConnectionList = NewList(CompareConnection); c->ConnectionIncrement = NewCounter(); c->CurrentSessions = NewCounter(); if (server_k && server_x) { c->ServerK = CloneK(server_k); c->ServerX = CloneX(server_x); } c->Version = CEDAR_VER; c->Build = CEDAR_BUILD; c->ServerStr = CopyStr(CEDAR_SERVER_STR); GetMachineName(tmp, sizeof(tmp)); c->MachineName = CopyStr(tmp); c->HttpUserAgent = CopyStr(DEFAULT_USER_AGENT); c->HttpAccept = CopyStr(DEFAULT_ACCEPT); c->HttpAcceptLanguage = CopyStr("ja"); c->HttpAcceptEncoding = CopyStr(DEFAULT_ENCODING); c->Traffic = NewTraffic(); c->TrafficLock = NewLock(); c->CaList = NewList(CompareCert); c->TrafficDiffList = NewList(NULL); SetCedarCipherList(c, "RC4-MD5"); c->ClientId = _II("CLIENT_ID"); c->UdpPortList = NewIntList(false); InitNetSvcList(c); InitLocalBridgeList(c); InitCedarLayer3(c); c->WebUI = WuNewWebUI(c); #ifdef ALPHA_VERSION beta_str = "Alpha"; #else // ALPHA_VERSION #ifndef RELEASE_CANDIDATE beta_str = "Beta"; #else // RELEASE_CANDIDATE beta_str = "Release Candidate"; #endif // RELEASE_CANDIDATE #endif // ALPHA_VERSION ToStr(tmp2, c->Beta); Format(tmp, sizeof(tmp), "Version %u.%02u Build %u %s %s (%s)", CEDAR_VER / 100, CEDAR_VER - (CEDAR_VER / 100) * 100, CEDAR_BUILD, c->Beta == 0 ? "" : beta_str, c->Beta == 0 ? "" : tmp2, _SS("LANGSTR")); Trim(tmp); if (true) { SYSTEMTIME st; Zero(&st, sizeof(st)); st.wYear = BUILD_DATE_Y; st.wMonth = BUILD_DATE_M; st.wDay = BUILD_DATE_D; c->BuiltDate = SystemToUINT64(&st); } c->VerString = CopyStr(tmp); Format(tmp, sizeof(tmp), "Compiled %04u/%02u/%02u %02u:%02u:%02u by %s at %s", BUILD_DATE_Y, BUILD_DATE_M, BUILD_DATE_D, BUILD_DATE_HO, BUILD_DATE_MI, BUILD_DATE_SE, BUILDER_NAME, BUILD_PLACE); c->BuildInfo = CopyStr(tmp); return c; }
// License dialog UINT EmLicenseDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param) { RPC *s = (RPC *)param; NMHDR *n; // Validate arguments if (hWnd == NULL) { return 0; } switch (msg) { case WM_INITDIALOG: EmLicenseDlgInit(hWnd, s); break; case WM_NOTIFY: n = (NMHDR *)lParam; switch (n->code) { case LVN_ITEMCHANGED: switch (n->idFrom) { case L_LIST: case L_STATUS: EmLicenseDlgUpdate(hWnd, s); break; } break; } break; case WM_COMMAND: switch (wParam) { case IDOK: if (IsEnable(hWnd, IDOK)) { UINT i = LvGetSelected(hWnd, L_LIST); if (i != INFINITE) { char *s = LvGetStrA(hWnd, L_LIST, i, 5); char tmp[MAX_SIZE]; Format(tmp, sizeof(tmp), _SS("LICENSE_SUPPORT_URL"), s); ShellExecute(hWnd, "open", tmp, NULL, NULL, SW_SHOW); Free(s); } } break; case B_OBTAIN: ShellExecute(hWnd, "open", _SS("LICENSE_INFO_URL"), NULL, NULL, SW_SHOW); break; case B_ADD: if (EmLicenseAdd(hWnd, s)) { EmLicenseDlgRefresh(hWnd, s); } break; case B_DEL: if (IsEnable(hWnd, B_DEL)) { UINT id = (UINT)LvGetParam(hWnd, L_LIST, LvGetSelected(hWnd, L_LIST)); if (id != 0) { if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("SM_LICENSE_DELETE_MSG")) == IDYES) { RPC_TEST t; Zero(&t, sizeof(t)); t.IntValue = id; if (CALL(hWnd, EcDelLicenseKey(s, &t))) { EmLicenseDlgRefresh(hWnd, s); } } } } break; case IDCANCEL: Close(hWnd); break; } break; case WM_CLOSE: EndDialog(hWnd, 0); break; } LvStandardHandler(hWnd, msg, wParam, lParam, L_LIST); return 0; }
// Start the EtherLogger Manager void EMExec() { char *host; char *ret; bool cancel_now = false; TOKEN_LIST *t; UINT port = EL_ADMIN_PORT; InitWinUi(_UU("EM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE")); while (true) { ret = EmRemoteDlg(); if (ret != NULL) { t = ParseToken(ret, ":"); if (t->NumTokens == 1 || t->NumTokens == 2) { RPC *rpc = NULL; bool ok = false; UINT ret; host = t->Token[0]; if (t->NumTokens == 2) { port = ToInt(t->Token[1]); } else { port = EL_ADMIN_PORT; } // Try without a password first ret = EcConnect(host, port, "", &rpc); RETRY: if (ret != ERR_NO_ERROR && ret != ERR_AUTH_FAILED) { // Connection failed CALL(NULL, ret); } else { if (ret == ERR_NO_ERROR) { // Successful connection ok = true; } else { // Password required char *pass = SmPassword(NULL, host); if (pass == NULL) { // Cancel cancel_now = true; } else { // Retry ret = EcConnect(host, port, pass, &rpc); Free(pass); if (ret == ERR_NO_ERROR) { ok = true; } else { goto RETRY; } } } } if (ok) { // Main screen EMMain(rpc); // Disconnect EcDisconnect(rpc); cancel_now = true; } FreeToken(t); } Free(ret); } else { cancel_now = true; } if (cancel_now) { break; } } FreeWinUi(); }
// Read the string table bool LoadTableMain(wchar_t *filename) { BUF *b; UINT64 t1, t2; UCHAR hash[MD5_SIZE]; // Validate arguments if (filename == NULL) { return false; } if (MayaquaIsMinimalMode()) { return true; } if (UniStrCmpi(old_table_name, filename) == 0) { // Already loaded return true; } t1 = Tick64(); // Open the file b = ReadDumpW(filename); if (b == NULL) { char tmp[MAX_SIZE]; StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (file not found).\r\nPlease check hamcore.se2.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)"); Alert(tmp, NULL); exit(-1); return false; } Hash(hash, b->Buf, b->Size, false); if (LoadUnicodeCache(filename, b->Size, hash) == false) { if (LoadTableFromBuf(b) == false) { FreeBuf(b); return false; } SaveUnicodeCache(filename, b->Size, hash); //Debug("Unicode Source: strtable.stb\n"); } else { //Debug("Unicode Source: unicode_cache\n"); } FreeBuf(b); SetLocale(_UU("DEFAULE_LOCALE")); UniStrCpy(old_table_name, sizeof(old_table_name), filename); t2 = Tick64(); if (StrCmpi(_SS("STRTABLE_ID"), STRTABLE_ID) != 0) { char tmp[MAX_SIZE]; Format(tmp, sizeof(tmp), "Error: Can't read string tables (invalid version: '%s'!='%s').\r\nPlease check hamcore.se2.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)", _SS("STRTABLE_ID"), STRTABLE_ID); Alert(tmp, NULL); exit(-1); return false; } //Debug("Unicode File Read Cost: %u (%u Lines)\n", (UINT)(t2 - t1), LIST_NUM(TableList)); return true; }
/* * Helper function to process the load operation. */ static int coff_load_object(struct linux_binprm *bprm, struct pt_regs *regs, int binary) { COFF_FILHDR *coff_hdr = NULL; COFF_SCNHDR *text_sect = NULL, *data_sect = NULL, *bss_sect = NULL, *sect_bufr = NULL, *sect_ptr = NULL; int text_count = 0, data_count = 0, bss_count = 0, lib_count = 0; coff_section text, data, bss; u_long start_addr = 0, p = bprm->p, m_addr, lPers; short flags, aout_size = 0; int pageable = 1, sections = 0, status = 0, i, ce; int coff_exec_fileno; mm_segment_t old_fs; lPers = abi_personality((char *)_BX(regs)); ce = cap_mmap(0); coff_hdr = (COFF_FILHDR *)bprm->buf; /* * Validate the magic value for the object file. */ if (COFF_I386BADMAG(*coff_hdr)) return -ENOEXEC; flags = COFF_SHORT(coff_hdr->f_flags); /* * The object file should have 32 BIT little endian format. Do not allow * it to have the 16 bit object file flag set as Linux is not able to run * on the 80286/80186/8086. */ if ((flags & (COFF_F_AR32WR | COFF_F_AR16WR)) != COFF_F_AR32WR) return -ENOEXEC; /* * If the file is not executable then reject the execution. This means * that there must not be external references. */ if ((flags & COFF_F_EXEC) == 0) return -ENOEXEC; /* * Extract the header information which we need. */ sections = COFF_SHORT(coff_hdr->f_nscns); /* Number of sections */ aout_size = COFF_SHORT(coff_hdr->f_opthdr); /* Size of opt. headr */ /* * There must be at least one section. */ if (!sections) return -ENOEXEC; if (!bprm->file->f_op->mmap) pageable = 0; if (!(sect_bufr = kmalloc(sections * COFF_SCNHSZ, GFP_KERNEL))) { printk(KERN_WARNING "coff: kmalloc failed\n"); return -ENOMEM; } status = kernel_read(bprm->file, aout_size + COFF_FILHSZ, (char *)sect_bufr, sections * COFF_SCNHSZ); if (status < 0) { printk(KERN_WARNING "coff: unable to read\n"); goto out_free_buf; } status = get_unused_fd(); if (status < 0) { printk(KERN_WARNING "coff: unable to get free fs\n"); goto out_free_buf; } get_file(bprm->file); fd_install(coff_exec_fileno = status, bprm->file); /* * Loop through the sections and find the various types */ sect_ptr = sect_bufr; for (i = 0; i < sections; i++) { long int sect_flags = COFF_LONG(sect_ptr->s_flags); switch (sect_flags) { case COFF_STYP_TEXT: status |= coff_isaligned(sect_ptr); text_sect = sect_ptr; text_count++; break; case COFF_STYP_DATA: status |= coff_isaligned(sect_ptr); data_sect = sect_ptr; data_count++; break; case COFF_STYP_BSS: bss_sect = sect_ptr; bss_count++; break; case COFF_STYP_LIB: lib_count++; break; default: break; } sect_ptr = (COFF_SCNHDR *) & ((char *) sect_ptr)[COFF_SCNHSZ]; } /* * If any of the sections weren't properly aligned we aren't * going to be able to demand page this executable. Note that * at this stage the *only* excuse for having status <= 0 is if * the alignment test failed. */ if (status < 0) pageable = 0; /* * Ensure that there are the required sections. There must be one * text sections and one each of the data and bss sections for an * executable. A library may or may not have a data / bss section. */ if (text_count != 1) { status = -ENOEXEC; goto out_free_file; } if (binary && (data_count != 1 || bss_count != 1)) { status = -ENOEXEC; goto out_free_file; } /* * If there is no additional header then assume the file starts * at the first byte of the text section. This may not be the * proper place, so the best solution is to include the optional * header. A shared library __MUST__ have an optional header to * indicate that it is a shared library. */ if (aout_size == 0) { if (!binary) { status = -ENOEXEC; goto out_free_file; } start_addr = COFF_LONG(text_sect->s_vaddr); } else if (aout_size < (short) COFF_AOUTSZ) { status = -ENOEXEC; goto out_free_file; } else { COFF_AOUTHDR *aout_hdr; short aout_magic; aout_hdr = (COFF_AOUTHDR *) &((char *)coff_hdr)[COFF_FILHSZ]; aout_magic = COFF_SHORT(aout_hdr->magic); /* * Validate the magic number in the a.out header. If it is valid then * update the starting symbol location. Do not accept these file formats * when loading a shared library. */ switch (aout_magic) { case COFF_OMAGIC: case COFF_ZMAGIC: case COFF_STMAGIC: if (!binary) { status = -ENOEXEC; goto out_free_file; } start_addr = (u_int)COFF_LONG(aout_hdr->entry); break; /* * Magic value for a shared library. This is valid only when * loading a shared library. * * (There is no need for a start_addr. It won't be used.) */ case COFF_SHMAGIC: if (!binary) break; /* FALLTHROUGH */ default: status = -ENOEXEC; goto out_free_file; } } /* * Generate the proper values for the text fields * * THIS IS THE POINT OF NO RETURN. THE NEW PROCESS WILL TRAP OUT SHOULD * SOMETHING FAIL IN THE LOAD SEQUENCE FROM THIS POINT ONWARD. */ text.scnptr = COFF_LONG(text_sect->s_scnptr); text.size = COFF_LONG(text_sect->s_size); text.vaddr = COFF_LONG(text_sect->s_vaddr); /* * Generate the proper values for the data fields */ if (data_sect != NULL) { data.scnptr = COFF_LONG(data_sect->s_scnptr); data.size = COFF_LONG(data_sect->s_size); data.vaddr = COFF_LONG(data_sect->s_vaddr); } else { data.scnptr = 0; data.size = 0; data.vaddr = 0; } /* * Generate the proper values for the bss fields */ if (bss_sect != NULL) { bss.size = COFF_LONG(bss_sect->s_size); bss.vaddr = COFF_LONG(bss_sect->s_vaddr); } else { bss.size = 0; bss.vaddr = 0; } /* * Flush the executable from memory. At this point the executable is * committed to being defined or a segmentation violation will occur. */ if (binary) { COFF_SCNHDR *sect_ptr2 = sect_bufr; u_long personality = PER_SVR3; int i; if ((status = flush_old_exec(bprm))) goto out_free_file; /* * Look for clues as to the system this binary was compiled * on in the comments section(s). * * Only look at the main binary, not the shared libraries * (or would it be better to prefer shared libraries over * binaries? Or could they be different???) */ for (i = 0; i < sections; i++) { long sect_flags = COFF_LONG(sect_ptr2->s_flags); if (sect_flags == COFF_STYP_INFO && (status = coff_parse_comments(bprm->file, sect_ptr2, &personality)) > 0) goto found; sect_ptr2 = (COFF_SCNHDR *) &((char *)sect_ptr2)[COFF_SCNHSZ]; } /* * If no .comments section was found there is no way to * figure out the personality. Odds on it is SCO though... */ personality = PER_SCOSVR3; found: if (lPers) personality = lPers; if ( (personality & 0xFF) == (current->personality & 0xFF) ) set_personality(0); set_personality(personality); #if defined(CONFIG_ABI_TRACE) abi_trace(ABI_TRACE_UNIMPL,"Personality %08lX assigned\n",personality); #endif #ifdef CONFIG_64BIT set_thread_flag(TIF_IA32); clear_thread_flag(TIF_ABI_PENDING); #endif current->mm->start_data = 0; current->mm->end_data = 0; current->mm->end_code = 0; current->mm->mmap = NULL; current->flags &= ~PF_FORKNOEXEC; #ifdef set_mm_counter #if _KSL > 14 set_mm_counter(current->mm, file_rss, 0); #else set_mm_counter(current->mm, rss, 0); #endif #else current->mm->rss = 0; #endif /* * Construct the parameter and environment * string table entries. */ #if _KSL > 10 if ((status = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT)) < 0) #else if ((status = setup_arg_pages(bprm, EXSTACK_DEFAULT)) < 0) #endif goto sigsegv; p = (u_long)coff_mktables((char *)bprm->p, bprm->argc, bprm->envc); current->mm->end_code = text.size + (current->mm->start_code = text.vaddr); current->mm->end_data = data.size + (current->mm->start_data = data.vaddr); current->mm->brk = bss.size + (current->mm->start_brk = bss.vaddr); current->mm->start_stack = p; #if _KSL > 28 install_exec_creds(bprm); #else compute_creds(bprm); #endif #if _KSL < 15 #ifdef CONFIG_64BIT __asm__ volatile ( "movl %0,%%fs; movl %0,%%es; movl %0,%%ds" : :"r" (0)); __asm__ volatile ( "pushf; cli; swapgs; movl %0,%%gs; mfence; swapgs; popf" : :"r" (0)); write_pda(oldrsp,p); _FLG(regs) = 0x200; #else __asm__ volatile ( "movl %0,%%fs ; movl %0,%%gs" : :"r" (0)); _DS(regs) = _ES(regs) = __USER_DS; #endif _SS(regs) = __USER_DS; _SP(regs) = p; _CS(regs) = __USER_CS; _IP(regs) = start_addr; set_fs(USER_DS); #else start_thread(regs, start_addr, p); #endif #ifdef CONFIG_64BIT __asm__ volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); _SS(regs) = __USER32_DS; _CS(regs) = __USER32_CS; #endif } old_fs = get_fs(); set_fs(get_ds()); if (!pageable) { /* * Read the file from disk... * * XXX: untested. */ loff_t pos = data.scnptr; status = do_brk(text.vaddr, text.size); bprm->file->f_op->read(bprm->file, (char *)data.vaddr, data.scnptr, &pos); status = do_brk(data.vaddr, data.size); bprm->file->f_op->read(bprm->file, (char *)text.vaddr, text.scnptr, &pos); status = 0; } else { /* map the text pages...*/ cap_mmap(1); m_addr = map_coff(bprm->file, &text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, text.scnptr & PAGE_MASK); if(!ce) cap_mmap(2); if (m_addr != (text.vaddr & PAGE_MASK)) { status = -ENOEXEC; set_fs(old_fs); goto out_free_file; } /* map the data pages */ if (data.size != 0) { cap_mmap(1); m_addr = map_coff(bprm->file, &data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, data.scnptr & PAGE_MASK); if(!ce) cap_mmap(2); if (m_addr != (data.vaddr & PAGE_MASK)) { status = -ENOEXEC; set_fs(old_fs); goto out_free_file; } } status = 0; } /* * Construct the bss data for the process. The bss ranges from the * end of the data (which may not be on a page boundary) to the end * of the bss section. Allocate any necessary pages for the data. */ if (bss.size != 0) { cap_mmap(1); down_write(¤t->mm->mmap_sem); do_mmap(NULL, PAGE_ALIGN(bss.vaddr), bss.size + bss.vaddr - PAGE_ALIGN(bss.vaddr), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_32BIT, 0); up_write(¤t->mm->mmap_sem); if(!ce) cap_mmap(2); if ((status = coff_clear_memory(bss.vaddr, bss.size)) < 0) { set_fs(old_fs); goto out_free_file; } } set_fs(old_fs); if (!binary) goto out_free_file; /* * Load any shared library for the executable. */ if (lib_count) status = coff_preload_shlibs(bprm, sect_bufr, sections); set_binfmt(&coff_format); /* * Generate any needed trap for this process. If an error occured then * generate a segmentation violation. If the process is being debugged * then generate the load trap. (Note: If this is a library load then * do not generate the trap here. Pass the error to the caller who * will do it for the process in the outer lay of this procedure call.) */ if (status < 0) { sigsegv: printk(KERN_WARNING "coff: trapping process with SEGV\n"); send_sig(SIGSEGV, current, 0); /* Generate the error trap */ } #ifdef CONFIG_PTRACE /* --- Red Hat specific handling --- */ #else else if (current->ptrace & PT_PTRACED) send_sig(SIGTRAP, current, 0); #endif /* We are committed. It can't fail */ status = 0; out_free_file: SYS(close,coff_exec_fileno); out_free_buf: kfree(sect_bufr); return (status); }