35
Bonusbeispiel Bonusbeispiel Benedikt Huber Institut für Technische Informatik Technische Universität Wien - 182.709 Betriebssysteme UE WS2012 Based on slides from: Bernhard Frömel 4.Dezember 2012

Benedikt Huber - ti.tuwien.ac.at · I Kernel 2.6.38.7, Debian 5.0.6, Lenny I User Mode Linux (UML) Umgebung im TI-Lab installiert I virtuelle Maschine: Linux wird als User-Prozess

  • Upload
    lykhanh

  • View
    221

  • Download
    0

Embed Size (px)

Citation preview

Bonusbeispiel

Bonusbeispiel

Benedikt Huber

Institut für Technische InformatikTechnische Universität Wien

-182.709 Betriebssysteme UE WS2012Based on slides from: Bernhard Frömel

4.Dezember 2012

Bonusbeispiel Überblick

I Kernel Module und Device Drivers

I Kernel Modul Build Prozess

I Character Devices

I Übungsumgebung

I Bonus Beispiel

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Teil I

Kernel Module und Device Drivers

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

.Quelle: http://www.makelinux.net/kernel_map

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Allgemeines

I Linux Kernel is monolithisch (dh. Kernel und Treiber inRing 0)

I Loadable Kernel Module (LKM) UnterstützungI erweitern den Kernel um zusätzliche FunktionalitätI entwickeln, laden und entfernen von Modulen zur

System-LaufzeitI insbesondere gut geeignet für Device Drivers

(Gerätetreiber)I nur benötigte Treiber zu tatsächlich vorhandenen Geräte

werden geladenI vereinfachte Entwicklung (kein Reboot erforderlich)

I ”Module Stacking”, d.h. aufeinander aufbauende Module,möglich (modprobe(3))

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Kernel Modul (1)

I Kernel Module sind immer serviceorientiert:I Beim Ladevorgang ”einhängen” in Kernelstrukturen, bzw.

Bekanntmachung, welche Services angeboten werdenI Danach nur noch Bearbeitung von Requests

I Keine externen Bibliotheken (insb. keine libc!), aber viele”bekannte” Funktionen trotzdem vertreten

I Formatierten String ausgeben: printk (linux/kernel.h)I linux/string.h: strcpy, strcat, memset, ...

I Limitierte Stackgröße: 4-8 KByte bei 32-bit, 16 Kbyte bei64-bit x86 Architekturen

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Kernel Modul (2)

I Gleichzeitigkeit (Concurrency) beachten!I Sequentieller Code kann immer unterbrochen werden

(schon beim Laden des Moduls! –> ”Module LoadingRaces”)

I Scheduling/PreemptionI InterruptsI Symmetric Multi Prozessor (SMP)

I auf saubere Synchronisation bei shared resources (globaleVariablen, Devices, ...) achten!

I ”manuelle” Freigabe von Ressourcen notwendig: kein”Garbage Collector” - auch nicht bei Modulentfernung perrmmod(8)!

I Portabilität wichtig: keine Annahmen über Seiten- undWortgröße, Endianess, ... treffen.

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

(Userspace) Applikation vs. Kernel Modul

Kriterium Applikation Kernel Modul

Funktion task/serviceorientiert nur serviceorientiertParameter argv Mod. Parameter”Entry Point” main Funktion module_init”Exit Point” ”beliebig” module_exitBibliotheken System (libc, libm, ...) nur KernelStack Größe MByte KByteFloating Point ja nein (CPU context)Zugriffsverletz. Segmentation Fault Kernel FaultRes. Freigabe Termination keine/NeustartSprache ”beliebig” GNU C (C99 Std)

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Device Drivers (1)

I Gerät wird hinter wohldefiniertem Programmierinterfaceabstrahiert (File in /dev/, Ausnahme: Netzwerkgeräte inLinux nicht unter /dev/ auffindbar)

I Policy vs. Mechanism: Treiber sollI keine (möglichst wenige) Regeln/Richtlinien bezüglich

seiner Verwendung dem User aufzwingenI die gesamte (möglichst komplette) Hardwarefunktionalität

anbieten

I Hauptklassen von Device TreibernI Character Device (Stream)I Block Device (Blocks)I Network Device (Packets)

I Einteilung nach Subsystem: USB, SCSI, Firefire, . . .

Bonusbeispiel

Der LinuxKernel

KernelModul

Appplicationvs. KernelModul

DeviceDrivers

Device Drivers (2)

I SecurityI Kernel hat ”max. Rechte” im System, d.h.

Sicherheitsprobleme im Kernel bedeutenSicherheitsprobleme im System

I typische Security-Bugs:I BufferoverflowsI Information-LeakageI Unchecked User-Input

