Creating a device-file node An introduction to some privileged Linux system-calls (needed for an...

15
Creating a device-file node An introduction to some privileged Linux system- calls (needed for an upcoming programming exercise)

Transcript of Creating a device-file node An introduction to some privileged Linux system-calls (needed for an...

Page 1: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Creating a device-file node

An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Page 2: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

A device-driver example

• We want to build a simple device-driver, one that would let ordinary applications read and/or write to the CMOS memory (e.g. to adjust the date or time-of-day)

• This will require that we have a so-called device ‘special’ file in the ‘/dev’ directory

• Creating such a file normally requires the privileges of a System Administrator – but could be accomplished via a suitable LKM

Page 3: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

The Linux commands

• If a System Administrator wanted to setup a device-file in the ‘/dev’ directory named ‘cmos’ that has read-and-write privileges, the following commands would be used:

root# mknod /dev/cmos c 70 0root# chmod a+rw /dev/cmos

• Here the ‘c’ argument indicates that the file-node is for a ‘character-mode’ device

• Values 70 and 0 are arbitrary id-numbers

Page 4: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Removing a device-file

• To delete a file from the ‘/dev’ directory, the SysAdmin uses the ‘unlink’ command:

root# unlink /dev/cmos

• Because of standard privilege-restrictions on the ‘/dev’ directory, these commands will fail if executed by unprivileged users

• Students have not been given sufficient privileges to successfully execute these ‘mknod’, ‘chmod’ and ‘unlink’ commands

Page 5: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

LKM’s have full privileges

• But CS students in this class DO possess privileges that allow them to install, and to remove, Linux kernel modules:

user$ /sbin/insmod cmos.kouser$ /sbin/rmmod cmos.ko

• While installed, modules execute inside the kernel itself, with no privilege barriers

• Hence we should be able to perform the steps necessary to create a device-file!

Page 6: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Developers disapprove!

• The Linux developers want a ‘secure’ OS, so they have not made it convenient for us to create modules that would bypass the expected privilege-restrictions

• For example, they use ‘information hiding’ capabilities of the GNU “C” compiler to conceal the locations of kernel-code that performs ‘mknod’, ‘chmod’, and ‘unlink’

Page 7: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

‘Open Source’ philosophy

• At the same time, the Linux developers do adhere to the ‘Open Source’ philosophy – the kernel’s source-files are available in a tree-structured sub-directory:

$ cd /usr/src/linux

• The protocol for invoking system-services is widely known, and the ID-numbers for system-calls are in this header-file:

$ cat include/asm/unistd.h

Page 8: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

How to invoke ‘unlink’

• This in-line assembly language code, used within an LKM, can ‘unlink’ a device-file:

#include <asm/uaccess.h> // for get_fs(), set_ds()char pathname[] = “/dev/cmos”; // pathname for file to be ‘unlinked’int retval; // for the system-call’s return-value

{set_fs( get_ds() ); // allow kernel to address our dataasm(“ pushal “); // preserve registersasm(“ mov $10, %eax “); // ID for ‘sys_unlink()’asm(“ mov $pathname, %ebx “); // address of pathnameasm(“ int $0x80 “); // invoke kernel serviceasm(“ mov %eax, retval “); // save the return-valueasm(“ popal “); // recover registers

}

Page 9: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

How to invoke ‘mknod’

#include <asm/uaccess.h> // for get_fs(), set_ds()char pathname[] = “/dev/cmos”; // pathname for file to be ‘unlinked’int retval; // for the system-call’s return-value

{set_fs( get_ds() ); // allow kernel to address our dataasm(“ pushal “); // preserve registersasm(“ mov $14, %eax “); // ID for ‘sys_mknod()’asm(“ mov $pathname, %ebx “); // address of pathnameasm(“ mov $020000, %ecx “); // S_IFCHR constantasm(“ mov $70, %edx “); // our driver ID-numberasm(“ shl $8, %edx “); // DH=major, DL=minorasm(“ int $0x80 “); // invoke kernel serviceasm(“ mov %eax, retval “); // save the return-valueasm(“ popal “); // recover registers

}

Page 10: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

How to invoke ‘chmod’

#include <asm/uaccess.h> // for get_fs(), set_ds()char pathname[] = “/dev/cmos”; // pathname for file to be ‘unlinked’int retval; // for the system-call’s return-value

{set_fs( get_ds() ); // allow kernel to address our dataasm(“ pushal “); // preserve registersasm(“ mov $15, %eax “); // ID for ‘sys_chmod()’asm(“ mov $pathname, %ebx “); // address of pathnameasm(“ mov $000666, %ecx “); // read-and-write by allasm(“ int $0x80 “); // invoke kernel serviceasm(“ mov %eax, retval “); // save the return-valueasm(“ popal “); // recover registers

}

Page 11: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Use ‘man’ for prototypes

• Many of the Linux system-calls use the names of standard library-functions and employ the same function-arguments

• So the ‘man’ page for the library-function will often give the system-call’s prototype

• Example: $ man 2 mknod

• (You need the ‘2’ here -- or you’ll get the manual-page for the ‘mknod’ command)

Page 12: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Parameter-passing rule

• Assembly language code that invokes a system-call always uses register EAX to pass the system-call’s ID-number

• The system-call’s parameters (up to five) are then passed to the kernel in these registers (and in this order):

EBX, ECX, EDX, ESI, EDI

• Obviously this rule would only apply to a Linux version for the 32-bit x86 platforms

Page 13: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

In-class exercise #1

• Compile and install our ‘tempcdev.c’ LKM (from the class website), then verify using the ‘ls’ command that the ‘/dev/cmos’ file exists (and look at its access-permissions)

• Remove that LKM, and use ‘ls’ to confirm that the ‘/dev/cmos’ file has been deleted

• Use the ‘dmesg’ command to display the messages in your machine’s kernel logfile

Page 14: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

In-class exercise #2

• The file created by our ‘tempcdev.c’ LKM has ‘read-only’ permissions. So can you modify its ‘module_init()’ function so that the ‘/dev/cmos’ file will get created with both ‘read’ and ‘write’ access-privileges?

Page 15: Creating a device-file node An introduction to some privileged Linux system-calls (needed for an upcoming programming exercise)

Reminder!

• Information presented in tonight’s lesson carries with it the responsibility of ethical behavior on your part – do not misuse it!

• You are NOT authorized to look at other users’ files -- nor to erase or modify files which do not belong to you