int sec_get_param(dhd_pub_t *dhd, int mode)
{
	struct file *fp = NULL;
	char *filepath = NULL;
	int val, ret = 0;

	if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
		(mode >= PARAM_LAST_VALUE)) {
		DHD_ERROR(("[WIFI] %s: invalid argument\n", __FUNCTION__));
		return -EINVAL;
	}

	switch (mode) {
		case SET_PARAM_BUS_TXGLOM_MODE:
			filepath = "/data/.bustxglom.info";
			break;
		case SET_PARAM_ROAMOFF:
			filepath = "/data/.roamoff.info";
			break;
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
			filepath = "/data/.frameburst.info";
			break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
			filepath = "/data/.txbf.info";
			break;
#endif /* USE_WL_TXBF */
		default:
			return -EINVAL;
	}

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		ret = -EIO;
	} else {
		ret = kernel_read(fp, fp->f_pos, (char *)&val, 4);
		filp_close(fp, NULL);
	}

	if (ret < 0) {
		/* File operation is failed so we will return default value */
		switch (mode) {
			case SET_PARAM_BUS_TXGLOM_MODE:
				val = CUSTOM_GLOM_SETTING;
				break;
			case SET_PARAM_ROAMOFF:
#ifdef ROAM_ENABLE
				val = 0;
#elif defined(DISABLE_BUILTIN_ROAM)
				val = 1;
#else
				val = 0;
#endif /* ROAM_ENABLE */
				break;
#ifdef USE_WL_FRAMEBURST
			case SET_PARAM_FRAMEBURST:
				val = 1;
				break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
			case SET_PARAM_TXBF:
				val = 1;
				break;
#endif /* USE_WL_TXBF */
		}

		DHD_INFO(("[WIFI] %s: File open failed, file path=%s,"
			" default value=%d\n",
			__FUNCTION__, filepath, val));
		return val;
	}

	val = bcm_atoi((char *)&val);
	DHD_INFO(("[WIFI] %s: %s = %d\n", __FUNCTION__, filepath, val));

	switch (mode) {
		case SET_PARAM_ROAMOFF:
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
#endif /* USE_WL_TXBF */
			val = val ? 1 : 0;
			break;
	}

	return val;
}
/*
 * load an fdpic binary into various bits of memory
 */
static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{
	struct elf_fdpic_params exec_params, interp_params;
	struct elf_phdr *phdr;
	unsigned long stack_size;
	struct file *interpreter = NULL; /* to shut gcc up */
	char *interpreter_name = NULL;
	int executable_stack;
	int retval, i;

	memset(&exec_params, 0, sizeof(exec_params));
	memset(&interp_params, 0, sizeof(interp_params));

	exec_params.hdr = *(struct elfhdr *) bprm->buf;
	exec_params.flags = ELF_FDPIC_FLAG_PRESENT | ELF_FDPIC_FLAG_EXECUTABLE;

	/* check that this is a binary we know how to deal with */
	retval = -ENOEXEC;
	if (!is_elf_fdpic(&exec_params.hdr, bprm->file))
		goto error;

	/* read the program header table */
	retval = elf_fdpic_fetch_phdrs(&exec_params, bprm->file);
	if (retval < 0)
		goto error;

	/* scan for a program header that specifies an interpreter */
	phdr = exec_params.phdrs;

	for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
		switch (phdr->p_type) {
		case PT_INTERP:
			retval = -ENOMEM;
			if (phdr->p_filesz > PATH_MAX)
				goto error;
			retval = -ENOENT;
			if (phdr->p_filesz < 2)
				goto error;

			/* read the name of the interpreter into memory */
			interpreter_name = (char *) kmalloc(phdr->p_filesz, GFP_KERNEL);
			if (!interpreter_name)
				goto error;

			retval = kernel_read(bprm->file,
					     phdr->p_offset,
					     interpreter_name,
					     phdr->p_filesz);
			if (retval < 0)
				goto error;

			retval = -ENOENT;
			if (interpreter_name[phdr->p_filesz - 1] != '\0')
				goto error;

			kdebug("Using ELF interpreter %s", interpreter_name);

			/* replace the program with the interpreter */
			interpreter = open_exec(interpreter_name);
			retval = PTR_ERR(interpreter);
			if (IS_ERR(interpreter)) {
				interpreter = NULL;
				goto error;
			}

			retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE);
			if (retval < 0)
				goto error;

			interp_params.hdr = *((struct elfhdr *) bprm->buf);
			break;

		case PT_LOAD:
#ifdef CONFIG_MMU
			if (exec_params.load_addr == 0)
				exec_params.load_addr = phdr->p_vaddr;
#endif
			break;
		}

	}

	if (elf_check_const_displacement(&exec_params.hdr))
		exec_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;

	/* perform insanity checks on the interpreter */
	if (interpreter_name) {
		retval = -ELIBBAD;
		if (!is_elf_fdpic(&interp_params.hdr, interpreter))
			goto error;

		interp_params.flags = ELF_FDPIC_FLAG_PRESENT;

		/* read the interpreter's program header table */
		retval = elf_fdpic_fetch_phdrs(&interp_params, interpreter);
		if (retval < 0)
			goto error;
	}

	stack_size = exec_params.stack_size;
	if (stack_size < interp_params.stack_size)
		stack_size = interp_params.stack_size;

	if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
		executable_stack = EXSTACK_ENABLE_X;
	else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
		executable_stack = EXSTACK_DISABLE_X;
	else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK)
		executable_stack = EXSTACK_ENABLE_X;
	else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK)
		executable_stack = EXSTACK_DISABLE_X;
	else
		executable_stack = EXSTACK_DEFAULT;

	retval = -ENOEXEC;
	if (stack_size == 0)
		goto error;

	if (elf_check_const_displacement(&interp_params.hdr))
		interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;

	/* flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto error;

	/* there's now no turning back... the old userspace image is dead,
	 * defunct, deceased, etc. after this point we have to exit via
	 * error_kill */
	set_personality(PER_LINUX_FDPIC);
	set_binfmt(&elf_fdpic_format);

	current->mm->start_code = 0;
	current->mm->end_code = 0;
	current->mm->start_stack = 0;
	current->mm->start_data = 0;
	current->mm->end_data = 0;
	current->mm->context.exec_fdpic_loadmap = 0;
	current->mm->context.interp_fdpic_loadmap = 0;

	current->flags &= ~PF_FORKNOEXEC;

#ifdef CONFIG_MMU
	elf_fdpic_arch_lay_out_mm(&exec_params,
				  &interp_params,
				  &current->mm->start_stack,
				  &current->mm->start_brk);
#endif

	/* do this so that we can load the interpreter, if need be
	 * - we will change some of these later
	 */
	set_mm_counter(current->mm, rss, 0);

#ifdef CONFIG_MMU
	retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack);
	if (retval < 0) {
		send_sig(SIGKILL, current, 0);
		goto error_kill;
	}
#endif

	/* load the executable and interpreter into memory */
	retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, "executable");
	if (retval < 0)
		goto error_kill;

	if (interpreter_name) {
		retval = elf_fdpic_map_file(&interp_params, interpreter,
					    current->mm, "interpreter");
		if (retval < 0) {
			printk(KERN_ERR "Unable to load interpreter\n");
			goto error_kill;
		}

		allow_write_access(interpreter);
		fput(interpreter);
		interpreter = NULL;
	}

#ifdef CONFIG_MMU
	if (!current->mm->start_brk)
		current->mm->start_brk = current->mm->end_data;

	current->mm->brk = current->mm->start_brk = PAGE_ALIGN(current->mm->start_brk);

#else
	/* create a stack and brk area big enough for everyone
	 * - the brk heap starts at the bottom and works up
	 * - the stack starts at the top and works down
	 */
	stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
	if (stack_size < PAGE_SIZE * 2)
		stack_size = PAGE_SIZE * 2;

	down_write(&current->mm->mmap_sem);
	current->mm->start_brk = do_mmap(NULL,
					 0,
					 stack_size,
					 PROT_READ | PROT_WRITE | PROT_EXEC,
					 MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
					 0);

	if (IS_ERR((void *) current->mm->start_brk)) {
		up_write(&current->mm->mmap_sem);
		retval = current->mm->start_brk;
		current->mm->start_brk = 0;
		goto error_kill;
	}

	if (do_mremap(current->mm->start_brk,
		      stack_size,
		      ksize((char *) current->mm->start_brk),
		      0, 0
		      ) == current->mm->start_brk
	    )
		stack_size = ksize((char *) current->mm->start_brk);
	up_write(&current->mm->mmap_sem);

	current->mm->brk = current->mm->start_brk;
	current->mm->context.end_brk = current->mm->start_brk;
	current->mm->context.end_brk += (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
	current->mm->start_stack = current->mm->start_brk + stack_size;
#endif

	compute_creds(bprm);
	current->flags &= ~PF_FORKNOEXEC;
	if (create_elf_fdpic_tables(bprm, current->mm, &exec_params, &interp_params) < 0)
		goto error_kill;

	kdebug("- start_code  %lx",	(long) current->mm->start_code);
	kdebug("- end_code    %lx",	(long) current->mm->end_code);
	kdebug("- start_data  %lx",	(long) current->mm->start_data);
	kdebug("- end_data    %lx",	(long) current->mm->end_data);
	kdebug("- start_brk   %lx",	(long) current->mm->start_brk);
	kdebug("- brk         %lx",	(long) current->mm->brk);
	kdebug("- start_stack %lx",	(long) current->mm->start_stack);

#ifdef ELF_FDPIC_PLAT_INIT
	/*
	 * The ABI may specify that certain registers be set up in special
	 * ways (on i386 %edx is the address of a DT_FINI function, for
	 * example.  This macro performs whatever initialization to
	 * the regs structure is required.
	 */
	ELF_FDPIC_PLAT_INIT(regs,
			    exec_params.map_addr,
			    interp_params.map_addr,
			    interp_params.dynamic_addr ?: exec_params.dynamic_addr
			    );
#endif

	/* everything is now ready... get the userspace context ready to roll */
	start_thread(regs,
		     interp_params.entry_addr ?: exec_params.entry_addr,
		     current->mm->start_stack);

	if (unlikely(current->ptrace & PT_PTRACED)) {
		if (current->ptrace & PT_TRACE_EXEC)
			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
		else
			send_sig(SIGTRAP, current, 0);
	}

	retval = 0;

error:
	if (interpreter) {
		allow_write_access(interpreter);
		fput(interpreter);
	}
	if (interpreter_name)
		kfree(interpreter_name);
	if (exec_params.phdrs)
		kfree(exec_params.phdrs);
	if (exec_params.loadmap)
		kfree(exec_params.loadmap);
	if (interp_params.phdrs)
		kfree(interp_params.phdrs);
	if (interp_params.loadmap)
		kfree(interp_params.loadmap);
	return retval;

	/* unrecoverable error - kill the process */
 error_kill:
	send_sig(SIGSEGV, current, 0);
	goto error;

} /* end load_elf_fdpic_binary() */
Esempio n. 3
0
int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
	struct file *fp      = NULL;
	char macbuffer[18]   = {0};
	mm_segment_t oldfs   = {0};
	char randommac[3]    = {0};
	char buf[18]         = {0};
	char *filepath_efs       = MACINFO_EFS;
	char buf_temp[18] = {0};
#ifdef CONFIG_TARGET_LOCALE_VZW
	char *nvfilepath       = "/data/misc/wifi/.nvmac.info";
#else
	char *nvfilepath       = NVMACINFO;
