Comment puis-je allouer de la mémoire dans le noyau Linux pour un char* type de chaîne?
Je suis en train d'allouer de la mémoire pour un char* comme suit.
static ssize_t memo_write(struct file *filp, const char __user *buf,
size_t count, loff_t *f_pos){
ssize_t retval = -ENOMEM;
printk("write function\n");
if((data = kmalloc(strlen(buf), GFP_KERNEL)) == NULL)
printk("kmalloc fail\n");
if(copy_from_user(data, buf, strlen(buf))){
retval = -EFAULT;
goto out;
}
*f_pos += strlen(buf);
retval = strlen(buf);
out:
return retval;
}
"data" est déclarée dans un fichier d'en-tête comme
char *data;
Lorsque j'appelle la fonction d'écriture, le "kmalloc l'échec de la ligne n'est pas atteint, ce qui m'amène à croire que le kmalloc réussi, cependant, les données ne sont pas affichées lorsque je tente de lire à partir de la "data" variable de nouveau.
Plus de prêter à confusion, si je me débarrasser de la kmalloc bits au total, les données peuvent être lues à partir du pilote. Bien que le problème est ensuite elle est suivie par la charge des autres données car je n'ai pas la possibilité de memset() il.
Suis-je à l'aide de kmalloc correctement? Sans doute pas. Comment dois-je faire cela?
De plus, ma fonction de lecture est comme suit.
static ssize_t memo_read(struct file *f, char __user *buf,
size_t count, loff_t *f_pos){
ssize_t retval = 0;
printk("read function\n");
printk("data = %s\n", data);
if(*f_pos >= strlen(data)){
printk("EOF\n");
goto out;
}
if(copy_to_user(buf, data, strlen(data))){
retval = -EFAULT;
goto out;
}
printk("copy_to_user success\n");
*f_pos += strlen(data);
retval = strlen(data);
out:
return retval;
}
Grâce.
- Merci pour ces deux grandes réponses, c'est vraiment d'une grande aide! J'avais marquer à la fois comme la réponse choisie si je pouvais, même si je vais prendre la caf parce qu'il/elle verrouillage fourni et a moins de réputation :p Merci encore!
Vous devez vous connecter pour publier un commentaire.
Vous devriez être en utilisant
strlen_user()
sur l'espace utilisateur aiguille, au lieu destrlen()
- et vous ne devez faire qu'une seule fois, et de le garder autour de lui (autrement, vous avez un potentiel à exploiter de noyau, car une seconde de l'espace utilisateur thread pourrait modifier la mémoire tampon pendant que vous travaillez sur elle).Sinon, vous pouvez utiliser
strncpy_from_user()
.En dehors de cela, la
kmalloc
semble OK.(Mais vraiment, comme ephemient dit, vous devez repenser votre approche et l'utilisation de la
count
argument au lieu de les traiter comme un string).Puisque vous ne pouvez pas compter sur les données écrites dans un fichier en cours de nul chaînes terminées, vous aurez besoin de garder un
data_len
de paramètres de longueur autour des côtés de ladata
. Ensuite, votreread
/write
implémentations serait le long de ces lignes:write
gestionnaire... alors pourquoi ne pas utiliser lecount
argument? Il ne devrait pas être une garantie quebuf
est NUL de terminaison.loff_t
,ssize_t
etsize_t
rend ma peau ramper, il y a très probablement subtile les problèmes de débordement de là.N'oubliez pas de
kfree(data)
dans votre cas d'erreur...Dans tous les cas,
buf
est un pointeur vers la mémoire utilisateur, afin de NE PAS les appelerstrlen(buf)
. Vous devezcopy_from_user
premier. Pourquoi ne pas?
Lire votre gestionnaire suppose que
data
est un NUL de terminaison de chaîne. Quand vous étiez à l'aide d'un tableau, ce qui peut avoir été le cas par accident, mais vous n'avez jamais réellement assurer écrire gestionnaire. Ma conjecture est quecopy_to_user
échoue.Voici un exemple de travail d'une "note de service" module que j'ai écrit jusqu'à maintenant, à l'aide de
kmalloc
:Bien sûr, ce manque de verrouillage et d'autres précautions de sécurité, mais j'espère que cette aide.