static int sys_link(void * user_args) { struct _fs_link_args * args; int err, retval = -1; err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_link_args), GET_STRUCT_OFFSETS(struct _fs_link_args, path1, path1_len, path2, path2_len)); if (err) { set_errno(-err); goto out; } /* Validate strings */ if (!strvalid(args->path1, args->path1_len) || !strvalid(args->path2, args->path2_len)) { set_errno(ENAMETOOLONG); goto out; } err = fs_link_curproc(args->path1, args->path1_len, args->path2, args->path2_len); if (err) { set_errno(-err); goto out; } retval = 0; out: freecpystruct(args); return retval; }
static int sys_rmdir(void * user_args) { struct _fs_rmdir_args * args = 0; int err, retval = -1; err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_rmdir_args), GET_STRUCT_OFFSETS(struct _fs_rmdir_args, path, path_len)); if (err) { set_errno(-err); goto out; } /* Validate path string */ if (!strvalid(args->path, args->path_len)) { set_errno(ENAMETOOLONG); goto out; } err = fs_rmdir_curproc(args->path); if (err) { set_errno(-err); goto out; } retval = 0; out: freecpystruct(args); return retval; }
static int sys_mount(void * user_args) { struct _fs_mount_args * args = 0; vnode_t * mpt; int err; int retval = -1; err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_mount_args), GET_STRUCT_OFFSETS(struct _fs_mount_args, source, source_len, target, target_len, parm, parm_len)); if (err) { set_errno(-err); goto out; } /* Validate path strings */ if (!strvalid(args->source, args->source_len) || !strvalid(args->target, args->target_len)) { set_errno(ENAMETOOLONG); goto out; } if (fs_namei_proc(&mpt, -1, (char *)args->target, AT_FDCWD)) { set_errno(ENOENT); /* Mount point doesn't exist */ goto out; } err = fs_mount(mpt, args->source, args->fsname, args->flags, args->parm, args->parm_len); if (err) { set_errno(-err); goto out; } retval = 0; out: freecpystruct(args); return retval; }
static int sys_open(void * user_args) { struct _fs_open_args * args = 0; vnode_t * file; int err, retval = -1; /* Copyin args struct */ err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_open_args), GET_STRUCT_OFFSETS(struct _fs_open_args, name, name_len)); if (err) { set_errno(-err); goto out; } if (args->name_len < 2) { /* File name too short */ set_errno(EINVAL); goto out; } /* Validate name string */ if (!strvalid(args->name, args->name_len)) { set_errno(ENAMETOOLONG); goto out; } err = fs_namei_proc(&file, args->fd, args->name, args->atflags); if (err) { if (args->oflags & O_CREAT) { /* Create a new file */ /* TODO Determine correct mode bits?? */ retval = fs_creat_cproc(args->name, S_IFREG | args->mode, &file); if (retval) { set_errno(-retval); goto out; } } else { set_errno(ENOENT); goto out; } } retval = fs_fildes_create_cproc(file, args->oflags); if (retval < 0) { set_errno(-retval); retval = -1; } out: freecpystruct(args); return retval; }
static int sys_access(void * user_args) { struct _fs_access_args * args = 0; vnode_t * vnode; uid_t euid; gid_t egid; int err, retval = -1; err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_access_args), GET_STRUCT_OFFSETS(struct _fs_access_args, path, path_len)); if (err) { set_errno(-err); goto out; } if (!strvalid(args->path, args->path_len)) { set_errno(ENAMETOOLONG); goto out; } if (!(args->flag & AT_FDARG)) { /* access() */ err = fs_namei_proc(&vnode, -1, args->path, AT_FDCWD); if (err) { set_errno(-err); goto out; } } else { /* faccessat() */ fs_namei_proc(&vnode, args->fd, args->path, AT_FDARG); set_errno(ENOTSUP); return -1; } if (args->flag & AT_EACCESS) { euid = curproc->euid; egid = curproc->egid; } else { euid = curproc->uid; egid = curproc->gid; } if (args->amode & F_OK) { retval = 0; goto out; } retval = chkperm_vnode(vnode, euid, egid, args->amode); out: return retval; }
ssize_t write_dyndebug(const struct procfs_info * spec, struct procfs_stream * stream, const uint8_t * buf, size_t bufsize) { struct _kerror_dyndebug_msg * msg_opt = &__start_set_debug_msg_sect; struct _kerror_dyndebug_msg * stop = &__stop_set_debug_msg_sect; int err; if (msg_opt == stop) return 0; if (!strvalid((char *)buf, bufsize)) return -EINVAL; err = toggle_dbgmsg((char *)buf); if (err) return err; return stream->bytes; }
static int sys_filestat(void * user_args) { struct _fs_stat_args * args = 0; vnode_t * vnode; struct stat stat_buf; int err, retval = -1; err = copyinstruct(user_args, (void **)(&args), sizeof(struct _fs_stat_args), GET_STRUCT_OFFSETS(struct _fs_stat_args, path, path_len)); if (err) { set_errno(-err); goto out; } if (!useracc(args->buf, sizeof(struct stat), VM_PROT_WRITE)) { set_errno(EFAULT); goto out; } /* Validate path string */ if (!strvalid(args->path, args->path_len)) { set_errno(ENAMETOOLONG); goto out; } if (args->flags & AT_FDARG) { /* by fildes */ file_t * fildes; /* Note: AT_SYMLINK_NOFOLLOW == O_NOFOLLOW */ const int ofalgs = (args->flags & AT_SYMLINK_NOFOLLOW); fildes = fs_fildes_ref(curproc->files, args->fd, 1); if (!fildes) { set_errno(EBADF); goto out; } err = fildes->vnode->vnode_ops->stat(fildes->vnode, &stat_buf); if (!err) { /* Check if fildes was opened with O_SEARCH or if not then if we * have a permission to search by file permissions. */ if (fildes->oflags & O_SEARCH || chkperm_cproc(&stat_buf, O_EXEC)) err = lookup_vnode(&vnode, fildes->vnode, args->path, ofalgs); else /* No permission to search */ err = -EACCES; } fs_fildes_ref(curproc->files, args->fd, -1); if (err) { /* Handle previous error */ set_errno(-err); goto out; } } else { /* search by path */ if (fs_namei_proc(&vnode, -1, (char *)args->path, AT_FDCWD)) { set_errno(ENOENT); goto out; } } if ((args->flags & AT_FDARG) && (args->flags & O_EXEC)) { /* Get stat of given fildes, which we have * have in stat_buf. */ goto ready; } err = vnode->vnode_ops->stat(vnode, &stat_buf); if (err) { set_errno(-err); goto out; } ready: copyout(&stat_buf, args->buf, sizeof(struct stat)); retval = 0; out: freecpystruct(args); return retval; }