#endif
	int ret = 0;

	fp = filp_open(filepath_efs, O_RDONLY, 0);
		if (IS_ERR(fp)) {
start_readmac:
			/* File Doesn't Exist. Create and write mac addr.*/
		fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
			if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
				return -1;
			}
			oldfs = get_fs();
			set_fs(get_ds());

		/* Generating the Random Bytes for 3 last octects of the MAC address */
			get_random_bytes(randommac, 3);

			sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
					0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
		DHD_ERROR(("[WIFI]The Random Generated MAC ID: %s\n", macbuffer));

			if (fp->f_mode & FMODE_WRITE) {
			ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos);
			if (ret < 0)
			DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath_efs));
			else
			DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath_efs));
			}
			set_fs(oldfs);
		/* Reading the MAC Address from .mac.info file( the existed file or just created file)*/
		ret = kernel_read(fp, 0, buf, 18);
	} else {
		/* Reading the MAC Address from .mac.info file( the existed file or just created file)*/
		ret = kernel_read(fp, 0, buf, 18);
/* to prevent abnormal string display when mac address is displayed on the screen. */
		buf[17] = '\0';
		/*DHD_ERROR(("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17)));
		 */
		if (strncmp(buf , "00:00:00:00:00:00" , 17) < 1) {
			DHD_ERROR(("goto start_readmac \r\n"));
			filp_close(fp, NULL);
			goto start_readmac;
		}
	}

	if (ret) {
		if (!strncmp(buf, "12:34:56", 8)) {
			strncpy(buf_temp, buf+9, 8);
			snprintf(buf, 18, "00:12:34:%s", buf_temp);
			DHD_ERROR(("Wrong prefix is detected, 12:34:56 is"
				" changed as 00:12:34 : %d\n", sizeof(buf)));
		}
		sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
			   (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
			   (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
			   (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
	} else
		DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs));

	if (fp)
		filp_close(fp, NULL);

	/* Writing Newly generated MAC ID to the Dongle */
	if (0 == _dhd_set_mac_address(dhd, 0, mac))
		DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
	else
		DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));

	return 0;
}
Esempio n. 4
0
static int load_macho_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{ 
	unsigned long def_flags = 0;
	void* entry_point = 0;
	int retval = -ENOEXEC;
	int file_size = 0;
	int executable_stack = EXSTACK_DEFAULT;
	size_t macho_header_sz = sizeof(macho_header);
	macho_header* head = ((macho_header*)bprm->buf);
	struct file *linker_file = NULL;
	
	/* have we got enough space? */
	if (!head) {
		retval = -ENOMEM;
		goto out_ret;
	}
	
	retval = ml_checkImage(bprm->file, head);
	if (retval) {
		printk(KERN_WARNING "load_macho_binary: image failed sanity checks, not loading \n");
		goto out_ret;
	}
	
	/*
		XXX: this should be retrieved by ml_checkImage()
	*/
	file_size = ml_getFileSize(bprm->file);
	
	/*
		The file seems to be alright, so set up an environment for the 
		new binary to run in. After this, the old image will no longer be 
		usable. If some of the load commands are broken, this process is doomed.
	*/
	retval = flush_old_exec(bprm);
	if (retval) {
		panic("load_macho_binary: flush_old_exec failed\n");
	}
	else {
		current->flags &= ~PF_FORKNOEXEC;
		current->mm->def_flags = def_flags;
		
		setup_new_exec(bprm);
		
		/* set personality */
		unsigned int personality = current->personality & ~PER_MASK;
		personality |= PER_LINUX;
		
		/*
		 	This flag has to be set for 32x architectures (I think).
		*/
		personality |= ADDR_LIMIT_32BIT;
		
		set_personality(personality);

		/* set stuff */
		current->mm->free_area_cache = current->mm->mmap_base;
		current->mm->cached_hole_size = 0;
		//retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), executable_stack);
					
		if (retval < 0) {
			//send_sig(SIGKILL, current, 0);
			//goto out_ret;
		}
		
		/* stack */
		current->mm->start_stack = bprm->p;
	}
	
	
	/*
		Read the load commands from the file.
	*/
	size_t offset;
	size_t oldoffset;
	uint32_t ncmds;
	uint8_t* addr;

	offset = 0;
	ncmds = head->ncmds;
	addr = kmalloc(head->sizeofcmds, GFP_KERNEL); /***/
	retval = -EINVAL;
	
	int ret = 0;
	
	/*
		Top of the image data. This is needed to position the heap.
	*/
	int top_data = 0;
	
	/*
		First text segment where the mach header is.
	*/
	void* first_text = 0;
	void* first_text_linker = 0;
	
	/* read in load commands */
	kernel_read(bprm->file, macho_header_sz, addr, head->sizeofcmds);
	
	while (ncmds--) {
		/* LC pointer */
		struct load_command	*lcp = 
		(struct load_command *)(addr + offset);
		
		oldoffset = offset;
		offset += lcp->cmdsize;
		
		if (oldoffset > offset ||
		    lcp->cmdsize < sizeof(struct load_command) ||
		    offset > head->sizeofcmds + macho_header_sz)
		{
			printk(KERN_WARNING "load_macho_binary: malformed binary - lc overflow \n");
			goto lc_ret;
		}
		
		/*  Parse load commands.
		 
			We only need a bare minimum to get the image up an running. Dyld will
			take care of all the other stuff.
		 */
		switch(lcp->cmd) {
			case LC_SEGMENT:
				ret = ml_loadSegment(bprm, file_size, (struct segment_command*)lcp, &top_data, &first_text, 0);
				if (ret != LOAD_SUCCESS) {
					printk(KERN_WARNING "load_macho_binary: segment loading failure \n");
					goto lc_ret;
				}
				break;
			case LC_LOAD_DYLINKER:
				ret = ml_loadDylinker(bprm, file_size, (struct dylinker_command*)lcp, &linker_file);
				if (ret != LOAD_SUCCESS) {
					printk(KERN_WARNING "load_macho_binary: dylinker loading failure \n");
					goto lc_ret;
				}
				else {
					/* done */
				}
				break;
			case LC_UNIXTHREAD:
				ret = ml_loadUnixThread(bprm, file_size, (struct arm_thread_command*)lcp, &entry_point);
				if (ret != LOAD_SUCCESS) {
					printk(KERN_WARNING "load_macho_binary: unix thread loading failure \n");
					goto lc_ret;
				}
				break;
			default: 
				if (_verboseLog)
					printk(KERN_WARNING "load_macho_binary: unsupported lc 0x%p \n", (void*)lcp->cmd);

				break;
		}
	}
	
	/*
		Bootstrap the dynamic linker if needed.
	*/
	if (linker_file) {
		int dylinker_load_addr = top_data;
		
		ml_bootstrapDylinker(linker_file,
							&top_data,
							&first_text_linker,
							&entry_point);
		
		/* slide the entry point */
		entry_point = entry_point + dylinker_load_addr;
			
		if (_verboseLog)				
			printk(KERN_WARNING "load_macho_binary: dylinker's first text segment @ %d, new pc @ %d \n",
					first_text_linker,
					(int)entry_point);
	}
	
	/*
		Now, I don't know what these are used for, but I'm fairly sure
		they're *very* important. So let's set them up. 
		
		See 'linux/mm_types.h':
		unsigned long start_code, end_code, start_data, end_data;
		unsigned long start_brk, brk, start_stack;
	*/	
	current->mm->start_code = 0; /* IMP */
	current->mm->end_code = top_data; /* IMP */
	current->mm->start_data = 0;
	current->mm->end_data = top_data;
		
	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: setting up heap ...\n");

	/* Set up an empty heap. This will be grown as more memory is allocated.  */
	int brkret = ml_setBrk(top_data, top_data);

	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: setting up misc ...\n");

	/* setup misc stuff */
	set_binfmt(&macho_format);
	install_exec_creds(bprm);

	/*
		Stack (grows down on ARM).
	*/
	uint32_t* stack = bprm->p;
	uint32_t* argv_array;
	uint32_t* argv;
	uint32_t* envp_array;
	uint32_t* envp;
	uint32_t total_argv_size;
	uint32_t total_env_size;

	/* Construct envp array. */
	envp = envp_array = stack = (uint32_t*)stack - ((bprm->envc+1));

	/* Construct argv array. */
	argv = argv_array = stack = (uint32_t*)stack - ((bprm->argc+1));

	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: setting up stack @ %p ...\n", (uint32_t*)stack);

	uint32_t argc = bprm->argc;
	uint32_t envc = bprm->envc;
	char* p = bprm->p;

	/* Set up argv pointers */
	current->mm->arg_start = (unsigned long)p;
	while(argc--) {
		char c;

		put_user(p,argv++);
		do {
			get_user(c,p++);
		} while (c);
	}
	put_user(NULL,argv);

	/* Set up envp pointers */
	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
	while(envc--) {
		char c;

		put_user(p,envp++);
		do {
			get_user(c,p++);
		} while (c);
	}
	put_user(NULL,envp);
	current->mm->env_end = (unsigned long) p;

	/*
		The actual stuff passed to the linker goes here.
	*/
	stack = (uint32_t*)stack - (4);

	stack[0] = (uint32_t)first_text; /* mach_header */
	stack[1] = bprm->argc; /* argc */
	stack[2] = argv_array; /* argv */
	stack[3] = (uint32_t)first_text_linker; /* linker's mach_header */
	
	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: setting up main thread ...\n");	
	
	/*
		Set up the main thread
	*/
	if (BAD_ADDR(entry_point)) {
		/* entry point is not executable */
		
		printk(KERN_WARNING "load_macho_binary: bad entry point \n");
		force_sig(SIGSEGV, current);
		retval = -EINVAL;
		goto lc_ret;
	}
	
	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: setting up registers ...\n");

	/* 
		See 'start_thread' in 'processor.h'
		'start_thread' provides an ELF implementation of this function.
		This is for the Darwin ABI implementation which is used by iPhoneOS binaries.
	*/
	unsigned long initial_pc = (unsigned long)entry_point;	
	
	/* exit supervisor and enter user */
	set_fs(USER_DS);
	memset(regs->uregs, 0, sizeof(regs->uregs));
	regs->ARM_cpsr = USR_MODE;	

	/* not sure */
	if (elf_hwcap & HWCAP_THUMB && initial_pc & 1)
		regs->ARM_cpsr |= PSR_T_BIT;
		
	/* set up control regs */	
	regs->ARM_cpsr |= PSR_ENDSTATE;	
	regs->ARM_pc = initial_pc & ~1;		/* pc */
	regs->ARM_sp = stack;		/* sp */

	/* This is actually ignored, but set it anyway */
	regs->ARM_r2 = stack[2];	/* r2 (envp) */	
	regs->ARM_r1 = stack[1];	/* r1 (argv) */
	regs->ARM_r0 = stack[0];	/* r0 (argc) */	
	
	/* this will work for mmu and nonmmu */
	nommu_start_thread(regs);
	
	wire_weird_pages();	
			
	/*
		Binary is now loaded. Return 0 to signify success.
	*/
	retval = 0;

	if (_verboseLog)
		printk(KERN_WARNING "load_macho_binary: complete, heap starts at %d, brkret %d \n", top_data, brkret);

	/*
	 	Teardown
	*/
	lc_ret:
		kfree(addr);
	out_ret:
		return retval;
}
Esempio n. 5
0
int
dhd_read_macaddr(dhd_info_t *dhd)
{
    struct file *fp      = NULL;
    struct file *fpnv      = NULL;
    char macbuffer[18]   = {0};
    mm_segment_t oldfs   = {0};
	char randommac[3]    = {0};
	char buf[18]         = {0};
	char* filepath       = "/data/.mac.info";
    char* nvfilepath       = "/data/.nvmac.info";
	int ret;

	//MAC address copied from nv
	fpnv = filp_open(nvfilepath, O_RDONLY, 0);
	if (IS_ERR(fpnv)) {
start_readmac:
		fpnv = NULL;
		fp = filp_open(filepath, O_RDONLY, 0);
		if (IS_ERR(fp)) {
			/* File Doesn't Exist. Create and write mac addr.*/
			fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
			if(IS_ERR(fp)) {
				DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
				return -1;
			}

			oldfs = get_fs();
			set_fs(get_ds());

		/* Generating the Random Bytes for 3 last octects of the MAC address */
		get_random_bytes(randommac, 3);
		
		sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
			0x60,0xd0,0xa9,randommac[0],randommac[1],randommac[2]);
			DHD_INFO(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer));
			printk("[WIFI] The Random Generated MAC ID : %s\n", macbuffer);

			if(fp->f_mode & FMODE_WRITE) {			
				ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos);
				if(ret < 0)
					DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", macbuffer, filepath));
				else
					DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", macbuffer, filepath));
			}
			set_fs(oldfs);
		}
		/* Reading the MAC Address from .mac.info file( the existed file or just created file)*/
		//rtn_value=kernel_read(fp, fp->f_pos, buf, 18);	
		ret = kernel_read(fp, 0, buf, 18);	
	}
	else {
		/* Reading the MAC Address from .nvmac.info file( the existed file or just created file)*/
		ret = kernel_read(fpnv, 0, buf, 18);
		buf[17] ='\0';   // to prevent abnormal string display when mac address is displayed on the screen. 
		printk("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17));
		if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
			filp_close(fpnv, NULL);
			goto start_readmac;
		}

		fp = filp_open(filepath, O_RDONLY, 0);
		if (IS_ERR(fp))   // If you want to write MAC address to /data/.mac.info once, 
		{
			fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
			if(IS_ERR(fp)) {
				DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
				return -1;
			}

			oldfs = get_fs();
			set_fs(get_ds());
			
			if(fp->f_mode & FMODE_WRITE) {
				ret = fp->f_op->write(fp, (const char *)buf, sizeof(buf), &fp->f_pos);
				if(ret < 0)
					DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", buf, filepath));
				else
					DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", buf, filepath));
			}       
			set_fs(oldfs);
		} 
		ret = kernel_read(fp, 0, buf, 18);	
	}

	if(ret)
		sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
			   &dhd->pub.mac.octet[0], &dhd->pub.mac.octet[1], &dhd->pub.mac.octet[2], 
			   &dhd->pub.mac.octet[3], &dhd->pub.mac.octet[4], &dhd->pub.mac.octet[5]);
	else
		DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath));

	if (fp)
		filp_close(fp, NULL);
	if (fpnv)
		filp_close(fpnv, NULL);    	

	/* Writing Newly generated MAC ID to the Dongle */
	if (0 == _dhd_set_mac_address(dhd, 0, &dhd->pub.mac))
		DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
	else
		DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));

    return 0;
}
Esempio n. 6
0
/*
 * 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(&current->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(&current->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);
}
Esempio n. 7
0
static int
load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	int som_exec_fileno;
	int retval;
	unsigned int size;
	unsigned long som_entry;
	struct som_hdr *som_ex;
	struct som_exec_auxhdr *hpuxhdr;

	/* Get the exec-header */
	som_ex = (struct som_hdr *) bprm->buf;

	retval = check_som_header(som_ex);
	if (retval != 0)
		goto out;

	/* Now read in the auxiliary header information */

	retval = -ENOMEM;
	size = som_ex->aux_header_size;
	if (size > SOM_PAGESIZE)
		goto out;
	hpuxhdr = (struct som_exec_auxhdr *) kmalloc(size, GFP_KERNEL);
	if (!hpuxhdr)
		goto out;

	retval = kernel_read(bprm->file, som_ex->aux_header_location,
			(char *) hpuxhdr, size);
	if (retval < 0)
		goto out_free;
#error "Fix security hole before enabling me"
	retval = get_unused_fd();
	if (retval < 0)
		goto out_free;
	get_file(bprm->file);
	fd_install(som_exec_fileno = retval, bprm->file);

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto out_free;

	/* OK, This is the point of no return */
	current->flags &= ~PF_FORKNOEXEC;
	current->personality = PER_HPUX;

	/* Set the task size for HP-UX processes such that
	 * the gateway page is outside the address space.
	 * This can be fixed later, but for now, this is much
	 * easier.
	 */

	current->thread.task_size = 0xc0000000;

	/* Set map base to allow enough room for hp-ux heap growth */

	current->thread.map_base = 0x80000000;

	retval = map_som_binary(bprm->file, hpuxhdr);
	if (retval < 0)
		goto out_free;

	som_entry = hpuxhdr->exec_entry;
	kfree(hpuxhdr);

	set_binfmt(&som_format);
	compute_creds(bprm);
	setup_arg_pages(bprm);

	create_som_tables(bprm);

	current->mm->start_stack = bprm->p;
	current->mm->rss = 0;

