Esempio n. 1
0
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); 
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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
    }
}
Esempio n. 8
0
/* 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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
}
Esempio n. 11
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_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;
}
Esempio n. 12
0
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);
}