Exemple #1
0
static u_long *
coff_mktables(char *p, int argc, int envc)
{
	u_long			*argv, *envp;
	u_long			*sp;

	sp = (u_long *) ((-(u_long)sizeof(char *)) & (u_long)p);

	sp -= envc + 1;
	envp = sp;
	sp -= argc + 1;
	argv = sp;

	put_user(argc, --sp);
	current->mm->arg_start = (u_long)p;

	while (argc-- > 0) {
		__put_user(p, argv++);
		p += strlen_user(p);
	}

	__put_user(NULL, argv);
	current->mm->arg_end = current->mm->env_start = (u_long)p;

	while (envc-- > 0) {
		__put_user(p, envp++);
		p += strlen_user(p);
	}

	__put_user(NULL, envp);
	current->mm->env_end = (u_long) p;

	return (sp);
}
Exemple #2
0
void *
pfq_context_alloc(struct pfq_computation_descr const *descr)
{
        size_t size = 0, n = 0;
        void *ret;

        for(; n < descr->size; n++)
        {
		struct pfq_functional_descr const * fun = &descr->fun[n];
		int i;

		for(i = 0; i < sizeof(fun->arg)/sizeof(fun->arg[0]); i++)
		{
			if (fun->arg[i].addr) {

				size_t s = is_arg_string(&fun->arg[i])     ?  strlen_user(fun->arg[i].addr) :
					   is_arg_vector(&fun->arg[i])	   ?  fun->arg[i].size * fun->arg[i].nelem :
					   is_arg_vector_str(&fun->arg[i]) ?  fun->arg[i].nelem * sizeof(char *) + strlen_user(fun->arg[i].addr) :
					   is_arg_data  (&fun->arg[i])	   ?  (fun->arg[i].size > 8 ? fun->arg[i].size : 0 ) : 0;

				size += ALIGN(s, 8);
			}
		}
        }

        ret = kmalloc(size, GFP_KERNEL);
        if (ret == NULL) {
                printk(KERN_INFO "[PFQ] context_alloc: could not allocate %zu bytes!\n", size);
                return NULL;
        }

        pr_devel("[PFQ] context_alloc: %zu bytes allocated.\n", size);
        return ret;
}
Exemple #3
0
asmlinkage long sys_syscall(char __user *buf, int len){
	char message[200];
	if(strlen_user(buf) > 200){
		return -EINVAL;
	}
	copy_from_user(message, buf, strlen_user(buf));
	printk("syscall: %s\n", message);
	copy_to_user(buf, "It's alive", strlen("It's alive") + 1);
	return strlen("It's alive")+1;
}
Exemple #4
0
/**
 * Duplicate a string from user memory.
 *
 * Allocates a buffer large enough and copies across a string from user memory.
 * The allocation is not made using MM_WAIT, as there is no length limit and
 * therefore the length could be too large to fit in memory. Use of
 * strndup_from_user() is preferred to this.
 *
 * @param src		Location to copy from.
 * @param destp		Pointer to location in which to store address of
 *			destination buffer.
 *
 * @return		Status code describing result of the operation.
 *			Returns STATUS_INVALID_ARG if the string is
 *			zero-length.
 */
status_t strdup_from_user(const void *src, char **destp) {
	status_t ret;
	size_t len;
	char *d;

	ret = strlen_user(src, &len);
	if(ret != STATUS_SUCCESS) {
		return ret;
	} else if(len == 0) {
		return STATUS_INVALID_ARG;
	}

	d = kmalloc(len + 1, MM_USER);
	if(!d)
		return STATUS_NO_MEMORY;

	ret = memcpy_from_user(d, src, len);
	if(ret != STATUS_SUCCESS) {
		kfree(d);
		return ret;
	}
	d[len] = 0;
	*destp = d;
	return STATUS_SUCCESS;
}
Exemple #5
0
/**
 * FILE EXEC
 *
 * @v file_exec				Pointer to a struct s_PXENV_FILE_EXEC
 * @v s_PXENV_FILE_EXEC::Command	Command to execute
 * @ret #PXENV_EXIT_SUCCESS		Command was executed successfully
 * @ret #PXENV_EXIT_FAILURE		Command was not executed successfully
 * @ret s_PXENV_FILE_EXEC::Status	PXE status code
 *
 */
PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
	userptr_t command;
	size_t command_len;
	int rc;

	DBG ( "PXENV_FILE_EXEC" );

	/* Copy name from external program, and exec it */
	command = real_to_user ( file_exec->Command.segment,
				 file_exec->Command.offset );
	command_len = strlen_user ( command, 0 );
	{
		char command_string[ command_len + 1 ];

		copy_from_user ( command_string, command, 0,
				 sizeof ( command_string ) );
		DBG ( " %s", command_string );

		if ( ( rc = system ( command_string ) ) != 0 ) {
			file_exec->Status = PXENV_STATUS ( rc );
			return PXENV_EXIT_FAILURE;
		}
	}

	file_exec->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}
Exemple #6
0
asmlinkage long sys_my_set_state(char *the_string, int accumulator) {
	
	if (accumulator < 0) {
		return -EINVAL;
	}
	my_accumulator = accumulator;
	printk("\nReceived user value: %d\n", accumulator);
	printk("Value of my_accumulator set as: %d\n\n", my_accumulator);
	// accumulator is passed by value hence needs no locking or copy_from_user()
	unsigned int len_string = strlen_user(the_string);
	// zero out memory
	if (my_string)
        	kfree(my_string);
	// check if allocation fails
	if ((my_string = (char *) kmalloc(len_string, GFP_KERNEL)) == NULL) {
		return -EFAULT;
	}
	//check if copy fails
	if (copy_from_user(my_string, the_string, len_string))
    	{	
		kfree(my_string);
		return -EFAULT;
    	}
	//return success.
	printk("Succeeded in Copying.\n");
	printk("Received user string: %s\n", the_string);
	printk("\nValue of my_string set as: %s\n", my_string);
	return 0;
}
Exemple #7
0
/**
 * FILE OPEN
 *
 * @v file_open				Pointer to a struct s_PXENV_FILE_OPEN
 * @v s_PXENV_FILE_OPEN::FileName	URL of file to open
 * @ret #PXENV_EXIT_SUCCESS		File was opened
 * @ret #PXENV_EXIT_FAILURE		File was not opened
 * @ret s_PXENV_FILE_OPEN::Status	PXE status code
 * @ret s_PXENV_FILE_OPEN::FileHandle	Handle of opened file
 *
 */
PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) {
	userptr_t filename;
	size_t filename_len;
	int fd;

	DBG ( "PXENV_FILE_OPEN" );

	/* Copy name from external program, and open it */
	filename = real_to_user ( file_open->FileName.segment,
			      file_open->FileName.offset );
	filename_len = strlen_user ( filename, 0 );
	{
		char uri_string[ filename_len + 1 ];

		copy_from_user ( uri_string, filename, 0,
				 sizeof ( uri_string ) );
		DBG ( " %s", uri_string );
		fd = open ( uri_string );
	}

	if ( fd < 0 ) {
		file_open->Status = PXENV_STATUS ( fd );
		return PXENV_EXIT_FAILURE;
	}

	DBG ( " as file %d", fd );

	file_open->FileHandle = fd;
	file_open->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}
/**
 * Find indexed string within SMBIOS structure
 *
 * @v structure		SMBIOS structure descriptor
 * @v index		String index
 * @v data		Buffer for string
 * @v len		Length of string buffer
 * @ret rc		Length of string, or negative error
 */
int read_smbios_string ( struct smbios_structure *structure,
			 unsigned int index, void *data, size_t len ) {
	size_t strings_start = ( structure->offset + structure->header.len );
	size_t strings_end = ( strings_start + structure->strings_len );
	size_t offset;
	size_t string_len;

	assert ( smbios.address != UNULL );

	/* String numbers start at 1 (0 is used to indicate "no string") */
	if ( ! index )
		return -ENOENT;

	for ( offset = strings_start ; offset < strings_end ;
	      offset += ( string_len + 1 ) ) {
		/* Get string length.  This is known safe, since the
		 * smbios_strings struct is constructed so as to
		 * always end on a string boundary.
		 */
		string_len = strlen_user ( smbios.address, offset );
		if ( --index == 0 ) {
			/* Copy string, truncating as necessary. */
			if ( len > string_len )
				len = string_len;
			copy_from_user ( data, smbios.address, offset, len );
			return string_len;
		}
	}

	DBG ( "SMBIOS string index %d not found\n", index );
	return -ENOENT;
}
Exemple #9
0
/* hpux statfs */
int hpux_statfs(const char *path, struct hpux_statfs *buf)
{
	int error;
	int len;
	char *kpath;

	len = strlen_user((char *)path); 

	kpath = (char *) kmalloc(len+1, GFP_KERNEL);
	if ( !kpath ) {
	printk(KERN_DEBUG "failed to kmalloc kpath\n");
	return 0;
	}

	if ( copy_from_user(kpath, (char *)path, len+1) ) {
	printk(KERN_DEBUG "failed to copy_from_user kpath\n");
	kfree(kpath);
	return 0;
	}

	printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);

	kfree(kpath);

	/* just fake it, beginning of structures match */
	error = sys_statfs(path, (struct statfs *) buf);

	/* ignoring rest of statfs struct, but it should be zeros. Need to do 
		something with f_fsid[1], which is the fstype for sysfs */

	return error;
}
Exemple #10
0
int str2unistr(struct nls_table *nls, PUNICODE_STRING dst, char *src)
{
	int		len, i;
	int		ret = -ENOMEM;
	char		*ksrc, *p;
	wchar_t	*wc;

	if ((unsigned int) src > TASK_SIZE) {
		ksrc = src;
		len = strlen(src) + 1;
		goto ksrc_ready;
	}

	if (!src || !(len = strlen_user(src))) {
		dst->Length = 0;
		dst->MaximumLength = sizeof(wchar_t);
		dst->Buffer = (PWSTR)L"";
		return 0;
	}

	if (!(ksrc = kmalloc(len, GFP_KERNEL)))
		return ret;

	ret = -EFAULT;
	if (copy_from_user(ksrc, src, len))
		goto out_free_src;

ksrc_ready:
	dst->Length = 0;
	dst->MaximumLength = len * sizeof(wchar_t);
	dst->Buffer = kmalloc(dst->MaximumLength, GFP_KERNEL);
	ret = -ENOMEM;
	if (!dst->Buffer)
		goto out_free_src;

	wc = dst->Buffer;
	p = ksrc;
	while (p < ksrc + len - 1) {
		i = nls->char2uni(p, sizeof(wchar_t), wc++);
		if (i < 0) {
			ret = -EINVAL;
			goto out_free_dst;
		}
		p += i;
		dst->Length += sizeof(wchar_t);
	}
	*wc = L'\0';

	ret = 0;
	goto out_free_src;

out_free_dst:
	kfree(dst->Buffer);
out_free_src:
	if (ksrc != src)
		kfree(ksrc);

	return ret;
}
/*
* Saves extension list of media file
*/
asmlinkage long sys_set_media_ext(const char __user *mediaExtList)
{
	long len, rc = 0;
	uid_t uid;

	/* check uid if it's not root(0) nor system(1000) */
	uid = current_uid();
	if (check_uid(uid)) {
		printk(KERN_ERR "%s: %s(%u) not permitted.\n",
				__func__, current->comm, uid);
		return -EPERM;
	}

	mutex_lock(&media_ext_list_lock);
	/*
	*   The media file extension list set on each boot-up time
	*   and never set again while runtime. is_savedfileExtList_set
	*   is a global flag to check whether the list has been set or not.
	*   If it's already set, this function just return 0 for success.
	*/
	if (is_savedfileExtList_set) {
		printk(KERN_INFO "%s: the file list already set.\n", __func__);
		goto out;
	}

	/* check if mediaExtList is not userspace */
	if (!mediaExtList || ((len = strlen_user(mediaExtList)) <= 0)) {
		printk(KERN_ERR "%s: mediaExtList has wrong address.\n", __func__);
		rc = -EFAULT;
		goto out;
	}

	/* check overflow */
	if (len >= MAX_MEDIA_EXT_LENGTH) {
		printk(KERN_ERR "%s: mediaExtList is too large.\n", __func__);
		rc = -EOVERFLOW;
		goto out;
	}

	memset(savedfileExtList, 0, sizeof(savedfileExtList));
	rc = strncpy_from_user(savedfileExtList, mediaExtList, len);

	if (rc == -EFAULT) {
		printk(KERN_ERR "%s: access to userspace failed.\n", __func__);
		goto out;
	}

	is_savedfileExtList_set = true;
	/* set return value 0 for success */
	rc = 0;

	/* for debuging */
	/* printk("%s :: savedfileExtList(%d bytes): %s\n",
			__func__, strlen(savedfileExtList), savedfileExtList); */

out:
	mutex_unlock(&media_ext_list_lock);
	return rc;
}
Exemple #12
0
/**
 * Initialise command line
 *
 * @ret rc		Return status code
 */
