From 8ed51910870d8829a352afe36abfbaf74ab1b16e Mon Sep 17 00:00:00 2001 From: zhizhimeimei6 Date: Wed, 9 Feb 2022 18:07:22 +0800 Subject: [PATCH] hievent: enable hievent driver ohos inclusion category: feature issue: #I4PJDP CVE: NA ----------------- hievent driver is used to store and upload kernel event. Signed-off-by: zhizhimeimei6 --- drivers/staging/hievent/Kconfig | 13 +- drivers/staging/hievent/Makefile | 3 +- drivers/staging/hievent/hievent_driver.c | 161 +++++++++++------------ drivers/staging/hievent/hievent_driver.h | 2 +- drivers/staging/hievent/hiview_hievent.c | 24 ++-- drivers/staging/hievent/hiview_hievent.h | 2 +- 6 files changed, 104 insertions(+), 101 deletions(-) diff --git a/drivers/staging/hievent/Kconfig b/drivers/staging/hievent/Kconfig index 39da4c041ba9..07834c32ba12 100644 --- a/drivers/staging/hievent/Kconfig +++ b/drivers/staging/hievent/Kconfig @@ -1,4 +1,11 @@ config HIEVENT - tristate "Enable hievent" - help - hievent buffer manager + tristate "Enable hievent" + help + hievent buffer manager + +config BBOX_BUFFER_SIZE + int "bbox buffer size" + depends on HIEVENT + default 2048 + help + Define the default ring buffer size of BBOX \ No newline at end of file diff --git a/drivers/staging/hievent/Makefile b/drivers/staging/hievent/Makefile index 2f67bf647e86..3d3ff445f5c9 100644 --- a/drivers/staging/hievent/Makefile +++ b/drivers/staging/hievent/Makefile @@ -1,2 +1 @@ - -obj-$(CONFIG_HIEVENT) += hievent_driver.o +obj-$(CONFIG_HIEVENT) += hievent_driver.o \ No newline at end of file diff --git a/drivers/staging/hievent/hievent_driver.c b/drivers/staging/hievent/hievent_driver.c index 8331a9632e62..36b0a778e04f 100644 --- a/drivers/staging/hievent/hievent_driver.c +++ b/drivers/staging/hievent/hievent_driver.c @@ -8,13 +8,16 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ +#define pr_fmt(fmt) "hievent_driver " fmt + #include "hievent_driver.h" +#include #include #include #include @@ -31,32 +34,22 @@ #include #include -#ifndef HIEVENTDEV_MAJOR -#define HIEVENTDEV_MAJOR 241 -#endif - -#ifndef HIEVENT_NR_DEVS -#define HIEVENT_NR_DEVS 2 -#endif - -static int hievent_major = HIEVENTDEV_MAJOR; +static struct class *hievent_class; +static dev_t hievent_devno; -static struct cdev hievent_cdev; - -#define HIEVENT_BUFFER ((size_t)1024) -#define HIEVENT_DRIVER "/dev/hwlog_exception" +#define HIEVENT_BUFFER ((size_t)CONFIG_BBOX_BUFFER_SIZE) +#define HIEVENT_DRIVER "/dev/bbox" +#define HIEVENT_DEV_NAME "bbox" +#define HIEVENT_DEV_NR 1 struct hievent_entry { unsigned short len; unsigned short header_size; - int pid; - int tid; - int sec; - int nsec; char msg[0]; }; struct hievent_char_device { + struct cdev devm; int flag; struct mutex mtx; /* lock to protect read/write buffer */ unsigned char *buffer; @@ -159,21 +152,12 @@ static ssize_t hievent_read(struct file *file, char __user *user_buf, } hievent_buffer_dec(sizeof(header)); - retval = copy_to_user((unsigned char *)user_buf, - (unsigned char *)&header, - min(count, sizeof(header))); - if (retval < 0) { - retval = -EINVAL; - goto out; - } - retval = hievent_read_ring_buffer((unsigned char *)(user_buf + - sizeof(header)), header.len); + retval = hievent_read_ring_buffer((unsigned char __user *)(user_buf), header.len); if (retval < 0) { retval = -EINVAL; goto out; } - hievent_buffer_dec(header.len); retval = header.len + sizeof(header); @@ -210,26 +194,7 @@ static int hievent_write_ring_head_buffer(const unsigned char *buffer, static void hievent_head_init(struct hievent_entry * const header, size_t len) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0) -#define NANOSEC_PER_MIRCOSEC 1000 - struct timeval now = { 0 }; - - do_gettimeofday(&now); - - header->sec = now.tv_sec; - header->nsec = now.tv_usec * NANOSEC_PER_MIRCOSEC; -#else - struct timespec64 now = { 0 }; - - ktime_get_real_ts64(&now); - - header->sec = now.tv_sec; - header->nsec = now.tv_nsec; -#endif - header->len = (unsigned short)len; - header->pid = current->pid; - header->tid = 0; header->header_size = sizeof(struct hievent_entry); } @@ -265,7 +230,6 @@ int hievent_write_internal(const char *buffer, size_t buf_len) hievent_cover_old_log(buf_len); hievent_head_init(&header, buf_len); - retval = hievent_write_ring_head_buffer((unsigned char *)&header, sizeof(header)); if (retval) { @@ -293,15 +257,17 @@ int hievent_write_internal(const char *buffer, size_t buf_len) return retval; } -static unsigned int hievent_poll(struct file *filep, - struct poll_table_struct *fds) +static unsigned int hievent_poll(struct file *filep, poll_table *wait) { - (void)filep; - (void)fds; + unsigned int mask = 0; - wait_event_interruptible(hievent_dev.wq, (hievent_dev.size > 0)); + poll_wait(filep, &hievent_dev.wq, wait); + if (hievent_dev.size > 0) { + mask |= POLLIN | POLLRDNORM; + return mask; + } - return (POLLOUT | POLLWRNORM); + return 0; } static ssize_t hievent_write_iter(struct kiocb *iocb, struct iov_iter *from) @@ -310,14 +276,16 @@ static ssize_t hievent_write_iter(struct kiocb *iocb, struct iov_iter *from) unsigned char *temp_buffer = NULL; const struct iovec *iov = from->iov; int retval; - int buf_len; - + size_t buf_len; (void)iocb; - if (from->nr_segs != 3) { /* must contain 3 segments */ + + if (from->nr_segs != 2) { /* must contain 2 segments */ + pr_err("invalid nr_segs: %ld", from->nr_segs); retval = -EINVAL; goto out; } + /* seg 0 info is checkcode*/ retval = copy_from_user(&check_code, iov[0].iov_base, sizeof(check_code)); if (retval || check_code != CHECK_CODE) { @@ -325,8 +293,8 @@ static ssize_t hievent_write_iter(struct kiocb *iocb, struct iov_iter *from) goto out; } - /* seg 1 && 2 is head info */ - buf_len = iov[1].iov_len + iov[2].iov_len; + /* seg 1 info */ + buf_len = iov[1].iov_len; if (buf_len > HIEVENT_BUFFER - sizeof(struct hievent_entry)) { retval = -ENOMEM; goto out; @@ -344,20 +312,11 @@ static ssize_t hievent_write_iter(struct kiocb *iocb, struct iov_iter *from) goto free_mem; } - /* 1 2 head info */ - retval = copy_from_user(temp_buffer + iov[1].iov_len, iov[2].iov_base, - iov[2].iov_len); - if (retval) { - retval = -EIO; - goto free_mem; - } - retval = hievent_write_internal(temp_buffer, buf_len); - if (retval) { + if (retval < 0) { retval = -EIO; goto free_mem; } - retval = buf_len + iov[0].iov_len; free_mem: @@ -373,11 +332,11 @@ static const struct file_operations hievent_fops = { .write_iter = hievent_write_iter, /* write_iter */ }; -static void hievent_device_init(void) +static int hievent_device_init(void) { hievent_dev.buffer = kmalloc(HIEVENT_BUFFER, GFP_KERNEL); if (!hievent_dev.buffer) - return; + return -ENOMEM; init_waitqueue_head(&hievent_dev.wq); mutex_init(&hievent_dev.mtx); @@ -385,31 +344,69 @@ static void hievent_device_init(void) hievent_dev.head_offset = 0; hievent_dev.size = 0; hievent_dev.count = 0; + + return 0; } static int __init hieventdev_init(void) { int result; - dev_t devno = MKDEV(hievent_major, 0); + struct device *dev_ret = NULL; - result = register_chrdev_region(devno, 2, "hwlog_exception"); - if (result < 0) - return result; + result = alloc_chrdev_region(&hievent_devno, 0, HIEVENT_DEV_NR, HIEVENT_DEV_NAME); + if (result < 0) { + pr_err("register %s failed", HIEVENT_DRIVER); + return -ENODEV; + } + + cdev_init(&hievent_dev.devm, &hievent_fops); + hievent_dev.devm.owner = THIS_MODULE; + + result = cdev_add(&hievent_dev.devm, hievent_devno, HIEVENT_DEV_NR); + if (result < 0) { + pr_err("cdev_add failed"); + goto unreg_dev; + } + + result = hievent_device_init(); + if (result < 0) { + pr_err("hievent_device_init failed"); + goto del_dev; + } - cdev_init(&hievent_cdev, &hievent_fops); - hievent_cdev.owner = THIS_MODULE; - hievent_cdev.ops = &hievent_fops; + hievent_class = class_create(THIS_MODULE, HIEVENT_DEV_NAME); + if (IS_ERR(hievent_class)) { + pr_err("class_create failed"); + goto del_buffer; + } - cdev_add(&hievent_cdev, MKDEV(hievent_major, 0), HIEVENT_NR_DEVS); + dev_ret = device_create(hievent_class, 0, hievent_devno, 0, HIEVENT_DEV_NAME); + if (IS_ERR(dev_ret)) { + pr_err("device_create failed"); + goto del_class; + } - hievent_device_init(); return 0; + +del_class: + class_destroy(hievent_class); +del_buffer: + kfree(hievent_dev.buffer); +del_dev: + cdev_del(&hievent_dev.devm); +unreg_dev: + unregister_chrdev_region(hievent_devno, HIEVENT_DEV_NR); + + return -ENODEV; } static void __exit hievent_exit_module(void) { - cdev_del(&hievent_cdev); - unregister_chrdev_region(MKDEV(hievent_major, 0), HIEVENT_NR_DEVS); + device_destroy(hievent_class, hievent_devno); + class_destroy(hievent_class); + kfree(hievent_dev.buffer); + cdev_del(&hievent_dev.devm); + unregister_chrdev_region(hievent_devno, HIEVENT_DEV_NR); } static int __init hievent_init_module(void) diff --git a/drivers/staging/hievent/hievent_driver.h b/drivers/staging/hievent/hievent_driver.h index 56eb0c5ea316..5d52982b78f6 100644 --- a/drivers/staging/hievent/hievent_driver.h +++ b/drivers/staging/hievent/hievent_driver.h @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ diff --git a/drivers/staging/hievent/hiview_hievent.c b/drivers/staging/hievent/hiview_hievent.c index 552965dfacb4..c72e6f2bb401 100644 --- a/drivers/staging/hievent/hiview_hievent.c +++ b/drivers/staging/hievent/hiview_hievent.c @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ @@ -24,19 +24,19 @@ #define MAX_PATH_LEN 256 #define MAX_STR_LEN (10 * 1024) -/* 64K is max length of /dev/hwlog_exception */ -#define EVENT_INFO_BUF_LEN (64 * 1024) -#define EVENT_INFO_PACK_BUF_LEN (2 * 1024) +/* CONFIG_BBOX_BUFFER_SIZE is max length of /dev/bbox */ +#define EVENT_INFO_BUF_LEN ((size_t)CONFIG_BBOX_BUFFER_SIZE) +#define EVENT_INFO_PACK_BUF_LEN min((size_t)CONFIG_BBOX_BUFFER_SIZE, 2048) -#define BUF_POINTER_FORWARD \ +#define BUF_POINTER_FORWARD \ do { \ - if (tmplen < len) { \ - tmp += tmplen; \ - len -= tmplen; \ - } else { \ - tmp += len; \ - len = 0; \ - } \ + if (tmplen < len) { \ + tmp += tmplen; \ + len -= tmplen; \ + } else { \ + tmp += len; \ + len = 0; \ + } \ } while (0) struct hievent_payload { diff --git a/drivers/staging/hievent/hiview_hievent.h b/drivers/staging/hievent/hiview_hievent.h index 48d4ae32b536..358a3e8fed4e 100644 --- a/drivers/staging/hievent/hiview_hievent.h +++ b/drivers/staging/hievent/hiview_hievent.h @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ -- Gitee