0

我尝试将简单的加密添加到由 Android 中的 logcat 创建的日志文件中。为了性能,我在读取函数中添加加密而不是写入(driver/staging/android/logger.c)

    /*
     * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the
     * user-space buffer 'buf'. Returns 'count' on success.
     *
     * Caller must hold log->mutex.
     */
    static ssize_t do_read_log_to_user(struct logger_log *log,
                       struct logger_reader *reader,
                       char __user *buf,
                       size_t count)
    {
        size_t len;
    unsigned int i;
    size_t _size;
    unsigned char *str;

    /*
     * We read from the log in two disjoint operations. First, we read from
     * the current read head offset up to 'count' bytes or to the end of
     * the log, whichever comes first.
     */
    len = min(count, log->size - reader->r_off);

    // added
    _size= strlen(log->buffer);
    printk(KERN_INFO "_size=%d, len=%d, count=%d, logsize=%d, r_off=%d\n", _size, len, count, log->size, reader->r_off);
    str = kmalloc(len, GFP_KERNEL);
    if(str==NULL)
        printk(KERN_ERR "logger: failed to allocate buffer\n");
    memcpy(str,log->buffer,len);
    for(i=0;i < _size; i++)
        str[i] ^=14; //XOR encryption here
//  if (copy_to_user(buf, log->buffer + reader->r_off, len))
    if (copy_to_user(buf, str + reader->r_off, len))    //changed here
        return -EFAULT;

    /*
     * Second, we read any remaining bytes, starting back at the head of
     * the log.
     */
    if (count != len) {
//      if (copy_to_user(buf + len, log->buffer, count - len))
        if (copy_to_user(buf + len, str, count - len))  //changed here
            return -EFAULT;
    }

    reader->r_off = logger_offset(reader->r_off + count);

    if(str!=NULL) {
        kfree(str);
        str=NULL;   
    }

    return count;
}

但似乎它没有按预期工作。当我运行 adb logcat 时,从该段代码(/system/core/logcat/logcat.cpp)显示错误消息

            else if (entry->entry.len != ret - sizeof(struct logger_entry)) {
                fprintf(stderr, "read: unexpected length. Expected %d, got %d\n",
                        entry->entry.len, ret - sizeof(struct logger_entry));
                exit(EXIT_FAILURE);
            }

我在这里错过了什么吗?

更新:

我修改了代码只是为了将数据存储到 tempstr然后在将其复制给用户之前对其执行 XOR。

    /* Allocate the memory for storing plain text */
    str = kmalloc(len, GFP_KERNEL);
    if(str == NULL) {
        printk(KERN_ERR "logger: failed to allocate buffer\n");
        return -ENOMEM; 
    }
    memcpy(str, log->buffer + reader->r_off, len);
    /* Start: Add a simple XOR encryption here */
    for(i=0;i < strlen(str); i++)
        str[i] ^= 14;
    /* End: Add a simple XOR encryption here */

//  if (copy_to_user(buf, log->buffer + reader->r_off, len))    //Original code
    if (copy_to_user(buf, str, len))                //Modified code
        return -EFAULT;

但是,似乎仍然显示相同的错误,我确定问题来自以下代码

// Start: Add a simple XOR encryption here
for(i=0;i < strlen(str); i++)
    str[i] ^= 14;
// End: Add a simple XOR encryption here

因为如果我删除它,它就像原始代码一样工作。我在这里没有发现任何问题?有人看到这里有什么奇怪的吗???

4

1 回答 1

1

首先,您应该显示与原始来源的统一差异。熟悉内核开发和源代码的人将习惯于阅读差异。

我可以看到代码的一些问题

  • kmalloc()失败时,您会打印一条错误消息,但str无论如何都要复制到。灾难的可靠秘诀。
  • _size= strlen(log->buffer)我不知道,如果缓冲区被 NUL 终止,特别是因为似乎有一个log->size成员。如果它不是 NUL 终止的,strlen()则要么报告大小太大,要么运行直到遇到不可访问的页面,这可能会导致访问错误。
  • 您分配一个大小的缓冲区min(...),但将字节复制_size到其中。当两者之间不匹配时,您将破坏堆内存。
  • 您用于strlen()检测所需的缓冲区大小,但memcpy()之后执行。通常,您不应该混合使用str*()mem*()使用功能,而是使用其中一个或另一个。
于 2013-10-03T11:53:29.000 回答