I LizenzierungI Linux lizensiert unter Version 2 der General Public License

(GPL)I Proprietäre Module (d.h. Module die nicht GPLv2

kompatibel lizensiert sind) im Kernel ”toleriert”I Proprietäre Module erhalten aber nicht das komplette

Kernel APII Deklarierung der Lizenz per MODULE_LICENSE Makro

Bonusbeispiel

Setup

Beispiel

Teil II

Build Prozess

Bonusbeispiel

Setup

Beispiel

Kernel Quellen

I Kernel Quellen enthalten neben dem Kernel selbstI Build System basierend auf Unix Make,

–> <kernel_source>/Documentation/kbuildI Interfaces für User-Space Applikationen und Kernel Module

(Header Files)I zahlreiche Architekturen und Device Driver

I Linux Kernel Archiv: www.kernel.orgI ”configured” und ”built” Kernel-tree passend zum

Laufzeitkernel (uname -a)I oft erhältlich als Package in Distributionen (”Kernel

Headers”)I Symlink /usr/src/linux sollte auf Kernelquellen verweisen

I Devel- & Testsystem (e.g. Virtual Machine, . . . ) sinnvoll

Bonusbeispiel

Setup

Beispiel

Compilieren eigener Kernel Module

I “out-of-tree” Builds möglichI dabei Makefile ”two-faced”

I Bei Ausführung im Modulquellverzeichnis: Wechsel inKernel Source Directory und Ausführung des eigentlichenKernel Makefiles um das Modul zu übersetzen

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

I Bei Kernel-Build Einbindung: wird zu Makefilefragment, dasdie gesamte Compile-Info für Kernel-Build Vorgang enthält

obj-m := cmod1.o cmod2.o ...

I Laden und Entfernen von Modulen per insmod(8) undrmmod(8) als Superuser (”root”) zur Laufzeit möglich

I aktuelle Liste der geladenen Modulen: lsmod(8)

Bonusbeispiel

Setup

Beispiel

Hello World Modul, ’Makefile’

% (for kernel build)obj-m := hello_world.o

% (for module build)KERNELDIR = /usr/src/linux

all: modules

modules modules_install clean:$(MAKE) V=1 ARCH=um -C ${KERNELDIR} M=$$PWD $@

Bonusbeispiel

Setup

Beispiel

Hello World Modul, ’hello_world.c’

#include <linux/init.h>#include <linux/module.h>

MODULE_LICENSE("GPL");

static int mod_init(void){

printk(KERN_ALERT "Hello World!\n");return 0;

}

static void mod_exit(void){

printk(KERN_ALERT "Bye World!\n");}

module_init(mod_init);module_exit(mod_exit);

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Teil III

Character Devices

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Synchronisation

I Zugriff auf shared resources muss synchronisiert werdenI Semaphoren

I Initialisierung:sema_init(struct semaphore *, int);

I P Operation: z.B.int down_interruptible(struct semaphore *);

I V Operation: z.B. void up(struct semaphore *);I Als Mutex: Schutz eines kritischen Abschnitts,

Initialisierung mit 1I Prozess wird u.U. geblockt (nicht geeignet für

Interrupthandler)

I SpinlocksI Deaktiviert Interrupts, Busy Waiting (Multiprozessor)I Kann in Interruptbehandlungsroutinen verwendet werden

I atomic_* Funktionen: z.B.void atomic_inc(atomic_t *v);

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Speichermanagement

I Speicherverwaltung sehr flexibel unter Linux (siehe LDD3,Chapter 8: page-oriented, vmalloc, caches, pools, . . . );

I für die meisten Fälle geeignet:I Speicher anfordern: void *kmalloc(size_t, int);I Speicher freigeben: void kfree(void *ptr);

I angeforderter Speicher nicht initialisiert (kann beliebigenInhalt haben)

I freigegebener Speicher wird nicht automatisch gelöscht

int *data = kmalloc(DATA_SIZE, GFP_KERNEL);/* Fehlerbehandlung und

Verwendung von angeforderten Speicher */kfree(data);

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Datenaustausch Kernelspace <-> UserspaceOft notwendig Bufferinhalte vom Kernel-Space in denUser-Space und umgekehrt zu transferieren:

I Niemals ungeprüfte Pointer im Kernel dereferenzieren!

I copy to/from user Interface (asm/uaccess.h) nutzen:

unsigned long copy_to_user(void __user *to,const void *from,unsigned long count);

unsigned long copy_from_user(void *to,const void __user *from,unsigned long count);

I wie memcpy, zusätzlich: Prüfung des User-Space Pointers

