void cmd_flash_nand(const char *arg, void *data, unsigned sz) { u8 msg[128] = {0}; if(sz == 0) { fastboot_okay(""); return; } //Please DO NOT get any data for reference if security check is not passed if(!security_check(&data, &sz, 0, arg)) { sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); dprintf(DBG_LV, msg); fastboot_fail_wrapper(msg); return; } dprintf(DBG_LV, "cmd_flash_nand, data:0x%x\n",*(int*)data); if(cmd_flash_nand_img(arg,data,sz)) { //[Security] Notify security check that is the end. sz = 0; security_check(&data, &sz, IMAGE_TRUNK_SIZE, arg); } }
int example_syscall(struct credential *cred, int index, int op) { struct object *o; int error = get_object(index, &o); if (error != 0) return (error); des_cblock des_key; des_key_schedule key_schedule; crypto_setup(&des_key, &key_schedule); if ((error = security_check(cred, o, op))) return error; some_helper(op); void_helper(o); perform_operation(op, o); crypto_encrypt(&des_key, &key_schedule); log_audit_record(o, op); release(o); return 0; }
int perform_operation(int op, struct object *o) { #ifdef TESLA /* A very simple TESLA assertion. */ TESLA_WITHIN(example_syscall, previously(security_check(ANY(ptr), o, op) == 0)); /* An even simpler assertion! */ TESLA_WITHIN(example_syscall, previously(call(security_check))); /* More simple assertions. */ TESLA_WITHIN(example_syscall, previously(call(hold(o)))); TESLA_WITHIN(example_syscall, previously(returnfrom(hold(o)))); TESLA_WITHIN(example_syscall, eventually(call(release(o)))); /* A simple assertion about struct manipulation. */ TESLA_WITHIN(example_syscall, previously(o->refcount += 1)); /* An example of using high-level TESLA macros. */ TESLA_WITHIN(example_syscall, previously(security_check(ANY(ptr), o, op) == 0) || eventually(log_audit_record(o, op) == 0) ); /* An example of using the lower-level TESLA interface. */ TESLA_GLOBAL(call(example_syscall), returnfrom(example_syscall), TSEQUENCE( get_object(ANY(int), ANY(ptr)) == 0, security_check(ANY(ptr), o, op) == 0, some_helper(op) == 0 || call(never_actually_called), optional(call(void_helper(o))), TESLA_ASSERTION_SITE, returnfrom(release(o)) ) ); #endif return 0; }
static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bootm_headers_t images; #ifdef CONFIG_SECURE_BOOT #ifndef CONFIG_SPL_BUILD security_check(); #endif #endif if (bootz_start(cmdtp, flag, argc, argv, &images)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif arch_preboot_os(); do_bootm_linux(0, argc, argv, &images); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); #endif do_reset(cmdtp, flag, argc, argv); return 1; }
int write_storage_proc(void *arg) { u8* data = 0; u32 data_len = 0; char msg[128]; u64 image_offset = 0; u32 round = 0; //dprintf(DBG_DCACHE, " --[%d] Enter write_storage_proc \n", TIME_STAMP); for (;;) { dprintf(DBG_DCACHE, " --[%d]Wait ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); event_wait(&(ctx.dual_cache[ctx.flipIdxR].content_available)); dprintf(DBG_DCACHE, " --[%d]Obtain ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); if(ctx.b_error) { sprintf(msg, "\nError USB?\n"); goto error; } //if has something to write if(ctx.dual_cache[ctx.flipIdxR].content_length !=0 || ctx.dual_cache[ctx.flipIdxR].padding_length !=0) { data = (u8*)(ctx.dual_cache[ctx.flipIdxR].cache_buf); data_len = ctx.dual_cache[ctx.flipIdxR].content_length; #ifdef MTK_SECURITY_SW_SUPPORT if(!security_check(&data, &data_len, image_offset, NULL)) { //security error. sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); goto error; } #endif image_offset += ctx.dual_cache[ctx.flipIdxR].content_length; data -= ctx.dual_cache[ctx.flipIdxR].padding_length; data_len += ctx.dual_cache[ctx.flipIdxR].padding_length; //if data_len==0, secure img tail met. dprintf(DBG_DCACHE, " --[%d]Write ID:%d to EMMC \n", TIME_STAMP, ctx.flipIdxR); #ifdef MTK_SECURITY_SW_SUPPORT if(!write_data(data, data_len, sec_lib_security_get_img_total_size())) #else if(!write_data(data, data_len, 0)) #endif { //error sprintf(msg, "\nWrite data error. \n"); goto error; } } //last package, should return; if (ctx.dual_cache[ctx.flipIdxR].content_length == 0) { dprintf(DBG_DCACHE, " --[%d]Write EMMC Fin\n", TIME_STAMP); data_len = 0; #ifdef MTK_SECURITY_SW_SUPPORT security_check(&data, &data_len, image_offset, NULL); //notify security check that is the end. #endif if(ctx.boot_like_info.is_boot_like_image) { //boot image need download_size to flash. download_size = sto_info.to_write_data_len; //cache using is over, so copy boot image to download_base memcpy(download_base, ctx.boot_like_info.boot_like_image_address, download_size); } event_signal(&ctx.dual_cache[0].cache_available, SIGNAL_RESCHEDULE);//prevent from dead lock. event_signal(&ctx.dual_cache[1].cache_available, SIGNAL_RESCHEDULE); event_signal(&ctx.thr_end_ev, SIGNAL_RESCHEDULE); return 0; } round++; dprintf(DBG_DCACHE, " --[%d]Notify ID:%d cache writeable\n", TIME_STAMP, ctx.flipIdxR); event_signal(&ctx.dual_cache[ctx.flipIdxR].cache_available, SIGNAL_RESCHEDULE); //make this cache writeable again. ctx.flipIdxR = cache_shift(ctx.flipIdxR); //change next buffer. } return 0; error: dprintf(DBG_LV, msg); display_info(msg); abort_engine(&ctx); return (-1); }
BOOL cmd_flash_nand_img(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; int img_type; char *p_type; char msg[256]; index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return FALSE; } if(!is_support_flash(index)){ sprintf(msg,"partition '%s' not support flash\n",arg); fastboot_fail_wrapper(msg); return FALSE; } offset = partition_get_offset(index); if(offset == (u64)(-1)){ fastboot_fail_wrapper("partition get offset fail"); return FALSE; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == (u64)(-1)){ fastboot_fail_wrapper("partition get size fail"); return FALSE; }else{ printf("get size: 0x%llx\n",size); } if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (memcmp((void *)data, BOOT_MAGIC, strlen(BOOT_MAGIC))) { fastboot_fail_wrapper("image is not a boot image"); return FALSE; } } { char i_type[20] = {0}; get_image_type(data,sz,(char *)i_type); partition_get_type(index,&p_type); if(strcmp(i_type,p_type)){ display_info("[warning]image type is not match with partition type\n"); dprintf(DBG_LV, "[warning]image type'%s' is not match with partition type'%s'",i_type,p_type); } if(!strcmp(i_type,"raw data")){ img_type = RAW_DATA_IMG; }else if(!strcmp(i_type,"yaffs2")){ img_type = YFFS2_IMG; }else if(!strcmp(i_type,"ubifs")){ img_type = UBIFS_IMG; }else{ dprintf(DBG_LV, "image type '%s' unkown\n",i_type); display_info("\nimage type unkown"); return FALSE; } } TIME_START; display_info("write flash ...."); printf("writing %d bytes to '%s' img_type %d\n", sz, arg,img_type); #if defined(MTK_MLC_NAND_SUPPORT) if (nand_write_img((u64)offset, (char*)data, sz,(u64)size,img_type)) { #else if (nand_write_img((u32)offset, (char*)data, sz,(u32)size,img_type)) { #endif fastboot_fail_wrapper("nand write image failure"); return FALSE; } printf("partition '%s' updated\n", arg); fastboot_ok_wrapper("write flash sucess",sz); return TRUE; } void cmd_flash_nand(const char *arg, void *data, unsigned sz) { char msg[128] = {0}; if(sz == 0) { fastboot_okay(""); return; } #ifdef MTK_SECURITY_SW_SUPPORT //Please DO NOT get any data for reference if security check is not passed if(!security_check((u8**)&data, &sz, 0, arg)) { sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); dprintf(DBG_LV, msg); fastboot_fail_wrapper(msg); return; } #endif dprintf(DBG_LV, "cmd_flash_nand, data:0x%x\n",*(int*)data); if(cmd_flash_nand_img(arg,data,sz)) { //[Security] Notify security check that is the end. sz = 0; #ifdef MTK_SECURITY_SW_SUPPORT security_check((u8**)&data, &sz, IMAGE_TRUNK_SIZE, arg); #endif } }
void cmd_flash_emmc(const char *arg, void *data, unsigned sz) { sparse_header_t *sparse_header; /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */ //unsigned int *magic_number = (unsigned int *) data; BOOL write_ret = TRUE; char msg[128] = {0}; #if 0 if (magic_number[0] == DECRYPT_MAGIC_0 && magic_number[1] == DECRYPT_MAGIC_1) { #ifdef SSD_ENABLE ret = decrypt_scm((u32 **) &data, &sz); #endif if (ret != 0) { dprintf(CRITICAL, "ERROR: Invalid secure image\n"); return; } } else if (magic_number[0] == ENCRYPT_MAGIC_0 && magic_number[1] == ENCRYPT_MAGIC_1) { #ifdef SSD_ENABLE ret = encrypt_scm((u32 **) &data, &sz); #endif if (ret != 0) { dprintf(CRITICAL, "ERROR: Encryption Failure\n"); return; } } #endif if(sz == 0) { fastboot_okay(""); return; } #ifdef MTK_SECURITY_SW_SUPPORT //[Security] Please DO NOT get any data for reference if security check is not passed if(!security_check((u8**)&data, &sz, 0, arg)) { sprintf(msg, "\nSecurity deny - Err:0x%x \n", sec_error()); dprintf(DBG_LV, msg); fastboot_fail_wrapper((char*)msg); return; } #endif sparse_header = (sparse_header_t *) data; dprintf(DBG_LV, "cmd_flash_emmc, data:0x%x,, n sparse_header->magic = 0x%x\n",*(int*)data, sparse_header->magic ); if (sparse_header->magic != SPARSE_HEADER_MAGIC) { write_ret = cmd_flash_emmc_img(arg, data, sz); } else { write_ret = cmd_flash_emmc_sparse_img(arg, data, sz); } if( write_ret ) { //[Security] Notify security check that is the end. sz = 0; #ifdef MTK_SECURITY_SW_SUPPORT security_check((u8**)&data, &sz, IMAGE_TRUNK_SIZE, arg); #endif } }
/* the return value is always NULL */ void *tcpsocket(void *arg) { int n, jobcount; int connect_accept = 1, connect_continue = 1, handshake; joblist_t *job; /* these are used for communication over the TCP socket */ int fd = 0; message_t *message = NULL; threadlocal_t threadlocal; threadlocal.message = &message; threadlocal.fd = &fd; /* the connection to the client has been made by the server */ fd = ((int)arg); pthread_cleanup_push(cleanup_tcpsocket, &threadlocal); /* this is for debugging */ pthread_mutex_lock(&mutexthreadcount); threadcount++; pthread_mutex_unlock(&mutexthreadcount); /* this is for debugging */ pthread_mutex_lock(&mutexsocketcount); socketcount++; pthread_mutex_unlock(&mutexsocketcount); /* prevent smartcpu_update during the negociation and reading of the job */ pthread_mutex_lock(&mutexsmartcpu); smartcpu.freeze = 1; pthread_mutex_unlock(&mutexsmartcpu); /* prevent smartmem_update during the negociation and reading of the job */ pthread_mutex_lock(&mutexsmartmem); smartmem.freeze = 1; pthread_mutex_unlock(&mutexsmartmem); DEBUG(LOG_DEBUG, "tcpsocket: fd = %d, socketcount = %d, threadcount = %d", fd, socketcount, threadcount); pthread_mutex_lock(&mutexjoblist); jobcount = 0; job = joblist; while (job) { jobcount++; job = job->next; } pthread_mutex_unlock(&mutexjoblist); pthread_mutex_lock(&mutexhost); if (host->status==STATUS_MASTER) { connect_accept = 1; } else if (host->status==STATUS_IDLE && jobcount==0) { connect_accept = 1; } else { DEBUG(LOG_INFO, "tcpsocket: failed on status (%d) and/or jobcount (%d)", host->status, jobcount); connect_accept = 0; } pthread_mutex_unlock(&mutexhost); /* give a handshake */ handshake = connect_accept || connect_continue; if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) { DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int)); goto cleanup; } if (!connect_continue) { DEBUG(LOG_INFO, "tcpsocket: dropping connection"); goto cleanup; } message = (message_t*)malloc(sizeof(message_t)); message->host = (hostdef_t*)malloc(sizeof(hostdef_t)); message->job = (jobdef_t*)malloc(sizeof(jobdef_t)); message->arg = NULL; message->opt = NULL; /* read the host details */ if ((n = bufread(fd, message->host, sizeof(hostdef_t))) != sizeof(hostdef_t)) { DEBUG(LOG_DEBUG, "tcpsocket: read size = %d, should be %d", n, sizeof(hostdef_t)); goto cleanup; } /* test whether the version is compatible */ if (message->host->version!=VERSION) { DEBUG(LOG_ERR, "tcpsocket: incorrect host version (%u, %u)", message->host->version, VERSION); connect_accept = 0; connect_continue = 0; /* prevent another read request */ } /* determine whether the host, group and user is allowed to execute a job */ if (message->host->version==VERSION && !security_check(message->host)) { DEBUG(LOG_INFO, "tcpsocket: failed security check"); DEBUG(LOG_DEBUG, "tcpsocket: ismember_userlist = %d", ismember_userlist(message->host->user)); DEBUG(LOG_DEBUG, "tcpsocket: ismember_grouplist = %d", ismember_grouplist(message->host->group)); DEBUG(LOG_DEBUG, "tcpsocket: ismember_hostlist = %d", ismember_hostlist(message->host->name)); connect_accept = 0; } /* give a handshake */ handshake = connect_accept || connect_continue; if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) { DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int)); goto cleanup; } if (!connect_continue) { DEBUG(LOG_INFO, "tcpsocket: dropping connection"); goto cleanup; } /* read the job details */ if ((n = bufread(fd, message->job, sizeof(jobdef_t))) != sizeof(jobdef_t)) { DEBUG(LOG_ERR, "tcpsocket: packet size = %d, should be %d", n, sizeof(jobdef_t)); goto cleanup; } /* test whether the request can be accepted based on the job characteristics */ if (message->job->version!=VERSION) { DEBUG(LOG_ERR, "tcpsocket: incorrect job version (%u, %u)", message->job->version, VERSION); connect_accept = 0; connect_continue = 0; /* prevent another read request */ } pthread_mutex_lock(&mutexhost); if (message->job->memreq > host->memavail) { DEBUG(LOG_INFO, "tcpsocket: memory request too large"); connect_accept = 0; } if (message->job->cpureq > host->cpuavail) { DEBUG(LOG_INFO, "tcpsocket: cpu request too large"); connect_accept = 0; } if (message->job->timreq > host->timavail) { DEBUG(LOG_INFO, "tcpsocket: time request too large"); connect_accept = 0; } pthread_mutex_unlock(&mutexhost); if (message->job->argsize>MAXARGSIZE) { DEBUG(LOG_ERR, "tcpsocket: argsize too large"); connect_accept = 0; } if (message->job->optsize>MAXARGSIZE) { DEBUG(LOG_ERR, "tcpsocket: optsize too large"); connect_accept = 0; } /* remember the job characteristics for the smartshare algorithm */ smartshare_history(message->job); /* use a probabilistic approach to determine whether the connection should be dropped */ if (!smartshare_check(message->job->timreq, message->host->id)) { DEBUG(LOG_INFO, "tcpsocket: failed smartshare_check"); connect_accept = 0; } /* don't continue reading the content of the job, drop the connection before the job arguments are sent */ if (!connect_accept) connect_continue = 0; /* prevent another read request */ /* give a handshake */ handshake = connect_accept || connect_continue; if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) { DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int)); goto cleanup; } if (!connect_continue) { DEBUG(LOG_INFO, "tcpsocket: dropping connection"); goto cleanup; } /* read the job request arguments */ if (message->job->argsize>0) { message->arg = malloc(message->job->argsize); if ((n = bufread(fd, message->arg, message->job->argsize)) != message->job->argsize) { DEBUG(LOG_ERR, "tcpsocket: read size = %d, should be %d", n, message->job->argsize); goto cleanup; } } /* give a handshake */ handshake = connect_accept || connect_continue; if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) { DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int)); goto cleanup; } if (!connect_continue) { DEBUG(LOG_INFO, "tcpsocket: dropping connection"); goto cleanup; } /* read the job request options */ if (message->job->optsize>0) { message->opt = malloc(message->job->optsize); if ((n = bufread(fd, message->opt, message->job->optsize)) != message->job->optsize) { DEBUG(LOG_ERR, "tcpsocket: read size = %d, should be %d", n, message->job->optsize); goto cleanup; } } /* give a handshake */ handshake = connect_accept || connect_continue; if ((n = bufwrite(fd, &handshake, sizeof(int))) != sizeof(int)) { DEBUG(LOG_ERR, "tcpsocket: could not write handshake, n = %d, should be %d", n, sizeof(int)); goto cleanup; } if (!connect_continue) { DEBUG(LOG_INFO, "tcpsocket: dropping connection"); goto cleanup; } /* create a new list item */ job = (joblist_t *)malloc(sizeof(joblist_t)); job->job = message->job; job->host = message->host; job->arg = message->arg; job->opt = message->opt; pthread_mutex_lock(&mutexjoblist); /* add the item to the beginning of the list */ job->next = joblist; joblist = job; DEBUG(LOG_DEBUG, "tcpsocket: job.version = %u", job->job->version); DEBUG(LOG_DEBUG, "tcpsocket: job.id = %u", job->job->id); DEBUG(LOG_DEBUG, "tcpsocket: job.argsize = %u", job->job->argsize); DEBUG(LOG_DEBUG, "tcpsocket: job.optsize = %u", job->job->optsize); DEBUG(LOG_DEBUG, "tcpsocket: host.name = %s", job->host->name); DEBUG(LOG_DEBUG, "tcpsocket: host.port = %u", job->host->port); DEBUG(LOG_DEBUG, "tcpsocket: host.id = %u", job->host->id); pthread_mutex_unlock(&mutexjoblist); cleanup: /* from now on it is again allowed to use smartcpu_update */ pthread_mutex_lock(&mutexsmartcpu); smartcpu.freeze = 0; pthread_mutex_unlock(&mutexsmartcpu); /* from now on it is again allowed to use smartcpu_update */ pthread_mutex_lock(&mutexsmartmem); smartmem.freeze = 0; pthread_mutex_unlock(&mutexsmartmem); printf(""); /* otherwise the pthread_cleanup_pop won't compile */ pthread_cleanup_pop(1); return NULL; }
int main(int argc, char ** argv) { if (security_init() != 0) { log(CRITICAL, "Security initialisation Error. Exiting."); return EXIT_SECURITY_ERROR; } if (security_check() != SECURITY_OKAY) { log(CRITICAL, "Security check error. Exiting."); return EXIT_SECURITY_ERROR; } interactive_signals(); int config_status = loadConfig(argc, argv, USAGE_SERVER); if (config_status < 0) { if (config_status == CONFIG_VERSION) { std::cout << argv[0] << " (cyphesis) " << consts::version << " (Cyphesis build " << consts::buildId << ")" << std::endl << std::flush; return 0; } else if (config_status == CONFIG_HELP) { showUsage(argv[0], USAGE_SERVER); return 0; } else if (config_status != CONFIG_ERROR) { log(ERROR, "Unknown error reading configuration."); } // Fatal error loading config file. return EXIT_CONFIG_ERROR; } if (daemon_flag) { int pid = daemonise(); if (pid == -1) { return EXIT_FORK_ERROR; } else if (pid > 0) { return EXIT_SUCCESS; } } readConfigItem(instance, "usedatabase", database_flag); // If we are a daemon logging to syslog, we need to set it up. initLogger(); // Initialise the persistance subsystem. If we have been built with // database support, this will open the various databases used to // store server data. if (database_flag) { Persistence * p = Persistence::instance(); int dbstatus = p->init(); if (dbstatus < 0) { database_flag = false; log(ERROR, "Error opening database. Database disabled."); if (dbstatus == DATABASE_TABERR) { log(INFO, "Database connection established, " "but unable to create required tables."); log(INFO, "Please ensure that any obsolete database " "tables have been removed."); } else { log(INFO, "Unable to connect to the RDBMS."); log(INFO, "Please ensure that the RDBMS is running, " "the cyphesis database exists and is accessible " "to the user running cyphesis."); } log(INFO, String::compose("To disable this message please run:\n\n" " cyconfig --%1:usedatabase=false\n\n" "to permanently disable database usage.", instance)); } } // If the restricted flag is set in the config file, then we // don't allow connecting users to create accounts. Accounts must // be created manually by the server administrator. if (restricted_flag) { log(INFO, "Setting restricted mode."); } readConfigItem(instance, "inittime", timeoffset); std::string server_name; if (readConfigItem(instance, "servername", server_name) != 0) { if (instance == CYPHESIS) { server_name = get_hostname(); } else { server_name = instance; } } int nice = 1; readConfigItem(instance, "nice", nice); // Start up the python subsystem. init_python_api(); { // scope for CommServer // Create commserver instance that will handle connections from clients. // The commserver will create the other server related objects, and the // world object pair (World + WorldRouter), and initialise the admin // account. The primary ruleset name is passed in so it // can be stored and queried by clients. Inheritance::instance(); WorldRouter world; Ruleset::init(); TeleportAuthenticator::init(); StorageManager store(world); // This ID is currently generated every time, but should perhaps be // persistent in future. std::string server_id, lobby_id; long int_id, lobby_int_id; if (((int_id = newId(server_id)) < 0) || ((lobby_int_id = newId(lobby_id)) < 0)) { log(CRITICAL, "Unable to get server IDs from Database"); return EXIT_DATABASE_ERROR; } ServerRouting server(world, ruleset, server_name, server_id, int_id, lobby_id, lobby_int_id); CommServer commServer(server); if (commServer.setup() != 0) { log(CRITICAL, "Internal error setting up server infrastructure"); return EXIT_SOCKET_ERROR; } // This is where we should restore the database, before // the listen sockets are open. Unlike earlier code, we are // attempting to construct the internal state from the database, // not creating a new world using the contents of the database as a // template if (database_flag) { // log(INFO, _("Restoring world from database...")); store.restoreWorld(); // FIXME Do the following steps. // Read the world entity if any from the database, or set it up. // If it was there, make sure it did not get any of the wrong // position or orientation data. store.initWorld(); // log(INFO, _("Restored world.")); CommPSQLSocket * dbsocket = new CommPSQLSocket(commServer, Persistence::instance()->m_connection); commServer.addSocket(dbsocket); commServer.addIdle(dbsocket); IdleConnector * storage_idle = new IdleConnector(commServer); storage_idle->idling.connect(sigc::mem_fun(&store, &StorageManager::tick)); commServer.addIdle(storage_idle); } else { std::string adminId; long intId = newId(adminId); assert(intId >= 0); Admin * admin = new Admin(0, "admin", "BAD_HASH", adminId, intId); server.addAccount(admin); } // Add the test object, and call it regularly so it can do what it does. // UpdateTester * update_tester = new UpdateTester(commServer); // commServer.addIdle(update_tester); CommTCPListener * listener = new CommTCPListener(commServer, *new CommClientFactory<Connection>()); if (client_port_num < 0) { client_port_num = dynamic_port_start; for (; client_port_num <= dynamic_port_end; client_port_num++) { if (listener->setup(client_port_num) == 0) { break; } } if (client_port_num > dynamic_port_end) { log(ERROR, String::compose("Could not find free client listen " "socket in range %1-%2. Init failed.", dynamic_port_start, dynamic_port_end)); log(INFO, String::compose("To allocate 8 more ports please run:" "\n\n cyconfig " "--cyphesis:dynamic_port_end=%1\n\n", dynamic_port_end + 8)); return EXIT_PORT_ERROR; } log(INFO, String::compose("Auto configuring new instance \"%1\" " "to use port %2.", instance, client_port_num)); global_conf->setItem(instance, "tcpport", client_port_num, varconf::USER); global_conf->setItem(CYPHESIS, "dynamic_port_start", client_port_num + 1, varconf::USER); } else { if (listener->setup(client_port_num) != 0) { log(ERROR, String::compose("Could not create client listen socket " "on port %1. Init failed.", client_port_num)); return EXIT_SOCKET_ERROR; } } commServer.addSocket(listener); #ifdef HAVE_SYS_UN_H CommUnixListener * localListener = new CommUnixListener(commServer, *new CommClientFactory<TrustedConnection>()); if (localListener->setup(client_socket_name) != 0) { log(ERROR, String::compose("Could not create local listen socket " "with address \"%1\"", localListener->getPath())); delete localListener; } else { commServer.addSocket(localListener); } CommUnixListener * pythonListener = new CommUnixListener(commServer, *new CommPythonClientFactory()); if (pythonListener->setup(python_socket_name) != 0) { log(ERROR, String::compose("Could not create python listen socket " "with address %1.", pythonListener->getPath())); delete pythonListener; } else { commServer.addSocket(pythonListener); } #endif CommTCPListener * httpListener = new CommTCPListener(commServer, *new CommHttpClientFactory()); if (httpListener->setup(http_port_num) != 0) { log(ERROR, String::compose("Could not create http listen socket on " "port %1.", http_port_num)); delete httpListener; } else { commServer.addSocket(httpListener); } if (useMetaserver) { CommMetaClient * cmc = new CommMetaClient(commServer); if (cmc->setup(mserver) == 0) { commServer.addIdle(cmc); } else { log(ERROR, "Error creating metaserver comm channel."); delete cmc; } } #if defined(HAVE_LIBHOWL) || defined(HAVE_AVAHI) CommMDNSPublisher * cmdns = new CommMDNSPublisher(commServer); if (cmdns->setup() == 0) { commServer.addSocket(cmdns); commServer.addIdle(cmdns); } else { log(ERROR, "Unable to register service with MDNS daemon."); delete cmdns; } #endif // defined(HAVE_LIBHOWL) || defined(HAVE_AVAHI) // Configuration is now complete, and verified as somewhat sane, so // we save the updated user config. updateUserConfiguration(); log(INFO, "Running"); logEvent(START, "- - - Standalone server startup"); // Inform things that want to know that we are running. running(); // Reduce our system priority to make it easier to debug a runaway // server. if (nice != 0) { reduce_priority(nice); } // Loop until the exit flag is set. The exit flag can be set anywhere in // the code easily. while (!exit_flag) { try { commServer.poll(); } catch (...) { // It is hoped that commonly thrown exception, particularly // exceptions that can be caused by external influences // should be caught close to where they are thrown. If // an exception makes it here then it should be debugged. log(ERROR, "Exception caught in main()"); } } // exit flag has been set so we close down the databases, and indicate // to the metaserver (if we are using one) that this server is going down. // It is assumed that any preparation for the shutdown that is required // by the game has been done before exit flag was set. log(NOTICE, "Performing clean shutdown..."); } // close scope of CommServer, WorldRouter, and ServerRouting, which // cause the destruction of the server and world objects, and the entire // world contents Persistence::instance()->shutdown(); EntityBuilder::instance()->flushFactories(); EntityBuilder::del(); ArithmeticBuilder::del(); MindFactory::del(); TeleportAuthenticator::del(); Inheritance::clear(); // Shutdown the python interpretter. This frees lots of memory, and if // the malloc heap is in any way corrupt, a segfault is likely to // occur at this point. Previous occassions where pointers have been // deleted twice elsewhere in the code, have resulted in a segfault // at this point. AlRiddoch 10th November 2001 shutdown_python_api(); delete global_conf; log(INFO, "Clean shutdown complete."); logEvent(STOP, "- - - Standalone server shutdown"); return 0; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; #ifdef CONFIG_SECURE_BOOT #ifndef CONFIG_SECURE_BL1_ONLY security_check(); #endif #endif char cmdbuffer[64]; sprintf(cmdbuffer,"sdfuse autocheck"); run_command(cmdbuffer, 0); exynos4412_screen_backlight(0); #ifdef CONFIG_ZIMAGE_BOOT #define LINUX_ZIMAGE_MAGIC 0x016f2818 image_header_t *hdr; ulong addr; /* find out kernel image address */ if (argc < 2) { addr = load_addr; debug ("* kernel: default image load address = 0x%08lx\n", load_addr); } else { addr = simple_strtoul(argv[1], NULL, 16); } if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) { u32 val; printf("Boot with zImage\n"); //addr = virt_to_phys(addr); hdr = (image_header_t *)addr; hdr->ih_os = IH_OS_LINUX; hdr->ih_ep = ntohl(addr); memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images.legacy_hdr_os = hdr; images.legacy_hdr_valid = 1; goto after_header_check; } #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #if defined(CONFIG_ZIMAGE_BOOT) after_header_check: images.os.os = hdr->ih_os; images.ep = image_get_ep (&images.legacy_hdr_os_copy); #endif #ifdef CONFIG_SILENT_CONSOLE if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } arch_preboot_os(); boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret; boot_os_fn *boot_fn; #ifdef CONFIG_SECURE_BOOT #ifndef CONFIG_SPL_BUILD security_check(); #endif #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } if (bootm_start(cmdtp, flag, argc, argv)) return 1; /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif ret = bootm_load_os(images.os, &load_end, 1); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset(cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { image_header_t *hdr; hdr = &images.legacy_hdr_os_copy; if (image_get_type(hdr) == IH_TYPE_MULTI) puts("WARNING: legacy format multi " "component image " "overwritten\n"); } else { puts("ERROR: new format image overwritten - " "must RESET the board to recover\n"); bootstage_error(BOOTSTAGE_ID_OVERWRITTEN); do_reset(cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL); return 1; } } lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS); #ifdef CONFIG_SILENT_CONSOLE if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS); return 1; } arch_preboot_os(); boot_fn(0, argc, argv, &images); bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED); #ifdef DEBUG puts("\n## Control returned to monitor - resetting...\n"); #endif do_reset(cmdtp, flag, argc, argv); return 1; }
int write_storage_proc(void *arg) { u8* data = 0; u32 data_len = 0; u8 msg[128]; u64 image_offset = 0; dprintf(DBG_DCACHE, " --[%d] Enter write_storage_proc \n", TIME_STAMP); for (;;) { dprintf(DBG_DCACHE, " --[%d]Wait ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); event_wait(&(ctx.dual_cache[ctx.flipIdxR].content_available)); dprintf(DBG_DCACHE, " --[%d]Obtain ID:%d cache to read, \n", TIME_STAMP, ctx.flipIdxR); if(ctx.b_error) { sprintf(msg, "\nError USB?\n"); goto error; } //if has something to write if(ctx.dual_cache[ctx.flipIdxR].content_length !=0 || ctx.dual_cache[ctx.flipIdxR].padding_length !=0) { data = (u8*)(ctx.dual_cache[ctx.flipIdxR].cache_buf); data_len = ctx.dual_cache[ctx.flipIdxR].content_length; if(security_enabled(&ctx)) { if(!security_check(&data, &data_len, image_offset)) { //security error. sprintf(msg, "\nSecurity deny.\n"); goto error; } image_offset += data_len; } data -= ctx.dual_cache[ctx.flipIdxR].padding_length; data_len += ctx.dual_cache[ctx.flipIdxR].padding_length; //if data_len==0, secure img tail met. if(!security_enabled(&ctx) || ctx.security_step == S_CHECK_AND_DOWNLOAD) { dprintf(DBG_DCACHE, " --[%d]Write ID:%d to EMMC \n", TIME_STAMP, ctx.flipIdxR); if(!write_data(data, data_len)) { //error sprintf(msg, "\nWrite data error. \n"); goto error; } } } //last package, should return; if (ctx.dual_cache[ctx.flipIdxR].content_length == 0) { dprintf(DBG_DCACHE, " --[%d]Write EMMC Fin\n", TIME_STAMP); if(security_enabled(&ctx)) { security_check(&data, 0, image_offset); //notify security check that is the end. } if(ctx.boot_info.is_boot_image) { //boot image need download_size to flash. download_size = sto_info.to_write_data_len; //cache using is over, so copy boot image to download_base memcpy(download_base, ctx.boot_info.boot_image_address, download_size); } event_signal(&ctx.dual_cache[0].cache_available, SIGNAL_RESCHEDULE);//prevent from dead lock. event_signal(&ctx.dual_cache[1].cache_available, SIGNAL_RESCHEDULE); event_signal(&ctx.thr_end_ev, SIGNAL_RESCHEDULE); return 0; } dprintf(DBG_DCACHE, " --[%d]Notify ID:%d cache writeable\n", TIME_STAMP, ctx.flipIdxR); event_signal(&ctx.dual_cache[ctx.flipIdxR].cache_available, SIGNAL_RESCHEDULE); //make this cache writeable again. ctx.flipIdxR = cache_shift(ctx.flipIdxR); //change next buffer. } return 0; error: dprintf(DBG_LV, msg); display_info(msg); abort_engine(&ctx); return (-1); }