2017-08-23 1 views
2

Hier wird die Struktur erhalte ich:Wie eine Struktur kopieren einen Zeiger vom Benutzerraum enthält, ist auf Kernel

struct my_struct { 
    int size; 
    int *buffer; 
}; 

Nun, ich möchte copy_from_user eine Variable aus User-Space kopieren Raum auf Kernel verwenden, aber es funktioniert nicht scheinen zu arbeiten. Was ich tue, ist dies:

im User-Space mir eine Variable struct my_struct data erklären, die ich in initialisieren und es auf einen ioctl passieren, und im Kernel Ich nenne copy_from_user(&mydataInkernel, arg, sizeof(mydataInkernel)) nach dem ich die richtigen Speicher für den Zeiger zuweisen und wieder aufrufe copy_from_user(mydataInkernel.buffer, arg + 4, mydataInkernel.size). Ich weiß nicht, was ich falsch mache, aber es funktioniert nicht.

Ist die erste Kopie kopiert auch alle Daten, auf die von mydataInkernel.buffer?

Gibt es eine Möglichkeit, dies einfach copy_from_user mit zu tun?

UPDATE 1: Für die Größe eines Zeigers auf meiner Architektur ist es in der Tat 8 Byte (x86_64). Um es klarer zu sagen: Ich schreibe einen Gerätetreiber, um Daten aus dem Benutzerbereich mit ioctl in den Kernel-Bereich zu übertragen. So, hier ist der Code, den ich versuche zu tun, um den Puffer zu erhalten:

 ret_val = copy_from_user(dma_info, (ioctl_dma *)arg, sizeof(dma_info)); 
    if (ret_val) 
      printk(KERN_WARNING "COPY_FROM_USER failed !"); 
    else 
      ret_val = copy_from_user(dma_info->buffer, (ioctl_dma *)arg->buffer, dma_info->taille); 

    if (ret_val) 
      printk(KERN_WARNING "COPY_FROM_USER failed !"); 
    else 
    { 
     //Do the treatment 
    } 

Und hier ist der Prototyp der Funktion ioctl:

long pci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 

so glaube ich nicht, meine zweite copy_from_user korrekt ist sogar nach der Besetzung.

Nb: dma_info ist vom Typ die oben definierte Struktur.

Antwort

3

wenn Sie die ursprüngliche Struktur in kopiert, warum können Sie nicht nur copy_from (Arg-> Puffer, ....) anstelle von Spielen wie arg + 4 zu spielen?

da kein Code wurde gezeigt, dass es schwer für Sie sicher, zu sagen, aber wahrscheinlich ist das Problem in der oben. Offset von 'Puffer' ist nicht 4 Bytes. Es ist 8 aufgrund von Ausrichtungsanforderungen, unter der Annahme von x86_64.

es klar zu machen:

  1. Kopie aus zu einem lokalen Objekt
  2. bestätigen, dass die Puffergrößen vernünftig aussieht (zB es ist nicht Megabyte groß, wenn Sie nur Kilobyte erwarten)
  3. erstellen andere lokales Objekt. Verteilen Sie genügend Speicher für den Puffer und weisen Sie dem lokalen Objekt
  4. die Adresse des Puffers aus der in Schritt 1 erstellten Kopie zu (z. B. localobj-> buffer), und kopieren Sie diese aus dem Puffer.
+0

Vielen Dank für die Antwort. Ich habe die Frage aktualisiert. Ich hoffe, es gibt jetzt mehr Informationen. – manabinto

Verwandte Themen