static int cmdline_init ( void ) {
	userptr_t cmdline_user;
	char *cmdline;
	size_t len;
	int rc;

	/* Do nothing if no command line was specified */
	if ( ! cmdline_phys ) {
		DBGC ( colour, "RUNTIME found no command line\n" );
		return 0;
	}
	cmdline_user = phys_to_user ( cmdline_phys );
	len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );

	/* Allocate and copy command line */
	cmdline_copy = malloc ( len );
	if ( ! cmdline_copy ) {
		DBGC ( colour, "RUNTIME could not allocate %zd bytes for "
		       "command line\n", len );
		rc = -ENOMEM;
		goto err_alloc_cmdline_copy;
	}
	cmdline = cmdline_copy;
	copy_from_user ( cmdline, cmdline_user, 0, len );
	DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n",
	       cmdline, cmdline_phys );

	/* Mark command line as consumed */
	cmdline_phys = 0;

	/* Strip unwanted cruft from the command line */
	cmdline_strip ( cmdline, "BOOT_IMAGE=" );
	cmdline_strip ( cmdline, "initrd=" );
	while ( isspace ( *cmdline ) )
		cmdline++;
	DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline );

	/* Prepare and register image */
	cmdline_image.data = virt_to_user ( cmdline );
	cmdline_image.len = strlen ( cmdline );
	if ( cmdline_image.len ) {
		if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) {
			DBGC ( colour, "RUNTIME could not register command "
			       "line: %s\n", strerror ( rc ) );
			goto err_register_image;
		}
	}

	/* Drop our reference to the image */
	image_put ( &cmdline_image );

	return 0;

 err_register_image:
	image_put ( &cmdline_image );
 err_alloc_cmdline_copy:
	return rc;
}
Exemple #13
0
static void create_som_tables(struct linux_binprm *bprm)
{
    char **argv, **envp;
    int argc = bprm->argc;
    int envc = bprm->envc;
    unsigned long p;
    unsigned long *sp;

    /* Word-align the stack pointer */
    sp = (unsigned long *)((bprm->p + 3) & ~3);

    envp = (char **) sp;
    sp += envc + 1;
    argv = (char **) sp;
    sp += argc + 1;

    __put_user((unsigned long) envp,++sp);
    __put_user((unsigned long) argv,++sp);

    __put_user(argc, ++sp);

    bprm->p = (unsigned long) sp;

    p = current->mm->arg_start;
    while (argc-- > 0) {
        __put_user((char *)p,argv++);
        p += strlen_user((char *)p);
    }
    __put_user(NULL, argv);
    current->mm->arg_end = current->mm->env_start = p;
    while (envc-- > 0) {
        __put_user((char *)p,envp++);
        p += strlen_user((char *)p);
    }
    __put_user(NULL, envp);
    current->mm->env_end = p;
}
int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
{
	char *fsname = NULL;
	int len = 0;
	int fstype;

/*Unimplemented HP-UX syscall emulation. Syscall #334 (sysfs)
  Args: 1 80057bf4 0 400179f0 0 0 0 */
	printk(KERN_DEBUG "in hpux_sysfs\n");
	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);

	if ( opcode == 1 ) { /* GETFSIND */
		char __user *user_fsname = (char __user *)arg1;
		len = strlen_user(user_fsname);
		printk(KERN_DEBUG "len of arg1 = %d\n", len);
		if (len == 0)
			return 0;
		fsname = kmalloc(len, GFP_KERNEL);
		if (!fsname) {
			printk(KERN_DEBUG "failed to kmalloc fsname\n");
			return 0;
		}

		if (copy_from_user(fsname, user_fsname, len)) {
			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
			kfree(fsname);
			return 0;
		}

		/* String could be altered by userspace after strlen_user() */
		fsname[len] = '\0';

		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
		if ( !strcmp(fsname, "hfs") ) {
			fstype = 0;
		} else {
			fstype = 0;
		}

		kfree(fsname);

		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
		return fstype; /* something other than default */
	}


	return 0;
}
Exemple #15
0
int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
{
	char *fsname = NULL;
	int len = 0;
	int fstype;

	printk(KERN_DEBUG "in hpux_sysfs\n");
	printk(KERN_DEBUG "hpux_sysfs called with opcode = %d\n", opcode);
	printk(KERN_DEBUG "hpux_sysfs called with arg1='%lx'\n", arg1);

	if ( opcode == 1 ) { 	
		char __user *user_fsname = (char __user *)arg1;
		len = strlen_user(user_fsname);
		printk(KERN_DEBUG "len of arg1 = %d\n", len);
		if (len == 0)
			return 0;
		fsname = kmalloc(len, GFP_KERNEL);
		if (!fsname) {
			printk(KERN_DEBUG "failed to kmalloc fsname\n");
			return 0;
		}

		if (copy_from_user(fsname, user_fsname, len)) {
			printk(KERN_DEBUG "failed to copy_from_user fsname\n");
			kfree(fsname);
			return 0;
		}

		
		fsname[len] = '\0';

		printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
		if ( !strcmp(fsname, "hfs") ) {
			fstype = 0;
		} else {
			fstype = 0;
		}

		kfree(fsname);

		printk(KERN_DEBUG "returning fstype=%d\n", fstype);
		return fstype; 
	}


	return 0;
}
Exemple #16
0
static int set_wait_image_load_name(char *path)
{
	unsigned int length;

	length = strlen_user(path);

	if (length > PATH_MAX)
		return -EINVAL;

	if (strncpy_from_user(g_image_load_path, path, length) == -EFAULT)
	{
		return -EFAULT;
	}

	g_is_image_load_set = true;

	return 0;
}
Exemple #17
0
char *
strdup_user(const char __user *str)
{
        size_t len = strlen_user(str);
        char *ret;

        if (len == 0)
                return NULL;

        ret = (char *)kmalloc(len, GFP_KERNEL);
        if (!ret)
                return NULL;
        if (copy_from_user(ret, str, len)) {
                kfree(ret);
                return NULL;
        }
        return ret;
}
u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
{
    u32 ret;
    struct dsp_uuid uuid_obj;
    u32 path_size = 0;
    char *psz_path_name = NULL;
    int status = 0;

    CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
    if (status)
        goto func_end;

    path_size = strlen_user((char *)
                            args->args_mgr_registerobject.sz_path_name) +
                1;
    psz_path_name = kmalloc(path_size, GFP_KERNEL);
    if (!psz_path_name) {
        status = -ENOMEM;
        goto func_end;
    }
    ret = strncpy_from_user(psz_path_name,
                            (char *)args->args_mgr_registerobject.
                            sz_path_name, path_size);
    if (!ret) {
        status = -EFAULT;
        goto func_end;
    }

    if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) {
        status = -EINVAL;
        goto func_end;
    }

    status = dcd_register_object(&uuid_obj,
                                 args->args_mgr_registerobject.obj_type,
                                 (char *)psz_path_name);
