void RandomAccessFile_setLength (JNIEnv *env, w_instance thisRAF, w_long newlen) { w_instance fd_obj; vfs_FILE *file; fd_obj = getReferenceField(thisRAF, F_RandomAccessFile_fd); file = getWotsitField(fd_obj, F_FileDescriptor_fd); if(file == NULL) { throwNullPointerException(JNIEnv2w_thread(env)); } else { char *pathname; w_long oldptr; pathname = getFDName(fd_obj); oldptr = vfs_ftell(file); if(vfs_truncate(pathname, newlen) == -1) { throwIOException(JNIEnv2w_thread(env)); } freeFDName(pathname); if(newlen < oldptr && vfs_fseek(file, newlen, SEEK_SET) == -1) { throwIOException(JNIEnv2w_thread(env)); } } }
/* * dispose of the links from a revoked keyring * - called with the key sem write-locked */ void big_key_revoke(struct key *key) { struct path *path = (struct path *)&key->payload.data[big_key_path]; /* clear the quota */ key_payload_reserve(key, 0); if (key_is_instantiated(key) && (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) vfs_truncate(path, 0); }
static long do_sys_truncate(const char __user *pathname, loff_t length) { struct path path; int error; if (length < 0) /* sorry, but loff_t says... */ return -EINVAL; error = user_path(pathname, &path); if (!error) { error = vfs_truncate(&path, length); path_put(&path); } return error; }
static long do_sys_truncate(const char __user *pathname, loff_t length) { unsigned int lookup_flags = LOOKUP_FOLLOW; struct path path; int error; if (length < 0) /* sorry, but loff_t says... */ return -EINVAL; retry: error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); if (!error) { error = vfs_truncate(&path, length); path_put(&path); } if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; goto retry; } return error; }
static int kdbus_memfd_mmap(struct file *file, struct vm_area_struct *vma) { struct kdbus_memfile *mf = file->private_data; int ret = 0; mutex_lock(&mf->lock); if (vma->vm_flags & VM_WRITE) { size_t size; /* deny a writable mapping to a sealed file */ if (mf->sealed) { ret = -EPERM; goto exit; } /* extend the size of the shmem file to the size of the mapping */ size = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); if (size > PAGE_ALIGN(i_size_read(file_inode(mf->fp)))) { ret = vfs_truncate(&mf->fp->f_path, size); if (ret < 0) return ret; } } /* replace the anoymous inode file with our shmem file */ if (vma->vm_file) fput(vma->vm_file); vma->vm_file = get_file(mf->fp); ret = mf->fp->f_op->mmap(file, vma); exit: mutex_unlock(&mf->lock); return ret; }
static long kdbus_memfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct kdbus_memfile *mf = file->private_data; long ret = 0; mutex_lock(&mf->lock); switch (cmd) { case KDBUS_CMD_MEMFD_SIZE_GET: { u64 size = i_size_read(file_inode(mf->fp)); if (!KDBUS_IS_ALIGNED8(arg)) { ret = -EFAULT; goto exit; } if (copy_to_user(argp, &size, sizeof(__u64))) { ret = -EFAULT; goto exit; } break; } case KDBUS_CMD_MEMFD_SIZE_SET: { u64 size; if (!KDBUS_IS_ALIGNED8(arg)) { ret = -EFAULT; goto exit; } if (copy_from_user(&size, argp, sizeof(__u64))) { ret = -EFAULT; goto exit; } /* deny a writable access to a sealed file */ if (mf->sealed) { if (size == i_size_read(file_inode(mf->fp))) ret = -EALREADY; else ret = -EPERM; goto exit; } if (size != i_size_read(file_inode(mf->fp))) ret = vfs_truncate(&mf->fp->f_path, size); break; } case KDBUS_CMD_MEMFD_SEAL_GET: { int __user *addr = argp; if (put_user(mf->sealed, addr)) { ret = -EFAULT; goto exit; } break; } case KDBUS_CMD_MEMFD_SEAL_SET: { struct mm_struct *mm = current->mm; /* * Make sure we have only one single user of the file * before we seal, we rely on the fact there is no * any other possibly writable references to the file. * * Protect mmap() racing against us, take mm->mmap_sem * when accessing mf->sealed. */ down_read(&mm->mmap_sem); if (file_count(mf->fp) != 1) { if (mf->sealed == !!argp) ret = -EALREADY; else ret = -ETXTBSY; } if (ret == 0) mf->sealed = !!argp; up_read(&mm->mmap_sem); break; } default: ret = -ENOTTY; break; } exit: mutex_unlock(&mf->lock); return ret; }
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) { bool cont = true; /* * The connection was opened via the IPC_CONNECT_ME_TO call. * This call needs to be answered. */ async_answer_0(iid, EOK); while (cont) { ipc_call_t call; ipc_callid_t callid = async_get_call(&call); if (!IPC_GET_IMETHOD(call)) break; switch (IPC_GET_IMETHOD(call)) { case VFS_IN_REGISTER: vfs_register(callid, &call); cont = false; break; case VFS_IN_MOUNT: vfs_mount(callid, &call); break; case VFS_IN_UNMOUNT: vfs_unmount(callid, &call); break; case VFS_IN_OPEN: vfs_open(callid, &call); break; case VFS_IN_CLOSE: vfs_close(callid, &call); break; case VFS_IN_READ: vfs_read(callid, &call); break; case VFS_IN_WRITE: vfs_write(callid, &call); break; case VFS_IN_SEEK: vfs_seek(callid, &call); break; case VFS_IN_TRUNCATE: vfs_truncate(callid, &call); break; case VFS_IN_FSTAT: vfs_fstat(callid, &call); break; case VFS_IN_STAT: vfs_stat(callid, &call); break; case VFS_IN_MKDIR: vfs_mkdir(callid, &call); break; case VFS_IN_UNLINK: vfs_unlink(callid, &call); break; case VFS_IN_RENAME: vfs_rename(callid, &call); break; case VFS_IN_SYNC: vfs_sync(callid, &call); break; case VFS_IN_DUP: vfs_dup(callid, &call); break; case VFS_IN_WAIT_HANDLE: vfs_wait_handle(callid, &call); break; case VFS_IN_MTAB_GET: vfs_get_mtab(callid, &call); break; default: async_answer_0(callid, ENOTSUP); break; } } /* * Open files for this client will be cleaned up when its last * connection fibril terminates. */ }
int16_t cron_save() { #ifdef CRON_VFS_SUPPORT struct vfs_file_handle_t *file; vfs_size_t filesize; vfs_size_t tempsize; #else uint16_t filesize; uint16_t tempsize; #endif uint8_t count = 0; uint8_t saved_count = 0; #ifdef DEBUG_CRON debug_printf("cron: saving jobs\n"); #endif #ifdef CRON_VFS_SUPPORT file = vfs_create(CRON_FILENAME); if (file == NULL) { #ifdef DEBUG_CRON debug_printf("cron: can't create file\n"); #endif return -1; } #endif // placeholder filesize = sizeof(count); struct cron_event_linkedlist *job = head; while (job) { if (job->event.persistent) { count++; filesize += sizeof(struct cron_event) + job->event.extrasize; } job = job->next; } #ifdef CRON_VFS_SUPPORT if (vfs_write(file, &count, sizeof(count)) != sizeof(count)) return cron_write_error(file); #else if (filesize >= CRON_EEPROM_SIZE) return -1; eeprom_save_offset(crontab, 0, &count, sizeof(uint8_t)); #endif filesize = sizeof(count); job = head; while (job) { if (job->event.persistent) { #ifdef DEBUG_CRON debug_printf("cron: writing job %i\n", count); #endif tempsize = sizeof(struct cron_event) + job->event.extrasize; #ifdef DEBUG_CRON debug_printf ("cron: try to allocate size of %i consist of struct %i and extrasize %i!\n", tempsize, sizeof(struct cron_event), job->event.extrasize); #endif #ifdef CRON_VFS_SUPPORT if (vfs_write(file, &job->event, tempsize) != tempsize) return cron_write_error(file); #else eeprom_save_offset(crontab, filesize, &job->event, tempsize); #endif filesize += tempsize; saved_count++; } job = job->next; // reset watchdog only if it seems that everything is going right if (saved_count <= count) { wdt_kick(); } } #ifdef DEBUG_CRON debug_printf("cron: all jobs written with total size of %i\n", filesize); #endif #ifdef CRON_VFS_SUPPORT vfs_truncate(file, filesize); vfs_close(file); #else eeprom_update_chksum(); #endif return saved_count; }
static int cp(int argc, char *argv[]) { if(argc != 3) { printf("Usage: %s src dest\n", argv[0]); return 1; } static uint8_t buf[32768]; size_t rsize, wsize; vfs_handle_t src = NULL, dst = NULL; errval_t err; int ret = 0; char *path = vfs_path_mkabsolute(cwd, argv[1]); err = vfs_open(path, &src); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[1], err_getstring(err)); return 1; } path = vfs_path_mkabsolute(cwd, argv[2]); err = vfs_create(path, &dst); free(path); if (err_is_fail(err)) { printf("%s: %s\n", argv[2], err_getstring(err)); ret = 1; goto out; } err = vfs_truncate(dst, 0); if (err_is_fail(err)) { printf("truncate %s: %s\n", argv[2], err_getstring(err)); ret = 1; goto out; } do { err = vfs_read(src, buf, sizeof(buf), &rsize); if (err_is_fail(err)) { DEBUG_ERR(err, "error reading file"); ret = 1; goto out; } size_t wpos = 0; while (wpos < rsize) { err = vfs_write(dst, &buf[wpos], rsize - wpos, &wsize); if (err_is_fail(err) || wsize == 0) { DEBUG_ERR(err, "error writing file"); ret = 1; goto out; } wpos += wsize; } } while(rsize > 0); out: if (src != NULL) { err = vfs_close(src); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } if (dst != NULL) { err = vfs_close(dst); if (err_is_fail(err)) { DEBUG_ERR(err, "in vfs_close"); } } return ret; }
/** * decrypt * @f: pointer to struct which contains information about input,temporary and output files * @key_hash: MD5 of key created from password given by user * @user_args: pointer to struct user_args_t which contains arguments given by user in user-space * * Decrypts the data in multiples of block size of aes (16 bytes). Truncates the data if padding was added. * * Returns 0 on success; non-zero otherwise */ int decrypt(struct file_struct *f, unsigned char *key_hash, struct user_args_t *user_args) { int err, i; unsigned int bytes_to_decrypt, last_bytes, dec_in_loop, padding_size, inp_file_size; unsigned char buf[BUF_SIZE]; int bytes_read; bytes_read = read_from_file(f->filp_in, buf, 17); printk(KERN_ALERT"decryption bytes read = %u\n", bytes_read); for (i = 0 ; i < AES_KEY_SIZE ; i++) { if (key_hash[i] != buf[i+1]) { printk(KERN_ALERT"invalid password to decrypt\n"); err = -EACCES; goto ERR; } } padding_size = (int) buf[0]; printk(KERN_ALERT"padding size = %d\n", padding_size); f->filp_temp->f_pos = 0; inp_file_size = f->filp_in->f_inode->i_size - 17; printk(KERN_ALERT"inp file size = %u\n", inp_file_size); dec_in_loop = inp_file_size/BUF_SIZE; last_bytes = inp_file_size > BUF_SIZE ? inp_file_size % BUF_SIZE : 0; memset(buf, 0, BUF_SIZE); if (inp_file_size < BUF_SIZE) { bytes_read = read_from_file(f->filp_in, buf, inp_file_size); bytes_to_decrypt = inp_file_size; err = handle_enc_dec(f, buf, bytes_to_decrypt, user_args->enc_key, user_args->flags); vfs_truncate(&(f->filp_temp->f_path), inp_file_size-padding_size); goto ERR; } else { while (dec_in_loop) { bytes_read = read_from_file(f->filp_in, buf, BUF_SIZE); err = handle_enc_dec(f, buf, BUF_SIZE, user_args->enc_key, user_args->flags); --dec_in_loop; if (err) { printk(KERN_ALERT"error in encryption\n"); goto ERR; } } } if (inp_file_size != 0 && inp_file_size % BUF_SIZE == 0) { err = 0; vfs_truncate(&(f->filp_temp->f_path), inp_file_size-padding_size); goto ERR; } if (last_bytes) { bytes_read = read_from_file(f->filp_in, buf, last_bytes); printk(KERN_ALERT"read remaining %u bytes\n", bytes_read); } printk(KERN_ALERT" decryption last %u bytes\n", last_bytes); err = handle_enc_dec(f, buf, last_bytes, user_args->enc_key, user_args->flags); if (err) { printk(KERN_ALERT"error in decryption\n"); goto ERR; } vfs_truncate(&(f->filp_temp->f_path), inp_file_size-padding_size); ERR: return err; }