#if 0
	printk("(start_brk) %08lx\n" , (unsigned long) current->mm->start_brk);
	printk("(end_code) %08lx\n" , (unsigned long) current->mm->end_code);
	printk("(start_code) %08lx\n" , (unsigned long) current->mm->start_code);
	printk("(end_data) %08lx\n" , (unsigned long) current->mm->end_data);
	printk("(start_stack) %08lx\n" , (unsigned long) current->mm->start_stack);
	printk("(brk) %08lx\n" , (unsigned long) current->mm->brk);
#endif

	map_hpux_gateway_page(current,current->mm);

	start_thread_som(regs, som_entry, bprm->p);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;

	/* error cleanup */
out_free:
	kfree(hpuxhdr);
out:
	return retval;
}
int CheckRDWR_Macaddr(	struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac)
{
	struct file *fp_mac	= NULL;
	struct file *fp_nvm	= NULL;
	char macbuffer[18]		= {0};
	char randommac[3]		= {0};
	char buf[18]			= {0};
	char* filepath			= "/data/.mac.info";
	#ifdef CONFIG_TARGET_LOCALE_NA	
    char* nvfilepath       = "/data/misc/wifi/.nvmac.info";
	#else	
	char* nvfilepath		= "/data/.nvmac.info";
	#endif
	char cur_mac[128]		= {0};
	char dummy_mac[ETHER_ADDR_LEN]		= { 0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38 };
	char cur_macbuffer[18]	= {0};
	int ret = -1;

	g_iMacFlag = MACADDR_NONE;	

	fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
	if(IS_ERR(fp_nvm)) { // file is not exist
		//read MAC Address;
		//ReadMacAddress_OTP(dhd,cur_mac);
		//dhd_os_proto_block(dhdp);
		strcpy(cur_mac, "cur_etheraddr");
		//ret = dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, cur_mac, sizeof(cur_mac));
		ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac, sizeof(cur_mac), 0, 0);
		if (ret < 0) {
			DHD_ERROR(("Current READ MAC error \r\n"));
			memset(cur_mac , 0 , ETHER_ADDR_LEN);
			return -1;
		}
		else {
			DHD_ERROR(("MAC (OTP) : [%02X:%02X:%02X:%02X:%02X:%02X] \r\n" , 
			cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3], cur_mac[4], cur_mac[5]));
		}
		//dhd_os_proto_unblock(dhdp);
		
		sprintf(cur_macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
			cur_mac[0],cur_mac[1],cur_mac[2],cur_mac[3],cur_mac[4],cur_mac[5]);

		fp_mac = filp_open(filepath, O_RDONLY, 0);
		if(IS_ERR(fp_mac)) { // file is not exist
		
			if(memcmp(cur_mac,dummy_mac,ETHER_ADDR_LEN) == 0) { // read mac is 00:90:4C:C5:12:38
				g_iMacFlag = MACADDR_MOD_RANDOM;
			}
			else if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
				g_iMacFlag = MACADDR_MOD_RANDOM;
			}
			else {
				g_iMacFlag = MACADDR_MOD;
			}
		}
		else {
			int is_zeromac;

			ret = kernel_read(fp_mac, 0, buf, 18);
			filp_close(fp_mac, NULL);
			buf[17] ='\0';

			is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
			DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n" , buf, is_zeromac));

			if (is_zeromac == 0) {
				DHD_ERROR(("Zero MAC detected. Trying Random MAC.\n"));
				g_iMacFlag = MACADDR_MOD_RANDOM;
			} else {
				sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
				   &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]), 
				   &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
				if(memcmp(cur_mac,mac->octet,ETHER_ADDR_LEN) == 0) { // read mac is same
					g_iMacFlag = MACADDR_NONE;
				}
				else { // change mac..
					if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
						DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
						g_iMacFlag = MACADDR_MOD;
					}
					else {
						DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
						g_iMacFlag = MACADDR_NONE;
					}
				}
			}
		}
	}
	else {
		// COB type. only COB.
		/* Reading the MAC Address from .nvmac.info file( the existed file or just created file)*/
		ret = kernel_read(fp_nvm, 0, buf, 18);
		buf[17] ='\0';   // to prevent abnormal string display when mac address is displayed on the screen. 
		DHD_ERROR(("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17)));
		if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
			filp_close(fp_nvm, NULL);
			g_iMacFlag = MACADDR_COB_RANDOM;
		}
		else {
			sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
			   &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]), 
			   &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
			/* Writing Newly generated MAC ID to the Dongle */
			if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
				DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
				g_iMacFlag = MACADDR_COB;
			}
			else {
				DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
			}
		}
		filp_close(fp_nvm, NULL);
	}
	
	if((g_iMacFlag == MACADDR_COB_RANDOM) || (g_iMacFlag == MACADDR_MOD_RANDOM)) {
		get_random_bytes(randommac, 3);
		sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
				0x60,0xd0,0xa9,randommac[0],randommac[1],randommac[2]);		
		DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer));
		sscanf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X",
			   &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]), 
			   &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
		if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
			DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
			g_iMacFlag = MACADDR_COB;
		}
		else {
			DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
		}
	}

	
	return 0;
}
Esempio n. 9
0
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	unsigned char mac_buf[20] = {0};
	unsigned char otp_mac_buf[20] = {0};
	const char *macfilepath = MACINFO_EFS;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	struct file *fp_mac = NULL;

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_TRACE(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n", __func__,
			ret));
		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac->octet[0], mac->octet[1], mac->octet[2],
			mac->octet[3], mac->octet[4], mac->octet[5]);
		DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n",
			__FUNCTION__, MAC2STRDBG(mac->octet)));
	} else {
		bcm_tlv_t *elt = NULL;
		int remained_len = sizeof(cis_buf);
		int index = 0;
		uint8 *mac_addr = NULL;
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif

		/* Find a new tuple tag */
		while (index < remained_len) {
			if (cis_buf[index] == CIS_TUPLE_TAG_START) {
				remained_len -= index;
				if (remained_len >= sizeof(bcm_tlv_t)) {
					elt = (bcm_tlv_t *)&cis_buf[index];
				}
				break;
			} else {
				index++;
			}

		}

		/* Find a MAC address tuple */
		while (elt && remained_len >= TLV_HDR_LEN) {
			int body_len = (int)elt->len;

			if ((elt->id == CIS_TUPLE_TAG_START) &&
				(remained_len >= (body_len + TLV_HDR_LEN)) &&
				(*elt->data == CIS_TUPLE_TAG_MACADDR)) {
				/* found MAC Address tuple and
				 * get the MAC Address data
				 */
				mac_addr = (uint8 *)elt + CIS_TUPLE_TAG_MACADDR_OFF;
				break;
			}

			/* Go to next tuple if tuple value
			 * is not MAC address type
			 */
			elt = (bcm_tlv_t *)((uint8 *)elt + (body_len + TLV_HDR_LEN));
			remained_len -= (body_len + TLV_HDR_LEN);
		}

		if (mac_addr) {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac_addr[0], mac_addr[1], mac_addr[2],
				mac_addr[3], mac_addr[4], mac_addr[5]);
			DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n"));
		} else {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac->octet[0], mac->octet[1], mac->octet[2],
				mac->octet[3], mac->octet[4], mac->octet[5]);
			DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP,"
				" Check module mac by initial value: " MACDBG "\n",
				__FUNCTION__, MAC2STRDBG(mac->octet)));
		}
	}

	fp_mac = filp_open(macfilepath, O_RDONLY, 0);
	if (!IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n"));
		kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
		filp_close(fp_mac, NULL);

		if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
			DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n"));
			dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
		}
	}

	return ret;
}
Esempio n. 10
0
/* support routines */
static int coda_venus_readdir(struct file *coda_file, void *buf,
			      filldir_t filldir)
{
	int result = 0; /* # of entries returned */
	struct coda_file_info *cfi;
	struct coda_inode_info *cii;
	struct file *host_file;
	struct dentry *de;
	struct venus_dirent *vdir;
	unsigned long vdir_size =
	    (unsigned long)(&((struct venus_dirent *)0)->d_name);
	unsigned int type;
	struct qstr name;
	ino_t ino;
	int ret;

	cfi = CODA_FTOC(coda_file);
	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
	host_file = cfi->cfi_container;

	de = coda_file->f_path.dentry;
	cii = ITOC(de->d_inode);

	vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
	if (!vdir) return -ENOMEM;

	if (coda_file->f_pos == 0) {
		ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR);
		if (ret < 0)
			goto out;
		result++;
		coda_file->f_pos++;
	}
	if (coda_file->f_pos == 1) {
		ret = filldir(buf, "..", 2, 1, parent_ino(de), DT_DIR);
		if (ret < 0)
			goto out;
		result++;
		coda_file->f_pos++;
	}
	while (1) {
		/* read entries from the directory file */
		ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir,
				  sizeof(*vdir));
		if (ret < 0) {
			printk(KERN_ERR "coda readdir: read dir %s failed %d\n",
			       coda_f2s(&cii->c_fid), ret);
			break;
		}
		if (ret == 0) break; /* end of directory file reached */

		/* catch truncated reads */
		if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
			printk(KERN_ERR "coda readdir: short read on %s\n",
			       coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}
		/* validate whether the directory file actually makes sense */
		if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
			printk(KERN_ERR "coda readdir: invalid dir %s\n",
			       coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}

		name.len = vdir->d_namlen;
		name.name = vdir->d_name;

		/* Make sure we skip '.' and '..', we already got those */
		if (name.name[0] == '.' && (name.len == 1 ||
		    (vdir->d_name[1] == '.' && name.len == 2)))
			vdir->d_fileno = name.len = 0;

		/* skip null entries */
		if (vdir->d_fileno && name.len) {
			/* try to look up this entry in the dcache, that way
			 * userspace doesn't have to worry about breaking
			 * getcwd by having mismatched inode numbers for
			 * internal volume mountpoints. */
			ino = find_inode_number(de, &name);
			if (!ino) ino = vdir->d_fileno;

			type = CDT2DT(vdir->d_type);
			ret = filldir(buf, name.name, name.len,
				      coda_file->f_pos, ino, type);
			/* failure means no space for filling in this round */
			if (ret < 0) break;
			result++;
		}
		/* we'll always have progress because d_reclen is unsigned and
		 * we've already established it is non-zero. */
		coda_file->f_pos += vdir->d_reclen;
	}
out:
	kfree(vdir);
	return result ? result : ret;
}
Esempio n. 11
0
int
dhd_preinit_ioctls(dhd_pub_t *dhd)
{
	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
	uint up = 0;
	char buf[128], *ptr;
	uint power_mode = PM_FAST;
	uint32 dongle_align = DHD_SDALIGN;
	uint32 glom = 0;
	uint bcn_timeout = 3;
	int scan_assoc_time = 40;
	int scan_unassoc_time = 80;
	int roam_delta[2];
    	int roam_scan_period = 2;
#ifdef SCAN_5G_HOMECHANNEL_TIME
	int scan_home_time = 60;
#endif
#ifdef FCC_CERT
        uint spect = 0;
#endif
	struct file *fp      = NULL;
	char* filepath       = "/data/.psm.info";
	int qosinfo = 1; /* enable VO AC */

#ifdef SOFTAP
	if(!ap_fw_loaded) {
#endif /* SOFTAP */
		/* Set Country code */
		if (dhd->country_code[0] != 0) {
			if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY,
				dhd->country_code, sizeof(dhd->country_code)) < 0) {
				DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));
			}
		}	
#ifdef SOFTAP
	}
#endif /* SOFTAP */

	/* query for 'ver' to get version info from firmware */
	memset(buf, 0, sizeof(buf));
	ptr = buf;
	bcm_mkiovar("ver", 0, 0, buf, sizeof(buf));
	dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf));
	bcmstrtok(&ptr, "\n", 0);
	/* Print fw version info */
	DHD_ERROR(("Firmware version = %s\n", buf));
	/////////////////////////
	/* Set PowerSave mode */
	fp = filp_open(filepath, O_RDONLY, 0);
	if(IS_ERR(fp))// the file is not exist
	{
		/* Set PowerSave mode */
		dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));

		fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
		if(IS_ERR(fp)||(fp==NULL))
		{
			DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
		}
		else
		{
			char buffer[2]   = {1};
			if(fp->f_mode & FMODE_WRITE)
			{
				sprintf(buffer,"1\n");
				fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
			}
		}
	}
	else
	{
		char buffer[1]   = {0};
		kernel_read(fp, fp->f_pos, buffer, 1);
		if(strncmp(buffer, "1",1)==0)
		{
			/* Set PowerSave mode */
			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
		}
		else
		{
	/*Disable Power save features for CERTIFICATION*/
	power_mode = 0;
 
	/* Set PowerSave mode */
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
 
	/* Disable MPC */    
	bcm_mkiovar("mpc", (char *)&power_mode, 4, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
	
			fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
			if(IS_ERR(fp)||(fp==NULL))
			{
				DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
			}
			else
			{
				char buffer[2]   = {1};
				if(fp->f_mode & FMODE_WRITE)
				{
					sprintf(buffer,"1\n");
					fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
				}
			}
		}
	}

	if(fp)
		filp_close(fp, NULL);

#ifdef SOFTAP
	if(!ap_fw_loaded) {
#endif /* SOFTAP */
#ifdef FCC_CERT
		dhdcdc_set_ioctl(dhd, 0, WLC_DOWN, (char *)&up, sizeof(up));
		/* Disable TPC to get qualification of FCC */
		dhdcdc_set_ioctl(dhd, 0, WLC_SET_SPECT_MANAGMENT, (char *)&spect, sizeof(spect));
#endif /* FCC_CERT */
#ifdef SOFTAP
	}
#endif /* SOFTAP */

	/* Match Host and Dongle rx alignment */
	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	/* disable glom option per default */
	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	/* Setup timeout if Beacons are lost and roam is off to report link down */
	bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	/* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */
	bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	/* Enable UAPSD for voice packet AC=VO */
	bcm_mkiovar("wme_qosinfo", (char *)&qosinfo, 4, iovbuf, sizeof(iovbuf)); 
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	/* Force STA UP */
	if (dhd_radio_up)
		dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up));

	/* Setup event_msgs */
	bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time,
		sizeof(scan_assoc_time));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time,
		sizeof(scan_unassoc_time));

	/* roaming delta = 10 dBm */
    	roam_delta[0] = 10;
    	roam_delta[1] = WLC_BAND_AUTO;
    	dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_DELTA, (char *)roam_delta, sizeof(roam_delta));
   
    	/* roaming scan period = 2 seconds */
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_ROAM_SCAN_PERIOD, (char *)&roam_scan_period, sizeof(roam_scan_period));