I Rückgabe enthält Anzahl der nicht kopierten Bytes (d.h.wenn nicht 0 –> Fehler).

I Kopieroperationen können jederzeit unterbrochen werden(Concurrency!) z.B. angeforderte Page nicht imHauptspeicher

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Character Devices

I zeichenorientierte Geräte, die sich wie Files verhalten z.B.Maus, Keyboard, Serial, ...

I implementieren meist open, close, read und write

I oft nur sequentiell les/schreibbar (z.B. /dev/ttyS0)

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Major/Minor Number

I Special File (mknod(1)) in /dev/ referenziert Device perTyp, Major und Minor Device Number

I Dynamische Anforderung (alloc_chrdev_region) od.statische Zuweisung (register_chrdev_region) möglich

I Kernel verwaltet Character Devices in struct cdev, dieals Member struct file_operations enthält.

I Dabei ist struct inode die Kernel-interneRepräsentation einer Datei, und struct file die einesoffenen Dateideskriptors

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

File Operationen

I struct file_operations (linux/fs.h) enthältFunction Pointer als Members: z.B.

int (*open)(struct inode *,struct file *);int (*release) (struct inode *, struct file *);int (*unlocked_ioctl) (struct inode *,struct file *, unsigned int, unsigned long);

(ioctl vs. unlocked_ioctl:http://lwn.net/Articles/119652/)

ssize_t (*read) (struct file *,char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *,const char __user *, size_t, loff_t *);

loff_t (*llseek) (struct file *, loff_t, int);

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

File OperationenI Device Treiber kann Default-Verhalten der File

Operationen ”überschreiben”I Funktionen werden bei den jeweiligen Operationen (vom

Userspace) auf das Character Device aufgerufenI Ausführung im Kernelspace, im Kontext des aufrufenden

Userspace ProzessesI Setzen des struct module *owner Members wichtig,

sodass Modul nicht aus System entfernt werden kann,solange File Operationen ausgeführt werden.

struct file_operations my_fops = {.owner = THIS_MODULE,.open = my_open,.release = my_release,.unlocked_ioctl = my_ioctl,.read = my_read,.write = my_write,.llseek = my_llseek,};

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

open

struct my_dev{

struct cdev cdev;/* other

members neededfor device */

};

int my_open(struct inode *inode, struct file *filp){

struct my_dev *dev;dev = container_of(inode->i_cdev,

struct my_dev, cdev);filp->private_data = dev;

return 0;}

container_of:http://www.kroah.com/log/linux/container_of.html

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

read/write

This is the Title of the Book, eMatter EditionCopyright © 2005 O’Reilly & Associates, Inc. All rights reserved.

read and write | 65

check the user-space pointer you can invoke __copy_to_user and __copy_from_userinstead. This is useful, for example, if you know you already checked the argument.Be careful, however; if, in fact, you do not check a user-space pointer that you pass tothese functions, then you can create kernel crashes and/or security holes.

As far as the actual device methods are concerned, the task of the read method is tocopy data from the device to user space (using copy_to_user), while the write methodmust copy data from user space to the device (using copy_from_user). Each read orwrite system call requests transfer of a specific number of bytes, but the driver is freeto transfer less data—the exact rules are slightly different for reading and writing andare described later in this chapter.

Whatever the amount of data the methods transfer, they should generally update thefile position at *offp to represent the current file position after successful comple-tion of the system call. The kernel then propagates the file position change back intothe file structure when appropriate. The pread and pwrite system calls have differ-ent semantics, however; they operate from a given file offset and do not change thefile position as seen by any other system calls. These calls pass in a pointer to theuser-supplied position, and discard the changes that your driver makes.

Figure 3-2 represents how a typical read implementation uses its arguments.

Both the read and write methods return a negative value if an error occurs. A returnvalue greater than or equal to 0, instead, tells the calling program how many byteshave been successfully transferred. If some data is transferred correctly and then anerror happens, the return value must be the count of bytes successfully transferred,

Figure 3-2. The arguments to read

Kernel Space(nonswappable)

struct fileBuffer

(in the driver)

User Space(swappable)

Buffer

(in theapplicationor libc)

f_countf_flagsf_mode

f_pos

....

....

copy_to_user()

ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *ppos);

,ch03.22228 Page 65 Friday, January 21, 2005 1:32 PM

.Quelle: LDD3, S65

Bonusbeispiel

Kernelspace

CharacterDevices

FileOperationen

Lifecycle

Lifecycle eines Character Devices

I InitialisierungI Registierung/Allozierung der Character Device Region:

register_chrdev_regionI Initialisierung der Character Device Strukturstruct cdev (inkl. struct file_operations):cdev_init

