We'll introduce a different mode of tracing a-la AFL fixed table and Dmitry suggests that the code would be simpler with the size expressed in bytes as opposed unsigned longs.
We only change the kcov::size field, which will be shared between different modes, but leave the task_struct::kcov_size field expressed in unsigned long in order to save an unecessary bitshift/division in the hot path when using KCOV_MODE_TRACE. Cc: Dmitry Vyukov <dvyu...@google.com> Cc: Michal Zalewski <lcam...@gmail.com> Cc: Kees Cook <keesc...@chromium.org> Signed-off-by: Quentin Casasnovas <quentin.casasno...@oracle.com> Signed-off-by: Vegard Nossum <vegard.nos...@oracle.com> --- kernel/kcov.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 30e6d05aa5a9..c2aa93851f93 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -32,7 +32,7 @@ struct kcov { /* The lock protects mode, size, area and t. */ spinlock_t lock; enum kcov_mode mode; - /* Size of arena (in long's for KCOV_MODE_TRACE). */ + /* Size of arena in bytes. */ unsigned size; /* Coverage buffer shared with user space. */ void *area; @@ -140,7 +140,7 @@ static int kcov_mmap(struct file *filep, struct vm_area_struct *vma) return -ENOMEM; spin_lock(&kcov->lock); - size = kcov->size * sizeof(unsigned long); + size = kcov->size; if (kcov->mode == KCOV_MODE_DISABLED || vma->vm_pgoff != 0 || vma->vm_end - vma->vm_start != size) { res = -EINVAL; @@ -198,13 +198,11 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, return -EBUSY; /* * Size must be at least 2 to hold current position and one PC. - * Later we allocate size * sizeof(unsigned long) memory, - * that must not overflow. */ size = arg; if (size < 2 || size > INT_MAX / sizeof(unsigned long)) return -EINVAL; - kcov->size = size; + kcov->size = size * sizeof(unsigned long); kcov->mode = KCOV_MODE_TRACE; return 0; case KCOV_ENABLE: @@ -223,7 +221,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, return -EBUSY; t = current; /* Cache in task struct for performance. */ - t->kcov_size = kcov->size; + t->kcov_size = kcov->size / sizeof(unsigned long); t->kcov_area = kcov->area; /* See comment in __sanitizer_cov_trace_pc(). */ barrier(); -- 2.10.2