#ifdef SCAN_5G_HOMECHANNEL_TIME
	DHD_INFO(("Scan Channel Home Time Set : 80 ms \r\n"));
	dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_HOME_TIME, (char *)&scan_home_time,
		sizeof(scan_home_time));
#endif	


#ifdef ARP_OFFLOAD_SUPPORT
	/* Set and enable ARP offload feature */
	if (dhd_arp_enable)
		dhd_arp_offload_set(dhd, dhd_arp_mode);
	dhd_arp_offload_enable(dhd, dhd_arp_enable);
#endif /* ARP_OFFLOAD_SUPPORT */

#ifdef PKT_FILTER_SUPPORT
	{
		int i;
		/* Set up pkt filter */
		if (dhd_pkt_filter_enable) {
			for (i = 0; i < dhd->pktfilter_count; i++) {
				dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
				dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
					0, dhd_master_mode);
			}
		}
	}
#endif /* PKT_FILTER_SUPPORT */

	return 0;
}
Esempio n. 12
0
static int verihmac_calc_hash(struct file* file,char* digest)
{
	struct hash_desc desc;
	struct scatterlist sg;

	int rc;
	char *rbuf;

	loff_t i_size, offset = 0;
	
	rbuf = kzalloc(PAGE_SIZE, GFP_KERNEL);
	if (!rbuf) {
	        printk(VERI_ERROR "no free memory\n");
		rc = -ENOMEM;
		return rc;
	}
	
	desc.tfm = crypto_alloc_hash(VERI_HMAC, 0,CRYPTO_ALG_ASYNC);
	
	if (IS_ERR(desc.tfm)) {
		printk(VERI_ERROR "failed to load %s transform: %ld\n",
			VERI_HMAC, PTR_ERR(desc.tfm));
		rc = PTR_ERR(desc.tfm);
		kfree(rbuf);
		return rc;
	}
	
	desc.flags = 0;
	
       if(crypto_hash_setkey(desc.tfm,password_str,password_len)!=0) { 
	  printk(VERI_ERROR "setting key error  \n");
	  kfree(rbuf);
	  crypto_free_hash(desc.tfm);
	  return -1;
	}
	
	rc=crypto_hash_init(&desc);   
	
	if(rc)
	{
	  printk(VERI_ERROR "hash_init failed \n");
	  crypto_free_hash(desc.tfm);
	  kfree(rbuf);
	  return rc;
	}
	
	i_size = i_size_read(file->f_dentry->d_inode);
	
	while (offset < i_size) {
		int rbuf_len;
		rbuf_len = kernel_read(file, offset, rbuf, PAGE_SIZE);
		
		if (rbuf_len < 0) {
			rc = rbuf_len;
			break;
		}
		
		if (rbuf_len == 0)
			break;
		
		offset += rbuf_len;
		
		sg_set_buf(&sg, rbuf, rbuf_len);
		rc = crypto_hash_update(&desc, &sg, rbuf_len);
		
		if (rc)
			break;
	}

	kfree(rbuf);
	if (!rc)
		rc = crypto_hash_final(&desc, digest);
	
	crypto_free_hash(desc.tfm);
	return rc;
}
Esempio n. 13
0
static int coda_venus_readdir(struct file *coda_file, void *buf,
			      filldir_t filldir)
{
	int result = 0; 
	struct coda_file_info *cfi;
	struct coda_inode_info *cii;
	struct file *host_file;
	struct dentry *de;
	struct venus_dirent *vdir;
	unsigned long vdir_size = offsetof(struct venus_dirent, d_name);
	unsigned int type;
	struct qstr name;
	ino_t ino;
	int ret;

	cfi = CODA_FTOC(coda_file);
	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
	host_file = cfi->cfi_container;

	de = coda_file->f_path.dentry;
	cii = ITOC(de->d_inode);

	vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
	if (!vdir) return -ENOMEM;

	if (coda_file->f_pos == 0) {
		ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR);
		if (ret < 0)
			goto out;
		result++;
		coda_file->f_pos++;
	}
	if (coda_file->f_pos == 1) {
		ret = filldir(buf, "..", 2, 1, parent_ino(de), DT_DIR);
		if (ret < 0)
			goto out;
		result++;
		coda_file->f_pos++;
	}
	while (1) {
		
		ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir,
				  sizeof(*vdir));
		if (ret < 0) {
			printk(KERN_ERR "coda readdir: read dir %s failed %d\n",
			       coda_f2s(&cii->c_fid), ret);
			break;
		}
		if (ret == 0) break; 

		
		if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
			printk(KERN_ERR "coda readdir: short read on %s\n",
			       coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}
		
		if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
			printk(KERN_ERR "coda readdir: invalid dir %s\n",
			       coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}

		name.len = vdir->d_namlen;
		name.name = vdir->d_name;

		
		if (name.name[0] == '.' && (name.len == 1 ||
		    (vdir->d_name[1] == '.' && name.len == 2)))
			vdir->d_fileno = name.len = 0;

		
		if (vdir->d_fileno && name.len) {
			ino = find_inode_number(de, &name);
			if (!ino) ino = vdir->d_fileno;

			type = CDT2DT(vdir->d_type);
			ret = filldir(buf, name.name, name.len,
				      coda_file->f_pos, ino, type);
			
			if (ret < 0) break;
			result++;
		}
		coda_file->f_pos += vdir->d_reclen;
	}
out:
	kfree(vdir);
	return result ? result : ret;
}
Esempio n. 14
0
File: dir.c Progetto: MaxChina/linux
/* support routines */
static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
{
	struct coda_file_info *cfi;
	struct coda_inode_info *cii;
	struct file *host_file;
	struct dentry *de;
	struct venus_dirent *vdir;
	unsigned long vdir_size = offsetof(struct venus_dirent, d_name);
	unsigned int type;
	struct qstr name;
	ino_t ino;
	int ret;

	cfi = CODA_FTOC(coda_file);
	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
	host_file = cfi->cfi_container;

	de = coda_file->f_path.dentry;
	cii = ITOC(de->d_inode);

	vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
	if (!vdir) return -ENOMEM;

	if (!dir_emit_dots(coda_file, ctx))
		goto out;

	while (1) {
		/* read entries from the directory file */
		ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir,
				  sizeof(*vdir));
		if (ret < 0) {
			pr_err("%s: read dir %s failed %d\n",
			       __func__, coda_f2s(&cii->c_fid), ret);
			break;
		}
		if (ret == 0) break; /* end of directory file reached */

		/* catch truncated reads */
		if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
			pr_err("%s: short read on %s\n",
			       __func__, coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}
		/* validate whether the directory file actually makes sense */
		if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
			pr_err("%s: invalid dir %s\n",
			       __func__, coda_f2s(&cii->c_fid));
			ret = -EBADF;
			break;
		}

		name.len = vdir->d_namlen;
		name.name = vdir->d_name;

		/* Make sure we skip '.' and '..', we already got those */
		if (name.name[0] == '.' && (name.len == 1 ||
		    (name.name[1] == '.' && name.len == 2)))
			vdir->d_fileno = name.len = 0;

		/* skip null entries */
		if (vdir->d_fileno && name.len) {
			ino = vdir->d_fileno;
			type = CDT2DT(vdir->d_type);
			if (!dir_emit(ctx, name.name, name.len, ino, type))
				break;
		}
		/* we'll always have progress because d_reclen is unsigned and
		 * we've already established it is non-zero. */
		ctx->pos += vdir->d_reclen;
	}
