I am doing a very simple character driver. I have write function:
我正在做一个非常简单的字符驱动程序。我有写功能:
/**********************************************************************
** Called when the device is written to
**********************************************************************/
static ssize_t device_write( struct file *filep, const char *buf,
size_t len, loff_t *f_pos ) {
int i=0,j=0;
int bytesToWrite;
char text[BUFSZ];
char key[256];
int keySize;
// generate key and determine it's size
while( buf[i] != ' '){
key[i] = buf[i];
i++;
}
i++;
while ( buf[i] !='\0'){
text[j] = buf[i];
j++;i++;
}
keySize = strlen(key);
len = len-keySize-1;
if (len < BUFSZ ) bytesToWrite = len;
else if (len >= BUFSZ) {
bytesToWrite = BUFSZ;
}
ksa(state,key,keySize);
prga(state,stream,len);
for (j=0;j<len;j++){
temp_buffer[j] = stream[j]^text[j];
}
down(&isPipeWritten); // if isPipeWritten!=0 ? isPipeWritten-- : wait
down(&pipe);
// clear the buffer
memset( internal_buffer, 0, BUFSZ );
*f_pos = 0;
// copy the data from the user into the internal buffer
if ( copy_from_user( &internal_buffer,buf, bytesToWrite ) != 0 )
return -EFAULT;
up(&isPipeRead); // isPipeRead=1; full
up(&pipe);
return bytesToWrite;
}
So, when writer writes to the device driver it:
因此,当writer写入设备驱动程序时:
- takes a key, which is first string
- takes the rest of text
-
pass key to ksa and prga to generate a cipher.
将密钥传递给ksa和prga以生成密码。
prga returns stream[len]
prga返回流[len]
-
xor text with stream[len]
xor文本与流[len]
- should cop cipher to internall_buffer
取一个键,这是第一个字符串
接受剩下的文字
应该密码到internall_buffer
Here are the problems:
以下是问题:
- can't xor, ubuntu stops.
- and also can not pass string other that buf itself to copy_from_user
不能xor,ubuntu停止。
并且也无法将其他buf本身的字符串传递给copy_from_user
I spend a whole day trying to figure it out, but I am a newbie. Also if you see some variable that is not declared, it means it is global. I just didn't copied that code.
我花了一整天时间想弄清楚,但我是新手。此外,如果您看到一些未声明的变量,则表示它是全局变量。我只是没有复制那段代码。
1 个解决方案
#1
You have some of this backwards. First, you should use copy_from_user
to pull the data from the user buffer into your own local buffer before processing it. You should never directly dereference user pointers (what if, for example, the user hands you a kernel address that contains some other user's private data). The buffer argument is usually declared something like this: const char __user *user_buf
to insure you don't improperly use it.
你有一些倒退。首先,您应该使用copy_from_user将数据从用户缓冲区提取到您自己的本地缓冲区中,然后再进行处理。您永远不应该直接取消引用用户指针(例如,如果用户向您提供包含其他用户私有数据的内核地址)。缓冲区参数通常声明如下:const char __user * user_buf以确保您不会不正确地使用它。
Second, you must make sure not to overflow your buffer, so you should range-check before calling copy_from_user
to make sure that the user data will fit in your internal buffer for example, what if the user passes you a length of 4gig (possibly you can also dynamically allocate the internal buffer if you don't want to impose an artificial limitation).
其次,你必须确保不要溢出你的缓冲区,所以你应该在调用copy_from_user之前进行范围检查,以确保用户数据适合你的内部缓冲区,例如,如果用户通过你4gig的长度怎么办(可能你如果你不想强加人为限制,也可以动态分配内部缓冲区。
Likewise, when copying text (while( buf[i] != ' '){
you must add a length check to ensure you don't run off the end of either source or destination.
同样,在复制文本时(while(buf [i]!=''){您必须添加长度检查以确保您不会在源或目标的末尾运行。
Having done all that, it's not possible for the xor operation itself to cause a kernel panic or oops. That is, a kernel panic (kernel stopping, whatever) almost certainly means that you are accessing memory you should not be accessing, resulting in a kernel page fault. Page faults in kernel code are only allowed in certain well-defined circumstances -- for example, when fulfilling a copy_from_user
-- and even then only on user addresses. Kernel data addresses should never cause page faults.
完成所有这些后,xor操作本身不可能导致内核崩溃或oops。也就是说,内核恐慌(内核停止,无论如何)几乎肯定意味着您正在访问您不应访问的内存,从而导致内核页面错误。内核代码中的页面错误仅允许在某些明确定义的情况下 - 例如,在完成copy_from_user时 - 甚至仅在用户地址上。内核数据地址不应该导致页面错误。
#1
You have some of this backwards. First, you should use copy_from_user
to pull the data from the user buffer into your own local buffer before processing it. You should never directly dereference user pointers (what if, for example, the user hands you a kernel address that contains some other user's private data). The buffer argument is usually declared something like this: const char __user *user_buf
to insure you don't improperly use it.
你有一些倒退。首先,您应该使用copy_from_user将数据从用户缓冲区提取到您自己的本地缓冲区中,然后再进行处理。您永远不应该直接取消引用用户指针(例如,如果用户向您提供包含其他用户私有数据的内核地址)。缓冲区参数通常声明如下:const char __user * user_buf以确保您不会不正确地使用它。
Second, you must make sure not to overflow your buffer, so you should range-check before calling copy_from_user
to make sure that the user data will fit in your internal buffer for example, what if the user passes you a length of 4gig (possibly you can also dynamically allocate the internal buffer if you don't want to impose an artificial limitation).
其次,你必须确保不要溢出你的缓冲区,所以你应该在调用copy_from_user之前进行范围检查,以确保用户数据适合你的内部缓冲区,例如,如果用户通过你4gig的长度怎么办(可能你如果你不想强加人为限制,也可以动态分配内部缓冲区。
Likewise, when copying text (while( buf[i] != ' '){
you must add a length check to ensure you don't run off the end of either source or destination.
同样,在复制文本时(while(buf [i]!=''){您必须添加长度检查以确保您不会在源或目标的末尾运行。
Having done all that, it's not possible for the xor operation itself to cause a kernel panic or oops. That is, a kernel panic (kernel stopping, whatever) almost certainly means that you are accessing memory you should not be accessing, resulting in a kernel page fault. Page faults in kernel code are only allowed in certain well-defined circumstances -- for example, when fulfilling a copy_from_user
-- and even then only on user addresses. Kernel data addresses should never cause page faults.
完成所有这些后,xor操作本身不可能导致内核崩溃或oops。也就是说,内核恐慌(内核停止,无论如何)几乎肯定意味着您正在访问您不应访问的内存,从而导致内核页面错误。内核代码中的页面错误仅允许在某些明确定义的情况下 - 例如,在完成copy_from_user时 - 甚至仅在用户地址上。内核数据地址不应该导致页面错误。