| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * An implementation of a loadable kernel mode driver providing |
|---|
| 3 | 4 | * multiple kernel/user space bidirectional communications links. |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Author: Alan Cox <alan@lxorguk.ukuu.org.uk> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or |
|---|
| 8 | | - * modify it under the terms of the GNU General Public License |
|---|
| 9 | | - * as published by the Free Software Foundation; either version |
|---|
| 10 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 11 | 7 | * |
|---|
| 12 | 8 | * Adapted to become the Linux 2.0 Coda pseudo device |
|---|
| 13 | 9 | * Peter Braam <braam@maths.ox.ac.uk> |
|---|
| .. | .. |
|---|
| 39 | 35 | #include <linux/device.h> |
|---|
| 40 | 36 | #include <linux/pid_namespace.h> |
|---|
| 41 | 37 | #include <asm/io.h> |
|---|
| 42 | | -#include <linux/poll.h> |
|---|
| 43 | 38 | #include <linux/uaccess.h> |
|---|
| 44 | 39 | |
|---|
| 45 | 40 | #include <linux/coda.h> |
|---|
| 46 | | -#include <linux/coda_psdev.h> |
|---|
| 47 | | - |
|---|
| 41 | +#include "coda_psdev.h" |
|---|
| 48 | 42 | #include "coda_linux.h" |
|---|
| 49 | 43 | |
|---|
| 50 | 44 | #include "coda_int.h" |
|---|
| .. | .. |
|---|
| 105 | 99 | ssize_t retval = 0, count = 0; |
|---|
| 106 | 100 | int error; |
|---|
| 107 | 101 | |
|---|
| 102 | + /* make sure there is enough to copy out the (opcode, unique) values */ |
|---|
| 103 | + if (nbytes < (2 * sizeof(u_int32_t))) |
|---|
| 104 | + return -EINVAL; |
|---|
| 105 | + |
|---|
| 108 | 106 | /* Peek at the opcode, uniquefier */ |
|---|
| 109 | | - if (copy_from_user(&hdr, buf, 2 * sizeof(u_long))) |
|---|
| 107 | + if (copy_from_user(&hdr, buf, 2 * sizeof(u_int32_t))) |
|---|
| 110 | 108 | return -EFAULT; |
|---|
| 111 | 109 | |
|---|
| 112 | 110 | if (DOWNCALL(hdr.opcode)) { |
|---|
| .. | .. |
|---|
| 124 | 122 | hdr.opcode, hdr.unique); |
|---|
| 125 | 123 | nbytes = size; |
|---|
| 126 | 124 | } |
|---|
| 127 | | - CODA_ALLOC(dcbuf, union outputArgs *, nbytes); |
|---|
| 125 | + dcbuf = kvmalloc(nbytes, GFP_KERNEL); |
|---|
| 126 | + if (!dcbuf) { |
|---|
| 127 | + retval = -ENOMEM; |
|---|
| 128 | + goto out; |
|---|
| 129 | + } |
|---|
| 128 | 130 | if (copy_from_user(dcbuf, buf, nbytes)) { |
|---|
| 129 | | - CODA_FREE(dcbuf, nbytes); |
|---|
| 131 | + kvfree(dcbuf); |
|---|
| 130 | 132 | retval = -EFAULT; |
|---|
| 131 | 133 | goto out; |
|---|
| 132 | 134 | } |
|---|
| 133 | 135 | |
|---|
| 134 | 136 | /* what downcall errors does Venus handle ? */ |
|---|
| 135 | | - error = coda_downcall(vcp, hdr.opcode, dcbuf); |
|---|
| 137 | + error = coda_downcall(vcp, hdr.opcode, dcbuf, nbytes); |
|---|
| 136 | 138 | |
|---|
| 137 | | - CODA_FREE(dcbuf, nbytes); |
|---|
| 139 | + kvfree(dcbuf); |
|---|
| 138 | 140 | if (error) { |
|---|
| 139 | 141 | pr_warn("%s: coda_downcall error: %d\n", |
|---|
| 140 | 142 | __func__, error); |
|---|
| .. | .. |
|---|
| 260 | 262 | goto out; |
|---|
| 261 | 263 | } |
|---|
| 262 | 264 | |
|---|
| 263 | | - CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
|---|
| 265 | + kvfree(req->uc_data); |
|---|
| 264 | 266 | kfree(req); |
|---|
| 265 | 267 | out: |
|---|
| 266 | 268 | mutex_unlock(&vcp->vc_mutex); |
|---|
| .. | .. |
|---|
| 322 | 324 | |
|---|
| 323 | 325 | /* Async requests need to be freed here */ |
|---|
| 324 | 326 | if (req->uc_flags & CODA_REQ_ASYNC) { |
|---|
| 325 | | - CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
|---|
| 327 | + kvfree(req->uc_data); |
|---|
| 326 | 328 | kfree(req); |
|---|
| 327 | 329 | continue; |
|---|
| 328 | 330 | } |
|---|
| .. | .. |
|---|
| 355 | 357 | .llseek = noop_llseek, |
|---|
| 356 | 358 | }; |
|---|
| 357 | 359 | |
|---|
| 358 | | -static int init_coda_psdev(void) |
|---|
| 360 | +static int __init init_coda_psdev(void) |
|---|
| 359 | 361 | { |
|---|
| 360 | 362 | int i, err = 0; |
|---|
| 361 | 363 | if (register_chrdev(CODA_PSDEV_MAJOR, "coda", &coda_psdev_fops)) { |
|---|
| 362 | 364 | pr_err("%s: unable to get major %d\n", |
|---|
| 363 | 365 | __func__, CODA_PSDEV_MAJOR); |
|---|
| 364 | | - return -EIO; |
|---|
| 366 | + return -EIO; |
|---|
| 365 | 367 | } |
|---|
| 366 | 368 | coda_psdev_class = class_create(THIS_MODULE, "coda"); |
|---|
| 367 | 369 | if (IS_ERR(coda_psdev_class)) { |
|---|
| .. | .. |
|---|
| 386 | 388 | MODULE_DESCRIPTION("Coda Distributed File System VFS interface"); |
|---|
| 387 | 389 | MODULE_ALIAS_CHARDEV_MAJOR(CODA_PSDEV_MAJOR); |
|---|
| 388 | 390 | MODULE_LICENSE("GPL"); |
|---|
| 389 | | -MODULE_VERSION("6.6"); |
|---|
| 391 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 392 | +MODULE_VERSION("7.0"); |
|---|
| 390 | 393 | |
|---|
| 391 | 394 | static int __init init_coda(void) |
|---|
| 392 | 395 | { |
|---|