out:
	kfree(vdir);
	return 0;
}
static int CVE_2010_0307_linux2_6_23_load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{
	struct file *interpreter = NULL; /* to shut gcc up */
 	unsigned long load_addr = 0, load_bias = 0;
	int load_addr_set = 0;
	char * elf_interpreter = NULL;
	unsigned int interpreter_type = INTERPRETER_NONE;
	unsigned char ibcs2_interpreter = 0;
	unsigned long error;
	struct elf_phdr *elf_ppnt, *elf_phdata;
	unsigned long elf_bss, elf_brk;
	int elf_exec_fileno;
	int retval, i;
	unsigned int size;
	unsigned long elf_entry, interp_load_addr = 0;
	unsigned long start_code, end_code, start_data, end_data;
	unsigned long reloc_func_desc = 0;
	char passed_fileno[6];
	struct files_struct *files;
	int executable_stack = EXSTACK_DEFAULT;
	unsigned long def_flags = 0;
	struct {
		struct elfhdr elf_ex;
		struct elfhdr interp_elf_ex;
  		struct exec interp_ex;
	} *loc;

	loc = kmalloc(sizeof(*loc), GFP_KERNEL);
	if (!loc) {
		retval = -ENOMEM;
		goto out_ret;
	}
	
	/* Get the exec-header */
	loc->elf_ex = *((struct elfhdr *)bprm->buf);

	retval = -ENOEXEC;
	/* First of all, some simple consistency checks */
	if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
		goto out;

	if (loc->elf_ex.e_type != ET_EXEC && loc->elf_ex.e_type != ET_DYN)
		goto out;
	if (!elf_check_arch(&loc->elf_ex))
		goto out;
	if (!bprm->file->f_op||!bprm->file->f_op->mmap)
		goto out;

	/* Now read in all of the header information */
	if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
		goto out;
	if (loc->elf_ex.e_phnum < 1 ||
	 	loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
		goto out;
	size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
	retval = -ENOMEM;
	elf_phdata = kmalloc(size, GFP_KERNEL);
	if (!elf_phdata)
		goto out;

	retval = kernel_read(bprm->file, loc->elf_ex.e_phoff,
			     (char *)elf_phdata, size);
	if (retval != size) {
		if (retval >= 0)
			retval = -EIO;
		goto out_free_ph;
	}

	files = current->files;	/* Refcounted so ok */
	retval = unshare_files();
	if (retval < 0)
		goto out_free_ph;
	if (files == current->files) {
		put_files_struct(files);
		files = NULL;
	}

	/* exec will make our files private anyway, but for the a.out
	   loader stuff we need to do it earlier */
	retval = get_unused_fd();
	if (retval < 0)
		goto out_free_fh;
	get_file(bprm->file);
	fd_install(elf_exec_fileno = retval, bprm->file);

	elf_ppnt = elf_phdata;
	elf_bss = 0;
	elf_brk = 0;

	start_code = ~0UL;
	end_code = 0;
	start_data = 0;
	end_data = 0;

	for (i = 0; i < loc->elf_ex.e_phnum; i++) {
		if (elf_ppnt->p_type == PT_INTERP) {
			/* This is the program interpreter used for
			 * shared libraries - for now assume that this
			 * is an a.out format binary
			 */
			retval = -ENOEXEC;
			if (elf_ppnt->p_filesz > PATH_MAX || 
			    elf_ppnt->p_filesz < 2)
				goto out_free_file;

			retval = -ENOMEM;
			elf_interpreter = kmalloc(elf_ppnt->p_filesz,
						  GFP_KERNEL);
			if (!elf_interpreter)
				goto out_free_file;

			retval = kernel_read(bprm->file, elf_ppnt->p_offset,
					     elf_interpreter,
					     elf_ppnt->p_filesz);
			if (retval != elf_ppnt->p_filesz) {
				if (retval >= 0)
					retval = -EIO;
				goto out_free_interp;
			}
			/* make sure path is NULL terminated */
			retval = -ENOEXEC;
			if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
				goto out_free_interp;

			/* If the program interpreter is one of these two,
			 * then assume an iBCS2 image. Otherwise assume
			 * a native linux image.
			 */
			if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 ||
			    strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0)
				ibcs2_interpreter = 1;

			/*
			 * The early SET_PERSONALITY here is so that the lookup
			 * for the interpreter happens in the namespace of the 
			 * to-be-execed image.  SET_PERSONALITY can select an
			 * alternate root.
			 *
			 * However, SET_PERSONALITY is NOT allowed to switch
			 * this task into the new images's memory mapping
			 * policy - that is, TASK_SIZE must still evaluate to
			 * that which is appropriate to the execing application.
			 * This is because exit_mmap() needs to have TASK_SIZE
			 * evaluate to the size of the old image.
			 *
			 * So if (say) a 64-bit application is execing a 32-bit
			 * application it is the architecture's responsibility
			 * to defer changing the value of TASK_SIZE until the
			 * switch really is going to happen - do this in
			 * flush_thread().	- akpm
			 */
			SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);

			interpreter = open_exec(elf_interpreter);
			retval = PTR_ERR(interpreter);
			if (IS_ERR(interpreter))
				goto out_free_interp;

			/*
			 * If the binary is not readable then enforce
			 * mm->dumpable = 0 regardless of the interpreter's
			 * permissions.
			 */
			if (file_permission(interpreter, MAY_READ) < 0)
				bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;

			retval = kernel_read(interpreter, 0, bprm->buf,
					     BINPRM_BUF_SIZE);
			if (retval != BINPRM_BUF_SIZE) {
				if (retval >= 0)
					retval = -EIO;
				goto out_free_dentry;
			}

			/* Get the exec headers */
			loc->interp_ex = *((struct exec *)bprm->buf);
			loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
			break;
		}
		elf_ppnt++;
	}

	elf_ppnt = elf_phdata;
	for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
		if (elf_ppnt->p_type == PT_GNU_STACK) {
			if (elf_ppnt->p_flags & PF_X)
				executable_stack = EXSTACK_ENABLE_X;
			else
				executable_stack = EXSTACK_DISABLE_X;
			break;
		}

	/* Some simple consistency checks for the interpreter */
	if (elf_interpreter) {
		interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;

		/* Now figure out which format our binary is */
		if ((N_MAGIC(loc->interp_ex) != OMAGIC) &&
		    (N_MAGIC(loc->interp_ex) != ZMAGIC) &&
		    (N_MAGIC(loc->interp_ex) != QMAGIC))
			interpreter_type = INTERPRETER_ELF;

		if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
			interpreter_type &= ~INTERPRETER_ELF;

		retval = -ELIBBAD;
		if (!interpreter_type)
			goto out_free_dentry;

		/* Make sure only one type was selected */
		if ((interpreter_type & INTERPRETER_ELF) &&
		     interpreter_type != INTERPRETER_ELF) {
	     		// FIXME - ratelimit this before re-enabling
			// printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
			interpreter_type = INTERPRETER_ELF;
		}
		/* Verify the interpreter has a valid arch */
		if ((interpreter_type == INTERPRETER_ELF) &&
		    !elf_check_arch(&loc->interp_elf_ex))
			goto out_free_dentry;
	} else {
		/* Executables without an interpreter also need a personality  */
		SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
	}

	/* OK, we are done with that, now set up the arg stuff,
	   and then start this sucker up */
	if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {
		char *passed_p = passed_fileno;
		sprintf(passed_fileno, "%d", elf_exec_fileno);

		if (elf_interpreter) {
			retval = copy_strings_kernel(1, &passed_p, bprm);
			if (retval)
				goto out_free_dentry; 
			bprm->argc++;
		}
	}

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		goto out_free_dentry;

	/* Discard our unneeded old files struct */
	if (files) {
		put_files_struct(files);
		files = NULL;
	}

	/* OK, This is the point of no return */
	current->flags &= ~PF_FORKNOEXEC;
	current->mm->def_flags = def_flags;

	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
	   may depend on the personality.  */
	SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
	if (elf_read_implies_exec(loc->elf_ex, executable_stack))
		current->personality |= READ_IMPLIES_EXEC;

	if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
		current->flags |= PF_RANDOMIZE;
	arch_pick_mmap_layout(current->mm);

	/* Do this so that we can load the interpreter, if need be.  We will
	   change some of these later */
	current->mm->free_area_cache = current->mm->mmap_base;
	current->mm->cached_hole_size = 0;
	retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
				 executable_stack);
	if (retval < 0) {
		send_sig(SIGKILL, current, 0);
		goto out_free_dentry;
	}
	
	current->mm->start_stack = bprm->p;

	/* Now we do a little grungy work by mmaping the ELF image into
	   the correct location in memory.  At this point, we assume that
	   the image should be loaded at fixed address, not at a variable
	   address. */
	for(i = 0, elf_ppnt = elf_phdata;
	    i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
		int elf_prot = 0, elf_flags;
		unsigned long k, vaddr;

		if (elf_ppnt->p_type != PT_LOAD)
			continue;

		if (unlikely (elf_brk > elf_bss)) {
			unsigned long nbyte;
	            
			/* There was a PT_LOAD segment with p_memsz > p_filesz
			   before this one. Map anonymous pages, if needed,
			   and clear the area.  */
			retval = set_brk (elf_bss + load_bias,
					  elf_brk + load_bias);
			if (retval) {
				send_sig(SIGKILL, current, 0);
				goto out_free_dentry;
			}
			nbyte = ELF_PAGEOFFSET(elf_bss);
			if (nbyte) {
				nbyte = ELF_MIN_ALIGN - nbyte;
				if (nbyte > elf_brk - elf_bss)
					nbyte = elf_brk - elf_bss;
				if (clear_user((void __user *)elf_bss +
							load_bias, nbyte)) {
					/*
					 * This bss-zeroing can fail if the ELF
					 * file specifies odd protections. So
					 * we don't check the return value
					 */
				}
			}
		}

		if (elf_ppnt->p_flags & PF_R)
			elf_prot |= PROT_READ;
		if (elf_ppnt->p_flags & PF_W)
			elf_prot |= PROT_WRITE;
		if (elf_ppnt->p_flags & PF_X)
			elf_prot |= PROT_EXEC;

		elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;

		vaddr = elf_ppnt->p_vaddr;
		if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
			elf_flags |= MAP_FIXED;
		} else if (loc->elf_ex.e_type == ET_DYN) {
			/* Try and get dynamic programs out of the way of the
			 * default mmap base, as well as whatever program they
			 * might try to exec.  This is because the brk will
			 * follow the loader, and is not movable.  */
			load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
		}

		error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
				elf_prot, elf_flags);
		if (BAD_ADDR(error)) {
			send_sig(SIGKILL, current, 0);
			retval = IS_ERR((void *)error) ?
				PTR_ERR((void*)error) : -EINVAL;
			goto out_free_dentry;
		}

		if (!load_addr_set) {
			load_addr_set = 1;
			load_addr = (elf_ppnt->p_vaddr - elf_ppnt->p_offset);
			if (loc->elf_ex.e_type == ET_DYN) {
				load_bias += error -
				             ELF_PAGESTART(load_bias + vaddr);
				load_addr += load_bias;
				reloc_func_desc = load_bias;
			}
		}
		k = elf_ppnt->p_vaddr;
		if (k < start_code)
			start_code = k;
		if (start_data < k)
			start_data = k;

		/*
		 * Check to see if the section's size will overflow the
		 * allowed task size. Note that p_filesz must always be
		 * <= p_memsz so it is only necessary to check p_memsz.
		 */
		if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
		    elf_ppnt->p_memsz > TASK_SIZE ||
		    TASK_SIZE - elf_ppnt->p_memsz < k) {
			/* set_brk can never work. Avoid overflows. */
			send_sig(SIGKILL, current, 0);
			retval = -EINVAL;
			goto out_free_dentry;
		}

		k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;

		if (k > elf_bss)
			elf_bss = k;
		if ((elf_ppnt->p_flags & PF_X) && end_code < k)
			end_code = k;
		if (end_data < k)
			end_data = k;
		k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
		if (k > elf_brk)
			elf_brk = k;
	}

	loc->elf_ex.e_entry += load_bias;
	elf_bss += load_bias;
	elf_brk += load_bias;
	start_code += load_bias;
	end_code += load_bias;
	start_data += load_bias;
	end_data += load_bias;

	/* Calling set_brk effectively mmaps the pages that we need
	 * for the bss and break sections.  We must do this before
	 * mapping in the interpreter, to make sure it doesn't wind
	 * up getting placed where the bss needs to go.
	 */
	retval = set_brk(elf_bss, elf_brk);
	if (retval) {
		send_sig(SIGKILL, current, 0);
		goto out_free_dentry;
	}
	if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
		send_sig(SIGSEGV, current, 0);
		retval = -EFAULT; /* Nobody gets to see this, but.. */
		goto out_free_dentry;
	}

	if (elf_interpreter) {
		if (interpreter_type == INTERPRETER_AOUT)
			elf_entry = load_aout_interp(&loc->interp_ex,
						     interpreter);
		else
			elf_entry = load_elf_interp(&loc->interp_elf_ex,
						    interpreter,
						    &interp_load_addr);
		if (BAD_ADDR(elf_entry)) {
			force_sig(SIGSEGV, current);
			retval = IS_ERR((void *)elf_entry) ?
					(int)elf_entry : -EINVAL;
			goto out_free_dentry;
		}
		reloc_func_desc = interp_load_addr;

		allow_write_access(interpreter);
		fput(interpreter);
		kfree(elf_interpreter);
	} else {
		elf_entry = loc->elf_ex.e_entry;
		if (BAD_ADDR(elf_entry)) {
			force_sig(SIGSEGV, current);
			retval = -EINVAL;
			goto out_free_dentry;
		}
	}

	kfree(elf_phdata);

	if (interpreter_type != INTERPRETER_AOUT)
		sys_close(elf_exec_fileno);

	set_binfmt(&elf_format);

#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
	retval = arch_setup_additional_pages(bprm, executable_stack);
	if (retval < 0) {
		send_sig(SIGKILL, current, 0);
		goto out;
	}
#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */

	compute_creds(bprm);
	current->flags &= ~PF_FORKNOEXEC;
	retval = create_elf_tables(bprm, &loc->elf_ex,
			  (interpreter_type == INTERPRETER_AOUT),
			  load_addr, interp_load_addr);
	if (retval < 0) {
		send_sig(SIGKILL, current, 0);
		goto out;
	}
	/* N.B. passed_fileno might not be initialized? */
	if (interpreter_type == INTERPRETER_AOUT)
		current->mm->arg_start += strlen(passed_fileno) + 1;
	current->mm->end_code = end_code;
	current->mm->start_code = start_code;
	current->mm->start_data = start_data;
	current->mm->end_data = end_data;
	current->mm->start_stack = bprm->p;

	if (current->personality & MMAP_PAGE_ZERO) {
		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
		   and some applications "depend" upon this behavior.
		   Since we do not have the power to recompile these, we
		   emulate the SVr4 behavior. Sigh. */
		down_write(&current->mm->mmap_sem);
		error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
				MAP_FIXED | MAP_PRIVATE, 0);
		up_write(&current->mm->mmap_sem);
	}

#ifdef ELF_PLAT_INIT
	/*
	 * The ABI may specify that certain registers be set up in special
	 * ways (on i386 %edx is the address of a DT_FINI function, for
	 * example.  In addition, it may also specify (eg, PowerPC64 ELF)
	 * that the e_entry field is the address of the function descriptor
	 * for the startup routine, rather than the address of the startup
	 * routine itself.  This macro performs whatever initialization to
	 * the regs structure is required as well as any relocations to the
	 * function descriptor entries when executing dynamically links apps.
	 */
	ELF_PLAT_INIT(regs, reloc_func_desc);
#endif

	start_thread(regs, elf_entry, bprm->p);
	if (unlikely(current->ptrace & PT_PTRACED)) {
		if (current->ptrace & PT_TRACE_EXEC)
			ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
		else
			send_sig(SIGTRAP, current, 0);
	}
	retval = 0;
out:
	kfree(loc);
out_ret:
	return retval;

	/* error cleanup */
out_free_dentry:
	allow_write_access(interpreter);
	if (interpreter)
		fput(interpreter);
out_free_interp:
	kfree(elf_interpreter);
out_free_file:
	sys_close(elf_exec_fileno);
out_free_fh:
	if (files)
		reset_files_struct(current, files);
out_free_ph:
	kfree(elf_phdata);
	goto out;
}
Esempio n. 16
0
int dhd_write_macaddr(struct ether_addr *mac)
{
	char *filepath_data      = MACINFO;
	char *filepath_efs      = MACINFO_EFS;

	struct file *fp_mac = NULL;
	char buf[WRMAC_BUF_SIZE]      = {0};
	mm_segment_t oldfs    = {0};
	int ret = -1;
	int retry_count = 0;

startwrite:

	sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
		mac->octet[0], mac->octet[1], mac->octet[2],
		mac->octet[3], mac->octet[4], mac->octet[5]);

	/* File will be created /data/.mac.info. */
	fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);

	if (IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_data));
		return -1;
	} else {
		oldfs = get_fs();
		set_fs(get_ds());

		if (fp_mac->f_mode & FMODE_WRITE) {
			ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
				sizeof(buf), &fp_mac->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
				" write into File: %s\n", buf, filepath_data));
			else
				DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
				" into File: %s\n", buf, filepath_data));
		}
		set_fs(oldfs);
		filp_close(fp_mac, NULL);
	}
	/* check .mac.info file is 0 byte */
	fp_mac = filp_open(filepath_data, O_RDONLY, 0);
	ret = kernel_read(fp_mac, 0, buf, 18);

	if ((ret == 0) && (retry_count++ < 3)) {
		filp_close(fp_mac, NULL);
		goto startwrite;
	}

	filp_close(fp_mac, NULL);
	/* end of /data/.mac.info */

	if (filepath_efs == NULL) {
		DHD_ERROR(("[WIFI_SEC] %s : no efs filepath", __func__));
		return 0;
	}

	/* File will be created /efs/wifi/.mac.info. */
	fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);

	if (IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
		return -1;
	} else {
		oldfs = get_fs();
		set_fs(get_ds());

		if (fp_mac->f_mode & FMODE_WRITE) {
			ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
				sizeof(buf), &fp_mac->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
				" write into File: %s\n", buf, filepath_efs));
			else
				DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
				" into File: %s\n", buf, filepath_efs));
		}
		set_fs(oldfs);
		filp_close(fp_mac, NULL);
	}

	/* check .mac.info file is 0 byte */
	fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
	ret = kernel_read(fp_mac, 0, buf, 18);

	if ((ret == 0) && (retry_count++ < 3)) {
		filp_close(fp_mac, NULL);
		goto startwrite;
	}

	filp_close(fp_mac, NULL);

	return 0;
}
Esempio n. 17
0
/*
 * Parse a comments section looking for clues as to the system this
 * was compiled on so we can get the system call interface right.
 */