I Registrierung des Character Devices im Kernel: cdev_addBemerkung: Ab diesem Zeitpunkt muss damit gerechnetwerden, dass das Device verwendet wird - auch wenn diemodule_init Funktion noch nicht fertig ist!

I EntfernungI Deregistrierung des Character Devices: cdev_delI Deregistrierung der Character Device Region:unregister_chrdev_region

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Teil IV

Bonusbeispiel

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Übungsumgebung

I Kernel 2.6.38.7, Debian 5.0.6, Lenny

I User Mode Linux (UML) Umgebung im TI-Lab installiert

I virtuelle Maschine: Linux wird als User-Prozess ausgeführt(Architektur UM)

I ”sichere” Umgebung für riskantes (und rasches) Entwickeln

I Interaktion mit Host per hostfs Filesystem (z.B.Home-Directory kann gemountet werden)

I Interaktion mit User über Pseudo Terminals in/dev/pts/ (z.B. per screen(1) verwendbar)

I weitere Details: siehe Angabe (im myTI)

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Organisatorisches

I Selbststudium: Linux Device Drivers 3rd Edition (LDD3) -zumindest Kapitel 1 bis 3, 5 (Semaphoren)

I Richtlinien:I Beispielabnahme ausschliesslich auf TI-Lab UmgebungI GNU C Standard, i.e. C99 Std. mit GNU Erweiterungen

(statt C89 Standard und gegebenen CFLAGS für alleanderen Beispiele)

I debug Modul Parameter (siehe Angabe)I Coding Style:/usr/src/linux/Documentation/CodingStyle

I SynchronisationI Sauberes Modul Unloading (keine Resourceleaks!)

I Abgabedeadline: 18.01.2013

I Abgabegespräche 21.01.2012, Anmeldung via myTI, TILabor

I Beginn: ab sofort

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Bonusbeispiel: Secvault - Übersicht

I Character Device Driver soll als Kernel Modulimplementiert werden

I Verwaltung von bis zu 4 Secure Vaults (Secvaults)I Größe zwischen 1 Byte und 1 MByte (konfigurierbar)I verschlüsselt nach XOR Verfahren

I Userspace Tool: svctlI anlegen und entfernen von SecvaultsI Löschung (gesamten Speicher mit 0x0 überschreiben)

eines Secvaults.

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Ablauf

I Modul stellt nach dem Laden Control Character Device(/dev/sv_ctl) zur Verfügung

I Userspace Tool svctl kommuniziert per IOCTL Calls mitControl Device (/dev/sv_ctl) des Treibers

I Anlegen, Löschen (mit 0x0 überschreiben) und Entferneneines Secvaults

I liest Schlüssel über stdin (bis zu 10 Byte, wenn weniger:0x0).

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Anlegen

I Überprüfung, ob Secvault schon existiert, falls ja –> FehlerI sonst:

I Erzeugung eines neuen Character DevicesI angeforderten Speicher reservierenI Schlüssel zum Secvault speichern

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Lesen/Schreiben/Löschen/Entfernen

I Beim Lesen/Schreiben *): Anwendung des symmetrischenVerchlüsselungsverfahren XOR abhängig von Positioncrypt(pos, data, key) = data[pos] ⊕ key[pos mod keysize]

I Wenn über Speichergrenze des Secvaultshinausgelesen/geschrieben wird: geeigneteFehlerbehandlung

I Löschanforderung: den gesamten Secvault mit 0x0überschreiben (Operation innerhalb des Moduls!)

I Entfernung: Speicher- und Characterdevicefreigabe *)

*) hier kann auch überprüft werden, ob der Benutzer berechtigtist (siehe Fragen in Angabe)

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Unterschiede LDD3 und Linux 2.6.38

LDD3 für 2.6.10 - API Changes:http://lwn.net/Articles/2.6-kernel-api/zB:

LDD3 2.6.38.7

ioctl unlocked_ioctlinit_MUTEX(&mutex) sema_init(&mutex, 1)current->uid current_uid()

Weitere Änderungen ?–> mailto:[email protected]

Bonusbeispiel

Übungs-umgebung

Org

Angabe

LDD3 vs.2.6.38

Quellen

Quellen und Material

I ”Linux Device Drivers 3rd Edition” (LDD3) von JonathanCorbet, Alessandro Rubini, and Greg Kroah-Hartmanhttp://lwn.net/Kernel/LDD3/

I ”Linux Kernel Development 2nd Edition” von Robert Lovehttp://book.chinaunix.net/special/ebook/Linux_Kernel_Development/0672327201/toc.html

I Makefileempfehlung von user502515,http://stackoverflow.com/questions/4570637/linux-device-driver-symbol-memcpy-not-found