func_end:
    kfree(psz_path_name);
    return status;
}
Exemple #19
0
/*
 * Function that takes a user path and
 * converts it to a kernel space string
 * Remember to free the memory allocated here
 * in the function that calls this function
 */
char *my_get_from_user(const char * const dirname)
{
    int ret = 0;
    char *ret_val = NULL;
    int ipLen = 0;

    /*
     * Verify if we have access to
     * the pointers
     */
    ret = access_ok(VERIFY_READ, dirname, 0);
    if (!ret) {
        ret = -EFAULT;
        goto OUT;
    }

    ipLen = strlen_user(dirname);
    ret_val = kmalloc(ipLen, GFP_KERNEL);
    if (NULL == ret_val) {
        ret = -ENOMEM;
        goto OUT;
    } else {
        ret = strncpy_from_user(ret_val, dirname, ipLen);
        if (ret < 0) {
            goto OUT;
        }
    }

OUT:
    if (ret < 0) {
        if (ret_val) {
            kfree(ret_val);
            ret_val = NULL;
        }
    }

    return ret_val;
}
Exemple #20
0
/**
 * Duplicate a string from user memory.
 *
 * Allocates a buffer large enough and copies across a string from user memory.
 * If the string is longer than the maximum length, then an error will be
 * returned. Because a length limit is provided, the allocation is made using
 * MM_WAIT - it is assumed that the limit is sensible.
 *
 * @param src		Location to copy from.
 * @param max		Maximum length allowed.
 * @param destp		Pointer to location in which to store address of
 *			destination buffer.
 *
 * @return		Status code describing result of the operation.
 *			Returns STATUS_INVALID_ARG if the string is
 *			zero-length.
 */
status_t strndup_from_user(const void *src, size_t max, char **destp) {
	status_t ret;
	size_t len;
	char *d;

	ret = strlen_user(src, &len);
	if(ret != STATUS_SUCCESS) {
		return ret;
	} else if(len == 0) {
		return STATUS_INVALID_ARG;
	} else if(len > max) {
		return STATUS_TOO_LONG;
	}

	d = kmalloc(len + 1, MM_KERNEL);
	ret = memcpy_from_user(d, src, len);
	if(ret != STATUS_SUCCESS) {
		kfree(d);
		return ret;
	}
	d[len] = 0;
	*destp = d;
	return STATUS_SUCCESS;
}
Exemple #21
0
/*
 * ======== MGRWRAP_RegisterObject ========
 */
u32 MGRWRAP_RegisterObject(union Trapped_Args *args, void *pr_ctxt)
{
	u32 retVal;
	struct DSP_UUID pUuid;
	u32 pathSize = 0;
	char *pszPathName = NULL;
	DSP_STATUS status = DSP_SOK;

	cp_fm_usr(&pUuid, args->ARGS_MGR_REGISTEROBJECT.pUuid, status, 1);
	if (DSP_FAILED(status))
		goto func_end;
	/* pathSize is increased by 1 to accommodate NULL */
	pathSize = strlen_user((char *)
			args->ARGS_MGR_REGISTEROBJECT.pszPathName) + 1;
	pszPathName = MEM_Alloc(pathSize, MEM_NONPAGED);
	if (!pszPathName)
		goto func_end;
	retVal = strncpy_from_user(pszPathName,
			(char *)args->ARGS_MGR_REGISTEROBJECT.pszPathName,
			pathSize);
	if (!retVal) {
		status = DSP_EPOINTER;
		goto func_end;
	}

	GT_1trace(WCD_debugMask, GT_ENTER,
		 "MGRWRAP_RegisterObject: entered pg2hMsg "
		 "0x%x\n", args->ARGS_MGR_REGISTEROBJECT.pUuid);
	status = DCD_RegisterObject(&pUuid,
				args->ARGS_MGR_REGISTEROBJECT.objType,
				(char *)pszPathName);
func_end:
	if (pszPathName)
		MEM_Free(pszPathName);
	return status;
}
Exemple #22
0
/*
 * ======== PROCWRAP_Load ========
 */