static int
coff_parse_comments(struct file *fp, COFF_SCNHDR *sect, long *personality)
{
	u_long			offset, nbytes;
	int			hits = 0, err;
	char			*buffer;

	if (!(buffer = (char *)__get_free_page(GFP_KERNEL)))
		return 0;

	/*
	 * Fetch the size of the section.  There must be something in there
	 * or the section wouldn't exist at all.  We only bother with the
	 * first 8192 characters though.  There isn't any point getting too
	 * carried away!
	 */
	if ((nbytes = COFF_LONG(sect->s_size)) > 8192)
		nbytes = 8192;

	offset = COFF_LONG(sect->s_scnptr);
	while (nbytes > 0) {
		u_long		count, start = 0;
		char		*p;

		err = kernel_read(fp, offset, buffer,
				nbytes > PAGE_SIZE ? PAGE_SIZE : nbytes);

		if (err <= 0) {
			 free_page((u_long) buffer);
			 return 0;
		}

		p = buffer;
		for (count = 0; count < err; count++) {
			coff_clue		*clue;
			char			c;

			c = *(buffer + PAGE_SIZE - 1);
			*(buffer + PAGE_SIZE - 1) = '\0';

			for (clue = coff_clues; clue->len; clue++) {
				if ((clue->len < 0 && strstr(p, clue->text)) ||
				    (clue->len > 0 && !strncmp(p, clue->text, clue->len))) {
					*personality &= clue->mask_and;
					*personality |= clue->mask_or;
					if (clue->terminal) {
						free_page((u_long)buffer);
						return 1;
					}
					hits++;
				}
			}
			*(buffer + PAGE_SIZE - 1) = c;

			while (*p && count < err)
				p++, count++;
			if (count < err) {
				p++;
				count++;
				start = count;
			}
		}

		/*
		 * If we didn't find an end ofstring at all this page
		 * probably isn't useful string data.
		 */
		if (start == 0)
			start = err;

		nbytes -= start;
		offset += start;
	}

	free_page((u_long)buffer);
	return (hits);
}
Esempio n. 18
0
void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
{
	struct file *fp = NULL;
	char *filepath = PSMINFO;
	char power_val = 0;
	char iovbuf[WL_EVENTING_MASK_LEN + 12];
#ifdef DHD_ENABLE_LPC
	int ret = 0;
	uint32 lpc = 0;
#endif /* DHD_ENABLE_LPC */

	g_pm_control = FALSE;

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		/* Enable PowerSave Mode */
		dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
			sizeof(uint), TRUE, 0);
		DHD_ERROR(("[WIFI_SEC] %s: /data/.psm.info open failed,"
			" so set PM to %d\n",
			__FUNCTION__, *power_mode));
		return;
	} else {
		kernel_read(fp, fp->f_pos, &power_val, 1);
		DHD_ERROR(("[WIFI_SEC] %s: POWER_VAL = %c \r\n", __FUNCTION__, power_val));

		if (power_val == '0') {
#ifdef ROAM_ENABLE
			uint roamvar = 1;
#endif
			*power_mode = PM_OFF;
			/* Disable PowerSave Mode */
			dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
				sizeof(uint), TRUE, 0);
			/* Turn off MPC in AP mode */
			bcm_mkiovar("mpc", (char *)power_mode, 4,
				iovbuf, sizeof(iovbuf));
			dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0);
			g_pm_control = TRUE;
#ifdef ROAM_ENABLE
			/* Roaming off of dongle */
			bcm_mkiovar("roam_off", (char *)&roamvar, 4,
				iovbuf, sizeof(iovbuf));
			dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0);
#endif
#ifdef DHD_ENABLE_LPC
			/* Set lpc 0 */
			bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0)) < 0) {
				DHD_ERROR(("[WIFI_SEC] %s: Set lpc failed  %d\n",
				__FUNCTION__, ret));
			}
#endif /* DHD_ENABLE_LPC */
		} else {
			dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
				sizeof(uint), TRUE, 0);
		}
	}

	if (fp)
		filp_close(fp, NULL);
}
Esempio n. 19
0
/*
 * This procedure is called to load a library section. The various
 * libraries are loaded from the list given in the section data.
 */
static int
coff_preload_shlib(struct linux_binprm *exe_bprm, COFF_SCNHDR *sect)
{
	COFF_SLIBHD		*phdr;
	char			*buffer;
	long			nbytes;
	int			err = 0;

	/*
	 * Fetch the size of the section. There must be
	 * enough room for at least one entry.
	 */
	nbytes = (long)COFF_LONG(sect->s_size);
	if (nbytes < (long)COFF_SLIBSZ)
		return -ENOEXEC;

	if (!(buffer = kmalloc(nbytes, GFP_KERNEL))) {
		printk(KERN_WARNING "coff: unable to allocate shlib buffer\n");
		return -ENOMEM;
	}

	err = kernel_read(exe_bprm->file,
			COFF_LONG(sect->s_scnptr), buffer, nbytes);

	if (err < 0)
		goto out;
	if (err != nbytes)
		goto enoexec;

	/*
	 * Go through the list of libraries in the data area.
	 */
	phdr = (COFF_SLIBHD *)buffer;
	while (nbytes > (long)COFF_SLIBSZ) {
		int		entry_size, header_size;
		mm_segment_t	old_fs = get_fs();

		entry_size = COFF_LONG(phdr->sl_entsz) * 4;
		header_size = COFF_LONG(phdr->sl_pathndx) * 4;

		/*
		 * Validate the sizes of the various items.
		 * I don't trust the linker!!
		 */
		if ((u_int)header_size >= (u_int)nbytes)
			goto enoexec;
		if ((u_int)entry_size <= (u_int)header_size)
			goto enoexec;
		if (entry_size <= 0)
			goto enoexec;

		set_fs(get_ds());
		err = SYS(uselib,&((char *)phdr)[header_size]);
		set_fs(old_fs);

		if (err < 0)
			goto out;

		/*
		 * Point to the next library in the section data.
		 */
		nbytes -= entry_size;
		phdr = (COFF_SLIBHD *) & ((char *) phdr)[entry_size];
	}

out:
	kfree(buffer);
	return (err);
enoexec:
	err = -ENOEXEC;
	goto out;
}
Esempio n. 20
0
int dhd_sel_ant_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 ant_val = 0;
	uint32 btc_mode = 0;
	char *filepath = ANTINFO;
	char iovbuf[WLC_IOCTL_SMLEN];
	uint chip_id = dhd_bus_chip_id(dhd);

	/* Check if this chip can support MIMO */
	if (chip_id != BCM4324_CHIP_ID &&
		chip_id != BCM4350_CHIP_ID &&
		chip_id != BCM4356_CHIP_ID &&
		chip_id != BCM4354_CHIP_ID) {
		DHD_ERROR(("[WIFI_SEC] %s: This chipset does not support MIMO\n",
			__FUNCTION__));
		return ret;
	}

	/* Read antenna settings from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] open error\n", __FUNCTION__, filepath));
		return ret;
	} else {
		ret = kernel_read(fp, 0, (char *)&ant_val, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return ret;
		}

		ant_val = bcm_atoi((char *)&ant_val);

		DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
		filp_close(fp, NULL);

		/* Check value from the file */
		if (ant_val < 1 || ant_val > 3) {
			DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, ant_val, filepath));
			return -1;
		}
	}

	/* bt coex mode off */
	if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
		bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
		if (ret) {
			DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
				"btc_mode, ret=%d\n",
				__FUNCTION__, ret));
			return ret;
		}
	}

	/* Select Antenna */
	bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	return 0;
}
Esempio n. 21
0
static int ml_bootstrapDylinker(struct file* file, /* file for the dylinker*/
								int* top_data, /* top of image data */
								void** first_text,
								void** entry_point) /* first text segment of the linker */
								
