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);
            }

ここで何か見逃しましたか?

更新しました:

データを一時的に保存しstr、ユーザーにコピーする前に 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(...)コピーします。_size2 つの間に不一致があると、ヒープ メモリが破損します。
  • strlen()必要なバッファサイズを検出するために使用しますが、memcpy()後で実行します。通常str*()、機能と機能を混在させるべきではなくmem*()、どちらか一方にとどまります。
于 2013-10-03T11:53:29.000 に答える