u32 PROCWRAP_Load(union Trapped_Args *args, void *pr_ctxt)
{
	s32 i, len;
	DSP_STATUS status = DSP_SOK;
	char *temp;
	s32 count = args->ARGS_PROC_LOAD.iArgc;
	u8 **argv, **envp = NULL;

	DBC_Require(count > 0);
	DBC_Require(count <= MAX_LOADARGS);

	argv = MEM_Alloc(count * sizeof(u8 *), MEM_NONPAGED);
	if (!argv) {
		status = DSP_EMEMORY;
		goto func_cont;
	}

	cp_fm_usr(argv, args->ARGS_PROC_LOAD.aArgv, status, count);
	if (DSP_FAILED(status)) {
		MEM_Free(argv);
		argv = NULL;
		goto func_cont;
	}

	for (i = 0; i < count; i++) {
		if (argv[i]) {
			/* User space pointer to argument */
			temp = (char *) argv[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			argv[i] = MEM_Alloc(len, MEM_NONPAGED);
			if (argv[i]) {
				cp_fm_usr(argv[i], temp, status, len);
				if (DSP_FAILED(status)) {
					MEM_Free(argv[i]);
					argv[i] = NULL;
					goto func_cont;
				}
			} else {
				status = DSP_EMEMORY;
				goto func_cont;
			}
		}
	}
	/* TODO: validate this */
	if (args->ARGS_PROC_LOAD.aEnvp) {
		/* number of elements in the envp array including NULL */
		count = 0;
		do {
			get_user(temp, args->ARGS_PROC_LOAD.aEnvp + count);
			count++;
		} while (temp);
		envp = MEM_Alloc(count * sizeof(u8 *), MEM_NONPAGED);
		if (!envp) {
			status = DSP_EMEMORY;
			goto func_cont;
		}

		cp_fm_usr(envp, args->ARGS_PROC_LOAD.aEnvp, status, count);
		if (DSP_FAILED(status)) {
			MEM_Free(envp);
			envp = NULL;
			goto func_cont;
		}
		for (i = 0; envp[i]; i++) {
			/* User space pointer to argument */
			temp = (char *)envp[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			envp[i] = MEM_Alloc(len, MEM_NONPAGED);
			if (envp[i]) {
				cp_fm_usr(envp[i], temp, status, len);
				if (DSP_FAILED(status)) {
					MEM_Free(envp[i]);
					envp[i] = NULL;
					goto func_cont;
				}
			} else {
				status = DSP_EMEMORY;
				goto func_cont;
			}
		}
	}
	GT_5trace(WCD_debugMask, GT_ENTER,
		"PROCWRAP_Load, hProcessor: 0x%x\n\tiArgc:"
		"0x%x\n\taArgv: 0x%x\n\taArgv[0]: %s\n\taEnvp: 0x%0x\n",
		args->ARGS_PROC_LOAD.hProcessor,
		args->ARGS_PROC_LOAD.iArgc, args->ARGS_PROC_LOAD.aArgv,
		argv[0], args->ARGS_PROC_LOAD.aEnvp);
	if (DSP_SUCCEEDED(status)) {
		status = PROC_Load(args->ARGS_PROC_LOAD.hProcessor,
				args->ARGS_PROC_LOAD.iArgc,
				(CONST char **)argv, (CONST char **)envp);
	}
func_cont:
	if (envp) {
		i = 0;
		while (envp[i])
			MEM_Free(envp[i++]);

		MEM_Free(envp);
	}

	if (argv) {
		count = args->ARGS_PROC_LOAD.iArgc;
		for (i = 0; (i < count) && argv[i]; i++)
			MEM_Free(argv[i]);

		MEM_Free(argv);
	}

	return status;
}
u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
    s32 i, len;
    int status = 0;
    char *temp;
    s32 count = args->args_proc_load.argc_index;
    u8 **argv = NULL, **envp = NULL;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

    if (count <= 0 || count > MAX_LOADARGS) {
        status = -EINVAL;
        goto func_cont;
    }

    argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
    if (!argv) {
        status = -ENOMEM;
        goto func_cont;
    }

    CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
    if (status) {
        kfree(argv);
        argv = NULL;
        goto func_cont;
    }

    for (i = 0; i < count; i++) {
        if (argv[i]) {

            temp = (char *)argv[i];

            len = strlen_user((char *)temp) + 1;

            argv[i] = kmalloc(len, GFP_KERNEL);
            if (argv[i]) {
                CP_FM_USR(argv[i], temp, status, len);
                if (status) {
                    kfree(argv[i]);
                    argv[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (args->args_proc_load.user_envp) {

        count = 0;
        do {
            if (get_user(temp,
                         args->args_proc_load.user_envp + count)) {
                status = -EFAULT;
                goto func_cont;
            }
            count++;
        } while (temp);
        envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
        if (!envp) {
            status = -ENOMEM;
            goto func_cont;
        }

        CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
        if (status) {
            kfree(envp);
            envp = NULL;
            goto func_cont;
        }
        for (i = 0; envp[i]; i++) {

            temp = (char *)envp[i];

            len = strlen_user((char *)temp) + 1;

            envp[i] = kmalloc(len, GFP_KERNEL);
            if (envp[i]) {
                CP_FM_USR(envp[i], temp, status, len);
                if (status) {
                    kfree(envp[i]);
                    envp[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (!status) {
        status = proc_load(hprocessor,
                           args->args_proc_load.argc_index,
                           (const char **)argv, (const char **)envp);
    }
func_cont:
    if (envp) {
        i = 0;
        while (envp[i])
            kfree(envp[i++]);

        kfree(envp);
    }

    if (argv) {
        count = args->args_proc_load.argc_index;
        for (i = 0; (i < count) && argv[i]; i++)
            kfree(argv[i]);

        kfree(argv);
    }

    return status;
}
Exemple #24
0
/****************************************************************************
 * Comment here was all wrong
 * Return value is 0 on success or negative on failure
 * XXX This stuff needs modifying to handle variable size display  (apparently)
 ****************************************************************************/
static int call_draw_screen(char **upupcTextFromUser,
                            int iX,
                            int iY,
                            int iCursorType,
                            int iCursorWidth,
                            int *upiArrows,
                            int *upiLineContents)
{
  spin_lock(&redraw_lock);

  int iRow, iStringLength;
  char *aupcTempPointerArray[iHeight];
 
  /* arrows */
  if (!upiArrows)
  {
    printk(KERN_ERR "Got NULL from upiArrows\n");
    return -EFAULT;
  }

  if (copy_from_user(piArrows, upiArrows, sizeof(int) * iHeight))
  {
    printk(KERN_ERR "Error drawing LCD Display, could not copy arrows array\n");
    return -EFAULT;
  }

  /* line contents */
  if (!upiLineContents)
  {
    printk(KERN_ERR "Got null from upiLineContents\n");
    return -EFAULT;
  }

  if (copy_from_user(piLineContents, upiLineContents,
                     sizeof(int) * iHeight))
  {
    printk(KERN_ERR "Error drawing LCD Display, could not copy line contents array\n");
    return -EFAULT;
  }

  /* text, first level */
  if (copy_from_user(aupcTempPointerArray,
                     upupcTextFromUser, 
                     sizeof(char *) * iHeight))
  {
    printk(KERN_ERR "Error drawing LCD Display, could not copy string array pointer\n");     
    return -EFAULT;
  }
 
  /* text, second level */
  for (iRow = 0; iRow < iHeight; iRow++)
  {
    iStringLength = strlen_user(aupcTempPointerArray[iRow]);

    if (ppcTexts[iRow])
      kfree(ppcTexts[iRow]);
     
    if (!(ppcTexts[iRow] = kmalloc(iStringLength + 1, GFP_KERNEL)))
    {
      printk(KERN_ERR "Error drawing LCD Display, could not allocate memory at row %d\n", iRow);
      return -ENOMEM;
    }
        
    if (copy_from_user(ppcTexts[iRow], aupcTempPointerArray[iRow], 
                       sizeof(char) * (iStringLength+1)))
    {
      printk(KERN_ERR "Error drawing LCD Display, could not copy string at row %d\n", iRow);
      return -EFAULT;
    }
  }

  /* send to driver */
  iXcoord = iX;
  iYcoord = iY;
  iCursorTypeGlobal = iCursorType;
  iCursorWidthGlobal = iCursorWidth;
  int ret = driver->draw_screen(ppcTexts, iX, iY, iCursorType, iCursorWidth,
                                piArrows, piLineContents);

  spin_unlock(&redraw_lock);
  return ret;
}
Exemple #25
0
int
pfq_computation_rtlink(struct pfq_computation_descr const *descr, struct pfq_computation_tree *comp, void *context)
{
	size_t n;

        /* size */

        comp->size = descr->size;

        /* entry point */

        comp->entry_point = &comp->node[descr->entry_point];

	/* link functions */

        for(n = 0; n < descr->size; n++)
        {
		struct pfq_functional_descr const *fun;
		struct pfq_functional_node *next;
		const char *signature;
		init_ptr_t init, fini;
		void *addr;
                size_t i;

                fun = &descr->fun[n];

		addr = resolve_user_symbol(&pfq_lang_functions, fun->symbol, &signature, &init, &fini);
		if (addr == NULL) {
			printk(KERN_INFO "[PFQ] %zu: rtlink: bad descriptor!\n", n);
			return -EPERM;
		}

		next = get_functional_node_by_index(descr, comp, descr->fun[n].next);

		comp->node[n].init    = init;
		comp->node[n].fini    = fini;

		comp->node[n].fun.run  = addr;
                comp->node[n].fun.next = next ? &next->fun : NULL;

		comp->node[n].fun.arg[0].value = 0;
		comp->node[n].fun.arg[1].value = 0;
		comp->node[n].fun.arg[2].value = 0;
		comp->node[n].fun.arg[3].value = 0;

		comp->node[n].fun.arg[0].nelem = 0;
		comp->node[n].fun.arg[1].nelem = 0;
		comp->node[n].fun.arg[2].nelem = 0;
		comp->node[n].fun.arg[3].nelem = 0;

		for(i = 0; i < sizeof(fun->arg)/sizeof(fun->arg[0]); i++)
		{
			if (is_arg_string(&fun->arg[i])) {

				char *str = pod_user(&context, fun->arg[i].addr, strlen_user(fun->arg[i].addr));
				if (str == NULL) {
					printk(KERN_INFO "[PFQ] %zu: pod_user(1): internal error!\n", n);
					return -EPERM;
				}

				comp->node[n].fun.arg[i].value = (ptrdiff_t)str;
				comp->node[n].fun.arg[i].nelem = -1;
			}
			else if (is_arg_vector_str(&fun->arg[i])) {

				char **base_ptr, **ptr;
				char *str;
				size_t j;

				base_ptr = ptr = (char **)context;

				context += sizeof(char *) * fun->arg[i].nelem;

				str = pod_user(&context, fun->arg[i].addr, strlen_user(fun->arg[i].addr));
				if (str == NULL) {
					printk(KERN_INFO "[PFQ] %zu: pod_user(2): internal error!\n", n);
					return -EPERM;
				}

				for(j = 0; j < fun->arg[i].nelem; j++)
				{
					char *end;
					*(ptr++) = str;
					end = strchr(str, '\x1e');
					if (end == NULL)
						break;
					*end = '\0';
					str = end+1;
				}

				comp->node[n].fun.arg[i].value = (ptrdiff_t)base_ptr;
				comp->node[n].fun.arg[i].nelem = fun->arg[i].nelem;
			}
			else if (is_arg_data(&fun->arg[i])) {

				if (fun->arg[i].size > 8) {

					char *ptr = pod_user(&context, fun->arg[i].addr, fun->arg[i].size);
					if (ptr == NULL) {
						printk(KERN_INFO "[PFQ] %zu: pod_user(3): internal error!\n", n);
						return -EPERM;
					}

					comp->node[n].fun.arg[i].value = (ptrdiff_t)ptr;
					comp->node[n].fun.arg[i].nelem = -1;
				}
				else {
					ptrdiff_t arg = 0;

					if (copy_from_user(&arg, fun->arg[i].addr, fun->arg[i].size)) {
						printk(KERN_INFO "[PFQ] %zu: copy_from_user: internal error!\n", n);
						return -EPERM;
					}

					comp->node[n].fun.arg[i].value = arg;
					comp->node[n].fun.arg[i].nelem = -1;
				}

			}
			else if (is_arg_vector(&fun->arg[i])) {

				if (fun->arg[i].nelem > 0) {

					char *ptr = pod_user(&context, fun->arg[i].addr,
							     fun->arg[i].size * fun->arg[i].nelem);
					if (ptr == NULL) {
						printk(KERN_INFO "[PFQ] %zu: pod_user(4): internal error!\n", n);
						return -EPERM;
					}

					comp->node[n].fun.arg[i].value = (ptrdiff_t)ptr;
					comp->node[n].fun.arg[i].nelem = fun->arg[i].nelem;
				}
				else {  /* empty vector */

					comp->node[n].fun.arg[i].value = 0xdeadbeef;
					comp->node[n].fun.arg[i].nelem = 0;
				}
			}
			else if (is_arg_function(&fun->arg[i])) {

				comp->node[n].fun.arg[i].value = (ptrdiff_t)get_functional_node_by_index(descr, comp,
													fun->arg[i].size);
				comp->node[n].fun.arg[i].nelem = -1;
			}
			else if (!is_arg_null(&fun->arg[i])) {

				printk(KERN_INFO "[PFQ] pfq_computation_rtlink: internal error@ function:%zu argument[%zu] => { %p, %zu, %zu }!\n",
				       n, i, (void __user *)fun->arg[i].addr, fun->arg[i].size, fun->arg[i].nelem);
				return -EPERM;
			}
		}
	}

	return 0;
}
/*
 * ======== procwrap_load ========
 */
u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
	s32 i, len;
	int status = 0;
	char *temp;
	s32 count = args->args_proc_load.argc_index;
	u8 **argv = NULL, **envp = NULL;
	void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

	if (count <= 0 || count > MAX_LOADARGS) {
		status = -EINVAL;
		goto func_cont;
	}

	argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
	if (!argv) {
		status = -ENOMEM;
		goto func_cont;
	}

	CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
	if (status) {
		kfree(argv);
		argv = NULL;
		goto func_cont;
	}

	for (i = 0; i < count; i++) {
		if (argv[i]) {
			/* User space pointer to argument */
			temp = (char *)argv[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			argv[i] = kmalloc(len, GFP_KERNEL);
			if (argv[i]) {
				CP_FM_USR(argv[i], temp, status, len);
				if (status) {
					kfree(argv[i]);
					argv[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}
	/* TODO: validate this */
	if (args->args_proc_load.user_envp) {
		/* number of elements in the envp array including NULL */
		count = 0;
		do {
			if (get_user(temp,
				     args->args_proc_load.user_envp + count)) {
				status = -EFAULT;
				goto func_cont;
			}
			count++;
		} while (temp);
		envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
		if (!envp) {
			status = -ENOMEM;
			goto func_cont;
		}

		CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
		if (status) {
			kfree(envp);
			envp = NULL;
			goto func_cont;
		}
		for (i = 0; envp[i]; i++) {
			/* User space pointer to argument */
			temp = (char *)envp[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			envp[i] = kmalloc(len, GFP_KERNEL);
			if (envp[i]) {
				CP_FM_USR(envp[i], temp, status, len);
				if (status) {
					kfree(envp[i]);
					envp[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}

	if (!status) {
		status = proc_load(hprocessor,
				   args->args_proc_load.argc_index,
				   (const char **)argv, (const char **)envp);
	}
func_cont:
	if (envp) {
		i = 0;
		while (envp[i])
			kfree(envp[i++]);

		kfree(envp);
	}

	if (argv) {
		count = args->args_proc_load.argc_index;
		for (i = 0; (i < count) && argv[i]; i++)
			kfree(argv[i]);

		kfree(argv);
	}

	return status;
}
Exemple #27
0
static int draw_progress_simple(struct lcd_draw_progress_simple *dps)
{
  int ret = -ENOMEM;
  char **ppcText = NULL;
  char *pcText;
  int height, width, i = 0, percent;
  int draw_progress = 1;
  int line_len;
  /* Beware: the following variables are in danger of shadowing file-static
   * vars with similar names */
  int *arrows = NULL, *line_contents = NULL;

  if (dps->iHighest <= dps->iLowest)
    return -EINVAL;

  if (dps->iProgress < dps->iLowest || dps->iProgress > dps->iHighest)
    draw_progress = 0;

  percent = (dps->iProgress * 100)/(dps->iHighest - dps->iLowest);

  height = driver->get_height();
  width = driver->get_width();

  /* set up arrows and line contents */
  if ((arrows = kmalloc(height * sizeof(int), GFP_KERNEL)) == NULL)
    goto exit;
  if ((line_contents = kmalloc(height * sizeof(int), GFP_KERNEL)) == NULL)
    goto exit;

  for (i = 0; i < height; ++i)
  {
    arrows[i] = LCD_ARROW_NONE;
    line_contents[i] = LCD_LINE_CONTENTS_TEXT;
  }

  /* set up strings */
  ppcText = kmalloc(height * sizeof(char *), GFP_KERNEL);
  if (!ppcText)
    goto exit;

  i = strlen_user(dps->pcHeading) + 1;

  if (!(pcText = kmalloc(i, GFP_KERNEL)))
    goto exit;

  if (copy_from_user(pcText, dps->pcHeading, i))
  {
    ret = -EFAULT;
    goto exit;
  }

  if (height == 1 && draw_progress) 
  {
    line_len = i + 5; /* Space for ' 100%' */

    if (!(ppcText[0] = kmalloc(line_len + 1, GFP_KERNEL)))
    {
      kfree(pcText);
      goto exit;
    }

    sprintf(ppcText[0], "%s %02d%%", pcText, percent);
    ppcText[0][line_len] = '\0';
    kfree(pcText);
  } 
  else
  {
    ppcText[0] = pcText;

    if (draw_progress) 
    {
      if (!(ppcText[1] = kmalloc(5, GFP_KERNEL)))
        goto exit;
      sprintf(ppcText[1], "%02d%%", percent);
    }
    else 
    {
      ppcText[1] = "";
    }

    for (i = 2; i < height; ++i)
      ppcText[i] = "";
  }

  ret = driver->draw_screen(ppcText, 0, 0, LCD_CURSOR_OFF, 0,
                            arrows, line_contents);

exit:
  if (ppcText)
  {
    if (ppcText[0])
      kfree(ppcText[0]);
    if (height > 1 && draw_progress)
      kfree(ppcText[1]);
    kfree(ppcText);
  }
  return ret;
}
Exemple #28
0
static unsigned long * create_irix_tables(char * p, int argc, int envc,
	struct elfhdr * exec, unsigned int load_addr,
	unsigned int interp_load_addr, struct pt_regs *regs,
	struct elf_phdr *ephdr)
{
	elf_addr_t *argv;
	elf_addr_t *envp;
	elf_addr_t *sp, *csp;

	pr_debug("create_irix_tables: p[%p] argc[%d] envc[%d] "
	         "load_addr[%08x] interp_load_addr[%08x]\n",
	         p, argc, envc, load_addr, interp_load_addr);

	sp = (elf_addr_t *) (~15UL & (unsigned long) p);
	csp = sp;
	csp -= exec ? DLINFO_ITEMS*2 : 2;
	csp -= envc+1;
	csp -= argc+1;
	csp -= 1;		/* argc itself */
	if ((unsigned long)csp & 15UL) {
		sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp);
	}

	/*
	 * Put the ELF interpreter info on the stack
	 */
#define NEW_AUX_ENT(nr, id, val) \
	  __put_user((id), sp+(nr*2)); \
	  __put_user((val), sp+(nr*2+1)); \

	sp -= 2;
	NEW_AUX_ENT(0, AT_NULL, 0);

	if (exec) {
		sp -= 11*2;

		NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
		NEW_AUX_ENT(1, AT_PHENT, sizeof(struct elf_phdr));
		NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
		NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
		NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
		NEW_AUX_ENT(5, AT_FLAGS, 0);
		NEW_AUX_ENT(6, AT_ENTRY, (elf_addr_t) exec->e_entry);
		NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
		NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
		NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
		NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
	}
#undef NEW_AUX_ENT

	sp -= envc+1;
	envp = sp;
	sp -= argc+1;
	argv = sp;

	__put_user((elf_addr_t)argc, --sp);
	current->mm->arg_start = (unsigned long) p;
	while (argc-->0) {
		__put_user((unsigned long)p, argv++);
		p += strlen_user(p);
	}
	__put_user((unsigned long) NULL, argv);
	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
	while (envc-->0) {
		__put_user((unsigned long)p, envp++);
		p += strlen_user(p);
	}
	__put_user((unsigned long) NULL, envp);
	current->mm->env_end = (unsigned long) p;
	return sp;
}
Exemple #29
0
asmlinkage int
sys_sysmips(int cmd, int arg1, int arg2, int arg3)
{
	int	*p;
	char	*name;
	int	flags, tmp, len, retval;

	lock_kernel();
	switch(cmd)
	{
	case SETNAME:
		retval = -EPERM;
		if (!capable(CAP_SYS_ADMIN))
			goto out;

		name = (char *) arg1;
		len = strlen_user(name);

		retval = len;
		if (len < 0)
			goto out;

		retval = -EINVAL;
		if (len == 0 || len > __NEW_UTS_LEN)
			goto out;

		copy_from_user(system_utsname.nodename, name, len);
		system_utsname.nodename[len] = '\0';
		retval = 0;
		goto out;

	case MIPS_ATOMIC_SET:
	/* This is page-faults safe */
	{ 
		static volatile int lock = 0;
		static struct wait_queue *wq = NULL;

		struct wait_queue wait = { current, NULL };
		int retry = 0;

		p = (int *) arg1;
		current->state = TASK_INTERRUPTIBLE;
		add_wait_queue(&wq, &wait);
		while (lock) {
			if (retry > 20) break;
			retry ++;

			if (signal_pending(current)) {
				remove_wait_queue(&wq, &wait);
				current->state = TASK_RUNNING;
				retval =   -EINTR;
				goto out;
			}
			schedule();
			current->state = TASK_INTERRUPTIBLE;
		}
		remove_wait_queue (&wq, &wait);
		current->state = TASK_RUNNING;

		if (lock) {
			retval = -EAGAIN;
			goto out;
		}
		lock ++;

		retval = verify_area(VERIFY_WRITE, p, sizeof(*p));
		if (retval) {
			goto out_atomic_set;
		}

		/* swap *p and arg2, this cause possibly page faults */
		if (__get_user(retval, p)) {
			retval = -EFAULT;
			goto out_atomic_set;
		}
		__put_user(arg2, p);

	out_atomic_set:
		lock --;
		wake_up_interruptible(&wq);
		goto out;
	}

	case MIPS_FIXADE:
		tmp = current->tss.mflags & ~3;
		current->tss.mflags = tmp | (arg1 & 3);
		retval = 0;
		goto out;

	case FLUSH_CACHE:
		flush_cache_all();
		retval = 0;
		goto out;

	case MIPS_RDNVRAM:
		retval = -EIO;
		goto out;
#ifdef CONFIG_CPU_R5900
	case MIPS_SYS_R5900:
		retval = mips_sys_r5900(arg1, arg2, arg3);
		goto out;
#endif
	default:
		retval = -EINVAL;
		goto out;
	}

out:
	unlock_kernel();
	return retval;
}
Exemple #30
0
static elf_addr_t * 
create_elf_tables(char *p, int argc, int envc,
		  struct elfhdr * exec,
		  unsigned long load_addr,
		  unsigned long load_bias,
		  unsigned long interp_load_addr, int ibcs)
{
	elf_caddr_t *argv;
	elf_caddr_t *envp;
	elf_addr_t *sp, *csp;
	char *k_platform, *u_platform;
	long hwcap;
	size_t platform_len = 0;

	/*
	 * Get hold of platform and hardware capabilities masks for
	 * the machine we are running on.  In some cases (Sparc), 
	 * this info is impossible to get, in others (i386) it is
	 * merely difficult.
	 */

	hwcap = ELF_HWCAP;
	k_platform = ELF_PLATFORM;

	if (k_platform) {
		platform_len = strlen(k_platform) + 1;
		u_platform = p - platform_len;
		__copy_to_user(u_platform, k_platform, platform_len);
	} else
		u_platform = p;

	/*
	 * Force 16 byte _final_ alignment here for generality.
	 * Leave an extra 16 bytes free so that on the PowerPC we
	 * can move the aux table up to start on a 16-byte boundary.
	 */
	sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
	csp = sp;
	csp -= ((exec ? DLINFO_ITEMS*2 : 4) + (k_platform ? 2 : 0));
	csp -= envc+1;
	csp -= argc+1;
	csp -= (!ibcs ? 3 : 1);	/* argc itself */
	if ((unsigned long)csp & 15UL)
		sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);

	/*
	 * Put the ELF interpreter info on the stack
	 */
#define NEW_AUX_ENT(nr, id, val) \
	  __put_user ((id), sp+(nr*2)); \
	  __put_user ((val), sp+(nr*2+1)); \

	sp -= 2;
	NEW_AUX_ENT(0, AT_NULL, 0);
	if (k_platform) {
		sp -= 2;
		NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
	}
	sp -= 2;
	NEW_AUX_ENT(0, AT_HWCAP, hwcap);

	if (exec) {
		sp -= 11*2;

		NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
		NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
		NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
		NEW_AUX_ENT(3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
		NEW_AUX_ENT(4, AT_BASE, interp_load_addr);
		NEW_AUX_ENT(5, AT_FLAGS, 0);
		NEW_AUX_ENT(6, AT_ENTRY, load_bias + exec->e_entry);
		NEW_AUX_ENT(7, AT_UID, (elf_addr_t) current->uid);
		NEW_AUX_ENT(8, AT_EUID, (elf_addr_t) current->euid);
		NEW_AUX_ENT(9, AT_GID, (elf_addr_t) current->gid);
		NEW_AUX_ENT(10, AT_EGID, (elf_addr_t) current->egid);
	}
#undef NEW_AUX_ENT

	sp -= envc+1;
	envp = (elf_caddr_t *) sp;
	sp -= argc+1;
	argv = (elf_caddr_t *) sp;
	if (!ibcs) {
		__put_user((elf_addr_t)(unsigned long) envp,--sp);
		__put_user((elf_addr_t)(unsigned long) argv,--sp);
	}

	__put_user((elf_addr_t)argc,--sp);
	current->mm->arg_start = (unsigned long) p;
	while (argc-->0) {
		__put_user((elf_caddr_t)(unsigned long)p,argv++);
		p += strlen_user(p);
	}
	__put_user(NULL, argv);
	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
	while (envc-->0) {
		__put_user((elf_caddr_t)(unsigned long)p,envp++);
		p += strlen_user(p);
	}
	__put_user(NULL, envp);
	current->mm->env_end = (unsigned long) p;
	return sp;
}