{
	/* fake bprm for the segment loader*/
	struct linux_binprm bprm;
	
	int retval;
	int load_addr = *top_data;
	size_t macho_header_sz = sizeof(macho_header);
	macho_header* head = kmalloc(macho_header_sz, GFP_KERNEL);
	int file_size = 0;
	
	/* this is for LC loader */
	int ret = 0;
	size_t offset;
	size_t oldoffset;
	uint32_t ncmds;
	uint8_t* addr;
	
	if (_verboseLog)
		printk(KERN_WARNING "ml_bootstrapDylinker: loading dynamic linker @ %d\n", load_addr);

	/*
		Read in the macho header.
	*/
	kernel_read(file, 0, head, macho_header_sz);

	retval = ml_checkImage(file, head);
	if (retval) {
		retval = LOAD_BADMACHO;
		printk(KERN_WARNING "ml_bootstrapDylinker: dylinker image failed sanity checks, not loading \n");
		goto out_ret;
	}
	
	/*
		XXX: this should be retrieved by ml_checkImage()
	*/
	file_size = ml_getFileSize(file);
	
	/*
		Read the load commands from the file.
	*/
	offset = 0;
	ncmds = head->ncmds;
	addr = kmalloc(head->sizeofcmds, GFP_KERNEL); /***/
	retval = -EINVAL;
	
	/* read in load commands */
	kernel_read(file, macho_header_sz, addr, head->sizeofcmds);
	
	bprm.file = file;
	
	while (ncmds--) {
		/* LC pointer */
		struct load_command	*lcp = 
		(struct load_command *)(addr + offset);
		
		oldoffset = offset;
		offset += lcp->cmdsize;
		
		if (oldoffset > offset ||
		    lcp->cmdsize < sizeof(struct load_command) ||
		    offset > head->sizeofcmds + macho_header_sz)
		{
			printk(KERN_WARNING "ml_bootstrapDylinker: malformed binary - lc overflow \n");
			goto lc_ret;
		}
		
		/*  Parse load commands.
		 
			We only need a bare minimum to get the image up an running. Dyld will
			take care of all the other stuff.
		 */
		switch(lcp->cmd) {
			case LC_SEGMENT:
			{
				/*
					Load and slide a dylinker segment.
				*/
				ret = ml_loadSegment(&bprm,
									file_size,
									(struct segment_command*)lcp,
									top_data, /* keep bumping the same top_data */
									first_text, /* first text segment */
									load_addr); /* slide up */
				
				if (ret != LOAD_SUCCESS) {
					printk(KERN_WARNING "ml_bootstrapDylinker: segment loading failure \n");
					goto lc_ret;
				}
				break;
			}
			case LC_UNIXTHREAD:
			{
				ret = ml_loadUnixThread(&bprm,
										file_size,
										(struct arm_thread_command*)lcp,
										entry_point);
										
				if (ret != LOAD_SUCCESS) {
					printk(KERN_WARNING "ml_bootstrapDylinker: unix thread loading failure \n");
					goto lc_ret;
				}
				break;
			}
			default: 
			{
				if (_verboseLog)
					printk(KERN_WARNING "ml_bootstrapDylinker: unsupported lc 0x%p \n", (void*)lcp->cmd);
				
				break;
			}
		}
	}


	/* loaded successfully */
	retval = LOAD_SUCCESS;
	
	/* free resources */
	lc_ret:
		kfree(addr);
	
	out_ret:	
		kfree(head);
		return retval;
}
Esempio n. 22
0
int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
{
	struct file *fp = NULL;
	char *filepath = NULL;
	int val = 0;

	if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
		(mode >= PARAM_LAST_VALUE)) {
		DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
		return BCME_ERROR;
	}

	switch (mode) {
		case SET_PARAM_BUS_TXGLOM_MODE:
			filepath = "/data/.bustxglom.info";
			break;
		case SET_PARAM_ROAMOFF:
			filepath = "/data/.roamoff.info";
			break;
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
			filepath = "/data/.frameburst.info";
			break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
			filepath = "/data/.txbf.info";
			break;
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
			filepath = "/data/.proptx.info";
			break;
#endif /* PROP_TXSTATUS */
		default:
			DHD_ERROR(("[WIFI_SEC] %s: File to find file name for index=%d\n",
				__FUNCTION__, mode));
			return BCME_ERROR;
	}

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: File open failed, file path=%s\n",
			__FUNCTION__, filepath));
		return BCME_ERROR;
	} else {
		if (kernel_read(fp, fp->f_pos, (char *)&val, 4) < 0) {
		filp_close(fp, NULL);
			/* File operation is failed so we will return error code */
			DHD_ERROR(("[WIFI_SEC] %s: read failed, file path=%s\n",
				__FUNCTION__, filepath));
			return BCME_ERROR;
		}
		filp_close(fp, NULL);
	}

	val = bcm_atoi((char *)&val);

	switch (mode) {
		case SET_PARAM_ROAMOFF:
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
#endif /* PROP_TXSTATUS */
		if (val < 0 || val > 1) {
			DHD_ERROR(("[WIFI_SEC] %s: value[%d] is out of range\n",
				__FUNCTION__, *read_val));
			return BCME_ERROR;
		}
			break;
		default:
			return BCME_ERROR;
	}
	*read_val = (uint)val;
	return BCME_OK;
}
Esempio n. 23
0
int sec_dhd_config_pm(dhd_pub_t *dhd, uint power_mode)
{
	struct file *fp      = NULL;
	char* filepath       = "/data/.psm.info";
	char iovbuf[WL_EVENTING_MASK_LEN + 12];
	int ret = 0;
	
	/* Set PowerSave mode */
	fp = filp_open(filepath, O_RDONLY, 0);
	if(IS_ERR(fp))// the file is not exist
	{
		/* Set PowerSave mode */
		ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
		if (ret < 0)
			goto err_out;

		fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
		if(IS_ERR(fp)||(fp==NULL))
		{
			DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
		}
		else
		{
			char buffer[2]   = {1};
			if(fp->f_mode & FMODE_WRITE)
			{
				sprintf(buffer,"1\n");
				fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
			}
			if(fp)
    	 			filp_close(fp, NULL);
		}
		return;	
	}
	else
	{
		char buffer[1]   = {0};
		kernel_read(fp, fp->f_pos, buffer, 1);
		if(strncmp(buffer, "1",1)==0)
		{
			/* Set PowerSave mode */
			ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
			if (ret < 0)
				goto err_out;
		}
		else
		{
			/*Disable Power save features for CERTIFICATION*/
			power_mode = 0;
		 
			/* Set PowerSave mode */
			ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
			if (ret < 0)
				goto err_out;
		 
			/* Disable MPC */    
			bcm_mkiovar("mpc", (char *)&power_mode, 4, iovbuf, sizeof(iovbuf));
			ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
			if (ret < 0)
				goto err_out;

			fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
			if(IS_ERR(fp)||(fp==NULL))
			{
				DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
			}
			else
			{
				char buffer[2]   = {1};
				if(fp->f_mode & FMODE_WRITE)
				{
					sprintf(buffer,"1\n");
					fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
				}
				if(fp)
    	 				filp_close(fp, NULL);
			}
			return;	
			
		}
	}
err_out:
	if(fp)
		filp_close(fp, NULL);
	return ret;
}
Esempio n. 24
0
uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p)
{
	struct file *fp = NULL;
	struct file *nvfp = NULL;
	char *filepath = WIFIVERINFO;
	int min_len, str_len = 0;
	int ret = 0;
	char* nvram_buf;
	char temp_buf[256];

	DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));

	DHD_INFO(("[WIFI_SEC] firmware version   : %s\n", firm_ver));
	DHD_INFO(("[WIFI_SEC] dhd driver version : %s\n", dhd_ver));
	DHD_INFO(("[WIFI_SEC] nvram path : %s\n", nvram_p));

	memset(version_info, 0, sizeof(version_info));

	if (strlen(dhd_ver)) {
		min_len = min(strlen(dhd_ver), max_len(temp_buf, DHD_PREFIX));
		min_len += strlen(DHD_PREFIX) + 3;
		DHD_INFO(("[WIFI_SEC] DHD ver length : %d\n", min_len));
		snprintf(version_info+str_len, min_len, DHD_PREFIX " %s\n", dhd_ver);
		str_len = strlen(version_info);

		DHD_INFO(("[WIFI_SEC] Driver version_info len : %d\n", str_len));
		DHD_INFO(("[WIFI_SEC] Driver version_info : %s\n", version_info));
	} else {
		DHD_ERROR(("[WIFI_SEC] Driver version is missing.\n"));
	}

	if (strlen(firm_ver)) {
		min_len = min(strlen(firm_ver), max_len(temp_buf, FIRM_PREFIX));
		min_len += strlen(FIRM_PREFIX) + 3;
		DHD_INFO(("[WIFI_SEC] firmware ver length : %d\n", min_len));
		snprintf(version_info+str_len, min_len, FIRM_PREFIX " %s\n", firm_ver);
		str_len = strlen(version_info);

		DHD_INFO(("[WIFI_SEC] Firmware version_info len : %d\n", str_len));
		DHD_INFO(("[WIFI_SEC] Firmware version_info : %s\n", version_info));
	} else {
		DHD_ERROR(("[WIFI_SEC] Firmware version is missing.\n"));
	}

	if (nvram_p) {
		memset(temp_buf, 0, sizeof(temp_buf));
		nvfp = filp_open(nvram_p, O_RDONLY, 0);
		if (IS_ERR(nvfp) || (nvfp == NULL)) {
			DHD_ERROR(("[WIFI_SEC] %s: Nvarm File open failed.\n", __FUNCTION__));
			return -1;
		} else {
			ret = kernel_read(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf));
			filp_close(nvfp, NULL);
		}

		if (strlen(temp_buf)) {
			nvram_buf = temp_buf;
			bcmstrtok(&nvram_buf, "\n", 0);
			DHD_INFO(("[WIFI_SEC] nvram tolkening : %s(%zu) \n",
				temp_buf, strlen(temp_buf)));
			snprintf(version_info+str_len, tstr_len(temp_buf, NV_PREFIX),
				NV_PREFIX " %s\n", temp_buf);
			str_len = strlen(version_info);
			DHD_INFO(("[WIFI_SEC] NVRAM version_info : %s\n", version_info));
			DHD_INFO(("[WIFI_SEC] NVRAM version_info len : %d, nvram len : %zu\n",
				str_len, strlen(temp_buf)));
		} else {
			DHD_ERROR(("[WIFI_SEC] NVRAM info is missing.\n"));
		}
	} else {
		DHD_ERROR(("[WIFI_SEC] Not exist nvram path\n"));
	}

	DHD_INFO(("[WIFI_SEC] version_info : %s, strlen : %zu\n",
		version_info, strlen(version_info)));

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n", __FUNCTION__));
	} else {
		memset(version_old_info, 0, sizeof(version_old_info));
		ret = kernel_read(fp, fp->f_pos, version_old_info, sizeof(version_info));
		filp_close(fp, NULL);
		DHD_INFO(("[WIFI_SEC] kernel_read ret : %d.\n", ret));
		if (strcmp(version_info, version_old_info) == 0) {
			DHD_ERROR(("[WIFI_SEC] .wifiver.info already saved.\n"));
			return 0;
		}
	}

	fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n",
			__FUNCTION__));
	} else {
		ret = write_filesystem(fp, fp->f_pos, version_info, sizeof(version_info));
		DHD_INFO(("[WIFI_SEC] sec_save_wlinfo done. ret : %d\n", ret));
		DHD_ERROR(("[WIFI_SEC] save .wifiver.info file.\n"));
		filp_close(fp, NULL);
	}
	return ret;
}
int dhd_custom_get_mac_address(unsigned char *buf)
{
    int ret = 0;
    int maclen;
    int i = 0;
    struct file *fp;
    char macaddr[16];
    char c = '\0';
    if (!buf)
    return -1;

    fp = filp_open("/data/misc/wifi/wifiNvMacaddress", O_RDONLY, 0);
    if(IS_ERR(fp) || (fp == NULL))
    {
        printk("djt %s open file err, fp = %x\n", __FUNCTION__, fp);
        return -1;
    }

    maclen = kernel_read(fp, 0, macaddr, 12);

    filp_close(fp, NULL);
    macaddr[12] = 0x00;
    //printk("zhaoruiqing macaddr %s\n", macaddr);

    for(i = 0; i < 6; i++)
    {
        unsigned int sum = 0;
        if(macaddr[i * 2] <= 'F' && macaddr[i * 2] >= 'A')
        {
            c = macaddr[i * 2] - 'A' + 10;
        }
        else if(macaddr[i * 2] <= 'f' && macaddr[i * 2] >= 'a')
        {
            c = macaddr[i * 2] - 'a' + 10;
        }
        else
        {
            c = macaddr[i * 2] - '0';
        }
        sum = c * 16;
        if(macaddr[i * 2 + 1] <= 'F' && macaddr[i * 2 + 1] >= 'A')
        {
            c = macaddr[i * 2 + 1] - 'A' + 10;
        }
        else if(macaddr[i * 2 + 1] <= 'f' && macaddr[i * 2 + 1] >= 'a')
        {
            c = macaddr[i * 2 + 1] - 'a' + 10;
        }
        else
        {
            c = macaddr[i * 2 + 1] - '0';
        }
        sum += c;

        printk("zhaoruiqing sum = %02x \n ", sum);
        buf[i] = (unsigned char)sum;

    }
    //printk("zhaoruiqing buf: %x\n ", buf);

    return ret;
}
Esempio n. 26
0
int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
	struct file *fp      = NULL;
	char macbuffer[18]   = {0};
	mm_segment_t oldfs   = {0};
	char randommac[3]    = {0};
	char buf[18]         = {0};
	char *filepath_efs       = MACINFO_EFS;
	int ret = 0;

	fp = filp_open(filepath_efs, O_RDONLY, 0);
	if (IS_ERR(fp)) {
start_readmac:
		/* File Doesn't Exist. Create and write mac addr. */
		fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
		if (IS_ERR(fp)) {
			DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
			return -1;
		}
		oldfs = get_fs();
		set_fs(get_ds());

		/* Generating the Random Bytes for 3 last octects of the MAC address */
		get_random_bytes(randommac, 3);

		sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
		DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID: %s\n", macbuffer));

		if (fp->f_mode & FMODE_WRITE) {
			ret = fp->f_op->write(fp, (const char *)macbuffer,
			sizeof(macbuffer), &fp->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] MAC address [%s] Failed to write into File:"
					" %s\n", macbuffer, filepath_efs));
			else
				DHD_ERROR(("[WIFI_SEC] MAC address [%s] written into File: %s\n",
					macbuffer, filepath_efs));
		}
		set_fs(oldfs);
		/* Reading the MAC Address from .mac.info file
		   ( the existed file or just created file)
		 */
		ret = kernel_read(fp, 0, buf, 18);
	} else {
		/* Reading the MAC Address from
		   .mac.info file( the existed file or just created file)
		 */
		ret = kernel_read(fp, 0, buf, 18);
		/* to prevent abnormal string display
		* when mac address is displayed on the screen.
		*/
		buf[17] = '\0';
		if (strncmp(buf, "00:00:00:00:00:00", 17) < 1) {
			DHD_ERROR(("[WIFI_SEC] goto start_readmac \r\n"));
			filp_close(fp, NULL);
			goto start_readmac;
		}
	}

	if (ret)
		sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
			(unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
			(unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
			(unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
	else
		DHD_ERROR(("[WIFI_SEC] dhd_bus_start: Reading from the '%s' returns 0 bytes\n",
			filepath_efs));

	if (fp)
		filp_close(fp, NULL);

	/* Writing Newly generated MAC ID to the Dongle */
	if (_dhd_set_mac_address(dhd, 0, mac) == 0)
		DHD_INFO(("[WIFI_SEC] dhd_bus_start: MACID is overwritten\n"));
	else
		DHD_ERROR(("[WIFI_SEC] dhd_bus_start: _dhd_set_mac_address() failed\n"));

	return 0;
}
Esempio n. 27
0
int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
		struct ether_addr *mac)
{
	struct file *fp_mac = NULL;
	struct file *fp_nvm = NULL;
	char macbuffer[18]    = {0};
	char randommac[3]   = {0};
	char buf[18]      = {0};
	char buf_temp[18] = {0};
#ifdef ENABLE_INSMOD_NO_FW_LOAD
	char *filepath      = "/efs/wifi/mac/.mac.info";
#else
	char *filepath      = "/efs/wifi/.mac.info";
#endif
#ifdef CONFIG_TARGET_LOCALE_NA
	char *nvfilepath = "/data/misc/wifi/.nvmac.info";
#else
#ifdef CONFIG_MACH_SAMSUNG_P4LTE
	char *nvfilepath = "/data/.mac.info";
	char *nvfilepath2 = "/efs/wifi/.mac.info";
#else
	char *nvfilepath = "/efs/wifi/.nvmac.info";
	char *nvfilepath2 = "/efs/imei/.nvmac.info";
#endif
#endif
	char cur_mac[128]   = {0};
	char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
	char cur_macbuffer[18]  = {0};
	int ret = -1;

	g_imac_flag = MACADDR_NONE;

	fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
	if (IS_ERR(fp_nvm)) { /* file does not exist */
		DHD_ERROR(("[WIFI] Fail to open %s, "
		 "MAC address is missing or Wi-Fi only model\n", nvfilepath));
		fp_nvm = filp_open(nvfilepath2, O_RDONLY, 0);
	}
	if (IS_ERR(fp_nvm)) { /* file does not exist */
		DHD_ERROR(("[WIFI] Fail to open %s\n", nvfilepath2));

		/* read MAC Address */
		strcpy(cur_mac, "cur_etheraddr");
		ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac,
				sizeof(cur_mac), 0, 0);
		if (ret < 0) {
			DHD_ERROR(("Current READ MAC error \r\n"));
			memset(cur_mac , 0 , ETHER_ADDR_LEN);
			return -1;
		} else {
			DHD_ERROR(("MAC (OTP) : "
			"[%02X.%02X.%02X] \r\n",
			cur_mac[0], cur_mac[4], cur_mac[5]));
		}

		sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			cur_mac[0], cur_mac[1], cur_mac[2],
			cur_mac[3], cur_mac[4], cur_mac[5]);

		fp_mac = filp_open(filepath, O_RDONLY, 0);
		if (IS_ERR(fp_mac)) { /* file does not exist */
			/* read mac is the dummy mac (00:90:4C:C5:12:38) */
			if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else
				g_imac_flag = MACADDR_MOD;
		} else {
			int is_zeromac;

			ret = kernel_read(fp_mac, 0, buf, 18);
			filp_close(fp_mac, NULL);
			buf[17] = '\0';

			is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
			/*DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n",
				buf, is_zeromac));*/

			if (is_zeromac == 0) {
				DHD_ERROR(("Zero MAC detected."
					" Trying Random MAC.\n"));
				g_imac_flag = MACADDR_MOD_RANDOM;
			} else {
				sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
					(unsigned int *)&(mac->octet[0]),
					(unsigned int *)&(mac->octet[1]),
					(unsigned int *)&(mac->octet[2]),
					(unsigned int *)&(mac->octet[3]),
					(unsigned int *)&(mac->octet[4]),
					(unsigned int *)&(mac->octet[5]));

				DHD_ERROR(("MAC (FILE): [%02X.%02X.%02X] "
					"[%d] \r\n",
					mac->octet[0], mac->octet[4],
					mac->octet[5], is_zeromac));
				/* current MAC address is same as previous one */
				if (memcmp(cur_mac, mac->octet,
					ETHER_ADDR_LEN) == 0) {
					g_imac_flag = MACADDR_NONE;
				} else { /* change MAC address */
					if (0 == _dhd_set_mac_address(dhd,
						0, mac)) {
						DHD_INFO(("%s: MACID is"
						" overwritten\n", __func__));
						g_imac_flag = MACADDR_MOD;
					} else {
						DHD_ERROR(("%s: "
						"_dhd_set_mac_address()"
						" failed\n", __func__));
						g_imac_flag = MACADDR_NONE;
					}
				}
			}
		}
	} else {
		/* COB type. only COB. */
		/* Reading the MAC Address from .nvmac.info file
		 * (the existed file or just created file)
		 */
		ret = kernel_read(fp_nvm, 0, buf, 18);

		/* to prevent abnormal string display when mac address
		 * is displayed on the screen.
		 */
		buf[17] = '\0';
		/*DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf,
			strncmp(buf, "00:00:00:00:00:00", 17)));*/
		if ((buf[0] == '\0') ||
			(strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
			g_imac_flag = MACADDR_COB_RANDOM;
		} else {
			if (!strncmp(buf, "12:34:56", 8)) {
				strncpy(buf_temp, buf+9, 8);
				snprintf(buf, 18, "00:12:34:%s", buf_temp);
				DHD_ERROR(("Wrong prefix is detected, 12:34:56 is changed as 00:12:34 : %d\n", sizeof(buf)));
			}
			sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
				(unsigned int *)&(mac->octet[0]),
				(unsigned int *)&(mac->octet[1]),
				(unsigned int *)&(mac->octet[2]),
				(unsigned int *)&(mac->octet[3]),
				(unsigned int *)&(mac->octet[4]),
				(unsigned int *)&(mac->octet[5]));
			/* Writing Newly generated MAC ID to the Dongle */
			if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
				DHD_INFO(("%s: MACID is overwritten\n",
					__func__));
				g_imac_flag = MACADDR_COB;
			} else {
				DHD_ERROR(("%s: _dhd_set_mac_address()"
					" failed\n", __func__));
			}
		}
		filp_close(fp_nvm, NULL);
	}

	if ((g_imac_flag == MACADDR_COB_RANDOM) ||
	    (g_imac_flag == MACADDR_MOD_RANDOM)) {
		get_random_bytes(randommac, 3);
		sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			0x00, 0x12, 0x34, randommac[0], randommac[1],
			randommac[2]);
		sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X",
			(unsigned int *)&(mac->octet[0]),
			(unsigned int *)&(mac->octet[1]),
			(unsigned int *)&(mac->octet[2]),
			(unsigned int *)&(mac->octet[3]),
			(unsigned int *)&(mac->octet[4]),
			(unsigned int *)&(mac->octet[5]));
		DHD_ERROR(("[WIFI] The Random Generated MAC ID : "
			"%02X.%02X.%02X\n",
			mac->octet[0], mac->octet[4], mac->octet[5]));
		if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
			DHD_INFO(("%s: MACID is overwritten\n", __func__));
			g_imac_flag = MACADDR_COB;
		} else {
			DHD_ERROR(("%s: _dhd_set_mac_address() failed\n",
				__func__));
		}
	}

	return 0;
}
Esempio n. 28
0
int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
	struct ether_addr *mac)
{
	struct file *fp_mac = NULL;
	struct file *fp_nvm = NULL;
	char macbuffer[18]    = {0};
	char randommac[3]   = {0};
	char buf[18]      = {0};
	char *filepath_data      = MACINFO;
	char *filepath_efs      = MACINFO_EFS;
#ifdef CONFIG_TARGET_LOCALE_NA
	char *nvfilepath       = "/data/misc/wifi/.nvmac.info";
#else
	char *nvfilepath = "/efs/wifi/.nvmac.info";
#endif
	char cur_mac[128]   = {0};
	char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
	char cur_macbuffer[18]  = {0};
	int ret = -1;

