Учитывая заданный вопрос и значительные проблемы, обнаруженные в другом месте в коде, я полагаю, что вы программист для начинающих C и, возможно, начинающий программист в целом. Поэтому я настоятельно рекомендую вам не играть с внутренними компонентами ядра. Намного проще писать и отлаживать содержимое пользовательского пространства.
Я также должен отметить, что комментарии, которые могут быть найдены ниже вопроса, мне свойственны тем, что они касаются исключительно незначительных точек, игнорируя общую картину.
Сначала я обработаю часть пользовательского пространства, а затем прокомментирую код ядра.
int main()
{
char buf[100];
В вашем фактическом коде код функции также начинается в начале строки? Обычно люди отступают не менее чем на 4 пробела, если не 8. Или вкладка в этом отношении.
char i = 0;
Неиспользованная переменная.
char tag=0;
Почему здесь установлено 0 и почему стиль отличается от вышеуказанной строки? ("=" vs "")
int fp;
Файловые дескрипторы обычно называются «fd». 'fp' используется для вещей, возвращаемых, например, Еореп.
char *val[10];
char *rval[10];
unsigned int a =18440;
unsigned int d =1;
Еще один стиль назначения.
memset(buf, 0, 10);
Почему?
tag=1;
Это перезаписывает присвоение в декларации.
fp = open("/dev/dd",O_RDWR);
if (fp<0)
{
printf("file failed to open\n");
Это должно печатать фактическую полученную ошибку, например. с ужасом. Также обратите внимание, что программа продолжает выполнение, несмотря на ошибку.
}
sprintf(val[1],"%d%x%x",tag,a,d);
Как было правильно отмечено в одном из комментариев, значение Валу [1] не определен и письменной форме, что это неопределенное поведение. Учитывая серьезность проблемы, я думаю, вам нужно перечитать уроки о указателях и обработке строк.
write(fp,val[1],strlen(val[1]));
StrLen легко избежать путем захвата возвращаемого значения Sprintf вместо
sprintf(rval[1],"%d%x",tag,a);// statement that causes segmentation fault
Той же проблемы, как и в предыдущем Sprintf.
return 0;
}
Теперь часть ядра. Пока вставленный образец неполный, достаточно заметить, что модуль ошибочен.
static ssize_t dev_write(struct file *filp, const char *buff, size_t len, loff_t *off)
{
short c=0;
short ind =0;
short count=0;
Почему эти типы короткие? Это проблема, о которой говорилось ниже. Также почему вы устанавливаете их здесь 0?
memset(msg,0,100);
Почему memset даже выполнен?
Неизвестно, что такое msg, но повторные 100 сильно намекают на неправильный код. Если это статический буфер, следует использовать sizeof (msg). В противном случае должен быть макрос или переменная с размером.
readPos=0;
Это, скорее всего, неверно.
while(len>0)
len не был проверен относительно размера буфера, поэтому, в частности, вы можете начать писать через буфер. Также отметим, как имеющий специальный способ выражения размера буфера позволило бы избежать повторения другого числа 100.
{
msg[count++]=buff[ind++];
Len имеет тип size_t, который значительно длиннее, чем короткие, который используется как для подсчета и Ind есть. Таким образом, в деталях для размеров, больших, чем у представимых с положительным знаком, это будет практически переворачиваться с + 32k до -32k. То есть, вы начнете писать материал до в буфер. Если это произойдет, чтобы не сбой, вы повторите цикл, предоставленный достаточно большой len.
Но это действительно второстепенный момент, поскольку доступ к буферу пользовательского пространства выполняется неправильно. Цитировать себя из других источников: Доступ к этому способу - это угроза безопасности и надежности. Рассмотрите, что происходит, когда пользователь передает адрес чего-либо внутри ядра или является мусором. Также он будет работать неправильно в нескольких случаях (например, SMAP или архитектуры, у которых пространство адресов ядра разделено на пространство пользователей).
Вам нужно get_user, copy_from_user или подобное.
len--;
}
Где находится 'msg'? Что это? Была ли сделана компиляция с включенными предупреждениями? Любые предупреждения? – chux
'val [1]', 'char *', присваивается 'sprintf()' без присвоенного ему значения. 'sprintf (val [1],"% d% x% x ", tag, a, d);' получает указатель на мусор. – chux
'char * val [10]; char * rval [10]; '->' char val [24]; char rval [24]; ',' snprintf (val, sizeof (val), "% d% x% x", tag, a, г) и т. д. – BLUEPIXY