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); }
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; }
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; }
/** * 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; }
/** * 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; }
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; }
/** * 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; }
/* 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; }
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; }
/** * 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; }
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; }
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; }
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; }
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; }
/* * 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; }
/** * 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; }
/* * ======== 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; }
/* * ======== 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; }
/**************************************************************************** * 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; }
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; }
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; }
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; }
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; }
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; }