	g_imac_flag = MACADDR_NONE;

	fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
	if (IS_ERR(fp_nvm)) { /* file does not exist */

		/* read MAC Address */
		strcpy(cur_mac, "cur_etheraddr");
		ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac,
			sizeof(cur_mac), 0, 0);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] Current READ MAC error \r\n"));
			memset(cur_mac, 0, ETHER_ADDR_LEN);
			return -1;
		} else {
			DHD_ERROR(("[WIFI_SEC] MAC (OTP) : "
			"[%02X:%02X:%02X:%02X:%02X:%02X] \r\n",
			cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3],
			cur_mac[4], cur_mac[5]));
		}

		sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			cur_mac[0], cur_mac[1], cur_mac[2],
			cur_mac[3], cur_mac[4], cur_mac[5]);

		fp_mac = filp_open(filepath_data, O_RDONLY, 0);
		if (IS_ERR(fp_mac)) { /* file does not exist */
			/* read mac is the dummy mac (00:90:4C:C5:12:38) */
			if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else
				g_imac_flag = MACADDR_MOD;
		} else {
			int is_zeromac;

			ret = kernel_read(fp_mac, 0, buf, 18);
			filp_close(fp_mac, NULL);
			buf[17] = '\0';

			is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
			DHD_ERROR(("[WIFI_SEC] MAC (FILE): [%s] [%d] \r\n",
				buf, is_zeromac));

			if (is_zeromac == 0) {
				DHD_ERROR(("[WIFI_SEC] Zero MAC detected."
					" Trying Random MAC.\n"));
				g_imac_flag = MACADDR_MOD_RANDOM;
			} else {
				sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
					(unsigned int *)&(mac->octet[0]),
					(unsigned int *)&(mac->octet[1]),
					(unsigned int *)&(mac->octet[2]),
					(unsigned int *)&(mac->octet[3]),
					(unsigned int *)&(mac->octet[4]),
					(unsigned int *)&(mac->octet[5]));
			/* current MAC address is same as previous one */
				if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
					g_imac_flag = MACADDR_NONE;
				} else { /* change MAC address */
					if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
						DHD_INFO(("[WIFI_SEC] %s: MACID is"
						" overwritten\n", __FUNCTION__));
						g_imac_flag = MACADDR_MOD;
					} else {
						DHD_ERROR(("[WIFI_SEC] %s: "
						"_dhd_set_mac_address()"
						" failed\n", __FUNCTION__));
						g_imac_flag = MACADDR_NONE;
					}
				}
			}
		}
		fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
		if (IS_ERR(fp_mac)) { /* file does not exist */
			/* read mac is the dummy mac (00:90:4C:C5:12:38) */
			if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
				g_imac_flag = MACADDR_MOD_RANDOM;
			else
				g_imac_flag = MACADDR_MOD;
		} else {
			int is_zeromac;

			ret = kernel_read(fp_mac, 0, buf, 18);
			filp_close(fp_mac, NULL);
			buf[17] = '\0';

			is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
			DHD_ERROR(("[WIFI_SEC] MAC (FILE): [%s] [%d] \r\n",
				buf, is_zeromac));

			if (is_zeromac == 0) {
				DHD_ERROR(("[WIFI_SEC] Zero MAC detected."
					" Trying Random MAC.\n"));
				g_imac_flag = MACADDR_MOD_RANDOM;
			} else {
				sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
					(unsigned int *)&(mac->octet[0]),
					(unsigned int *)&(mac->octet[1]),
					(unsigned int *)&(mac->octet[2]),
					(unsigned int *)&(mac->octet[3]),
					(unsigned int *)&(mac->octet[4]),
					(unsigned int *)&(mac->octet[5]));
			/* current MAC address is same as previous one */
				if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
					g_imac_flag = MACADDR_NONE;
				} else { /* change MAC address */
					if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
						DHD_INFO(("[WIFI_SEC] %s: MACID is"
						" overwritten\n", __FUNCTION__));
						g_imac_flag = MACADDR_MOD;
					} else {
						DHD_ERROR(("[WIFI_SEC] %s: "
						"_dhd_set_mac_address()"
						" failed\n", __FUNCTION__));
						g_imac_flag = MACADDR_NONE;
					}
				}
			}
		}
	} else {
		/* COB type. only COB. */
		/* Reading the MAC Address from .nvmac.info file
		 * (the existed file or just created file)
		 */
		ret = kernel_read(fp_nvm, 0, buf, 18);

		/* to prevent abnormal string display when mac address
		 * is displayed on the screen.
		 */
		buf[17] = '\0';
		DHD_ERROR(("[WIFI_SEC] Read MAC : [%s] [%d] \r\n", buf,
			strncmp(buf, "00:00:00:00:00:00", 17)));
		if ((buf[0] == '\0') ||
			(strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
			g_imac_flag = MACADDR_COB_RANDOM;
		} else {
			sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
				(unsigned int *)&(mac->octet[0]),
				(unsigned int *)&(mac->octet[1]),
				(unsigned int *)&(mac->octet[2]),
				(unsigned int *)&(mac->octet[3]),
				(unsigned int *)&(mac->octet[4]),
				(unsigned int *)&(mac->octet[5]));
			/* Writing Newly generated MAC ID to the Dongle */
			if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
				DHD_INFO(("[WIFI_SEC] %s: MACID is overwritten\n",
					__FUNCTION__));
				g_imac_flag = MACADDR_COB;
			} else {
				DHD_ERROR(("[WIFI_SEC] %s: _dhd_set_mac_address()"
					" failed\n", __FUNCTION__));
			}
		}
		filp_close(fp_nvm, NULL);
	}

	if ((g_imac_flag == MACADDR_COB_RANDOM) ||
	    (g_imac_flag == MACADDR_MOD_RANDOM)) {
		get_random_bytes(randommac, 3);
		sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			0x60, 0xd0, 0xa9, randommac[0], randommac[1],
			randommac[2]);
		DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID : %s\n",
			macbuffer));
		sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X",
			(unsigned int *)&(mac->octet[0]),
			(unsigned int *)&(mac->octet[1]),
			(unsigned int *)&(mac->octet[2]),
			(unsigned int *)&(mac->octet[3]),
			(unsigned int *)&(mac->octet[4]),
			(unsigned int *)&(mac->octet[5]));
		if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
			DHD_INFO(("[WIFI_SEC] %s: MACID is overwritten\n", __FUNCTION__));
			g_imac_flag = MACADDR_COB;
		} else {
			DHD_ERROR(("[WIFI_SEC] %s: _dhd_set_mac_address() failed\n",
				__FUNCTION__));
		}
	}

	return 0;
}
Esempio n. 29
0
int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
	struct file *fp      = NULL;
	char macbuffer[18]   = {0};
	mm_segment_t oldfs   = {0};
	char randommac[3]    = {0};
	char buf[18]         = {0};
	char *filepath_efs       = MACINFO_EFS;
	int is_zeromac       = 0;
	int ret = 0;
	/* MAC address copied from efs/wifi.mac.info */
	fp = filp_open(filepath_efs, O_RDONLY, 0);

	if (IS_ERR(fp)) {
		/* File Doesn't Exist. Create and write mac addr.*/
		fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
		if (IS_ERR(fp)) {
			DHD_ERROR(("[WIFI] %s: File open error\n",
				filepath_efs));
			return -1;
		}

		oldfs = get_fs();
		set_fs(get_ds());

		/* Generating the Random Bytes for
		 * 3 last octects of the MAC address
		 */
		get_random_bytes(randommac, 3);

		sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				0x60, 0xd0, 0xa9, randommac[0],
				randommac[1], randommac[2]);
		DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n",
				macbuffer));

		if (fp->f_mode & FMODE_WRITE) {
			ret = fp->f_op->write(fp,
				(const char *)macbuffer,
					sizeof(macbuffer), &fp->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI] Mac address [%s]"
					" Failed to write into File:"
					" %s\n", macbuffer, filepath_efs));
			else
				DHD_ERROR(("[WIFI] Mac address [%s]"
					" written into File: %s\n",
					macbuffer, filepath_efs));
		}
		set_fs(oldfs);
	} else {
	/* Reading the MAC Address from .mac.info file
	 * (the existed file or just created file)
	 */
	    ret = kernel_read(fp, 0, buf, 18);
		/* to prevent abnormal string display when mac address
		 * is displayed on the screen.
		 */
		buf[17] = '\0';
		/* Remove security log */
		/*DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf,
			strncmp(buf, "00:00:00:00:00:00", 17)));*/
		if ((buf[0] == '\0') ||
			(strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
			is_zeromac = 1;
		}
	}

	if (ret)
		sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
			(unsigned int *)&(mac->octet[0]),
			(unsigned int *)&(mac->octet[1]),
			(unsigned int *)&(mac->octet[2]),
			(unsigned int *)&(mac->octet[3]),
			(unsigned int *)&(mac->octet[4]),
			(unsigned int *)&(mac->octet[5]));
	else
		DHD_INFO(("dhd_bus_start: Reading from the"
			" '%s' returns 0 bytes\n", filepath_efs));

	if (fp)
		filp_close(fp, NULL);

	if (!is_zeromac) {
		/* Writing Newly generated MAC ID to the Dongle */
		if (0 == _dhd_set_mac_address(dhd, 0, mac))
			DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
		else
			DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() "
				"failed\n"));
	} else {
		DHD_ERROR(("dhd_bus_start:Is ZeroMAC BypassWrite.mac.info!\n"));
	}

	return 0;
}
int dhd_sel_ant_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 ant_val = 0;
	uint32 btc_mode = 0;
	char *filepath = "/data/.ant.info";
	char iovbuf[WLC_IOCTL_SMLEN];

	/* Read antenna settings from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI] %s: File [%s] open error\n", __FUNCTION__, filepath));
		return ret;
	} else {
		ret = kernel_read(fp, 0, (char *)&ant_val, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return ret;
		}

		ant_val = bcm_atoi((char *)&ant_val);

		DHD_ERROR(("[WIFI] %s: ANT val = %d\n", __FUNCTION__, ant_val));
		filp_close(fp, NULL);

		/* Check value from the file */
		if (ant_val < 1 || ant_val > 3) {
			DHD_ERROR(("[WIFI] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, ant_val, filepath));
			return -1;
		}
	}

	/* bt coex mode off */
	if (strstr(fw_path, "_mfg") != NULL) {
		bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
		if (ret) {
			DHD_ERROR(("[WIFI] %s: Fail to execute dhd_wl_ioctl_cmd(): "
				"btc_mode, ret=%d\n",
				__FUNCTION__, ret));
			return ret;
		}
	}

	/* Select Antenna */
	bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	return 0;
}