Networking / Beginners

Kernel modules

Kernel modules are dynamic extensions to the kernel that can be added without requiring a kernel rebuild or even a reboot. Kernel modules allow for the following:

  • The dynamic extension of kernel capabilities after the detection of new hardware-When a Personal Computer Memory Card International Association (PCMCIA) card is inserted into a UNIX laptop, the operating system can load the appropriate kernel modules. Adding a Universal Serial Bus (USB) device invokes a similar response.
  • The rapid testing and modification of kernel capabilities under development-The system call developer does not have to go through timeconsuming rebuilds and reboots just to test a new version.
  • The size of the kernel loaded at boot time can be kept smaller-Many capabilities are designated as loadable modules, so the boot time size of the kernel is kept small and manageable.

A UNIX administrator must know how to check for root kits that have been loaded as a kernel module. The lsmod command will list kernel modules that have been loaded. The following is a subset of typical modules loaded in a Linux 2.4 kernel:

Module 		Size 	Used by 	Tainted: PF
i810_audio 	27720 	1 	(autoclean)
ac97_codec 	13640 	0 	(autoclean) [i810_audio]
soundcore 	6404 	2 	(autoclean) [i810_audio]
agpgart 	47776 	3 	(autoclean)
nvidia 		2126120 6 	(autoclean)
parport_pc 	19076 	1 	(autoclean)
lp 		8996 	0 	(autoclean)
parport 	37056 	1 	(autoclean) [parport_pc lp]
ipt_state 	1048 	3 	(autoclean)
iptable_nat 	21720 	0 	(autoclean) (unused)
ip_conntrack 	26976 	2 	(autoclean) [ipt_state iptable_nat]
iptable_filter 	2412 	1 	(autoclean)
ip_tables 	15096 	5 	[ipt_state iptable_nat iptable_filter]
sg 		36524 	0 	(autoclean)
sr_mod 		18136 	0 	(autoclean)
ide-scsi 	12208 	0
scsi_mod 	107160 	3 	[sg sr_mod ide-scsi]
ide-cd 		35708 	0
cdrom 		33728 	0 	[sr_mod ide-cd]
keybdev 	2944 	0 	(unused)
mousedev 	5492 	1
hid 		22148 	0 	(unused)
input 		5856 	0 	[keybdev mousedev hid]
usb-uhci 	26348 	0 	(unused)
usbcore 	78784 	1 	[hid usb-uhci]
ext3 		70784 	7
jbd 		51892 	7 	[ext3]

System calls

A system call is a request to the operating system kernel for access to critical resources. System calls are accomplished using special instructions that allow a switch to the supervisor mode. These calls are the services provided by the kernel to application programs. In other words, a system call is a routine that performs a system-level function on behalf of a process. All system operations are allocated, initiated, monitored, manipulated, and terminated through system calls.

System calls can assist an administrator in evaluating an application's security. By examining calls that an application makes to the kernel, an administrator can determine if a security risk is involved. By viewing the system calls made by a process, it can be determined if the hard drive is being accessed when it should not be. Also, the system calls will reveal network access in a process that has no business on the network.

On a Linux system, the strace command is a system call tracer tool that prints out a trace of all the system calls made by a process or application. The ltrace command will similarly print out all library calls made. On FreeBSD you can use ktrace, and on Solaris truss.

The following example is a session that shows the use of strace on a simple Hello World program. First the program source is listed:

# cat helloworld.c
/*

* helloworld - simple hello world program
*/

#include <stdio.h>
int main(int argc, char **argv) {
	printf("Hello World\n");
}

Now the program is executed normally:

# ./a.out
Hello World

Finally, the program is executed with strace:

# strace ./a.out
execve("./a.out", ["./a.out"], [/* 35 vars */]) = 0
uname({sys="Linux", node="localhost.localdomain", ...}) = 0
brk(0) = 0x8049510
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0x40016000
open("/etc/ld.so.preload", O_RDONLY) 	= -1 ENOENT (No such file or
directory)
open("/etc/ld.so.cache", O_RDONLY) 	= 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=81158, ...}) = 0
old_mmap(NULL, 81158, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
close(3) 				= 0
open("/lib/tls/libc.so.6", O_RDONLY) 	= 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`V\1B4\0"..., 512)
= 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1531064, ...}) = 0
old_mmap(0x42000000, 1257224, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0x42000000
old_mmap(0x4212e000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED,
3, 0x12e000) = 0x4212e000
old_mmap(0x42131000, 7944, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x42131000
close(3) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0x400169e0,
limit:1048575, seg_32bit:1, contents:0, read_exec_only:0,
limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0x40017000, 81158) = 0
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 3), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x40017000
write(1, "Hello World\n", 12Hello World) 	= 12
munmap(0x40017000, 4096) 		= 0
exit_group(12) 				= ?

When strace is run on a program that accesses the network, you see certain calls that belie that access:

# strace ping -c 1 192.168.131.131
execve("/bin/ping", ["ping", "-c", "1", "192.168.131.131"], [/* 35 vars
*/]) = 0
    <lines deleted>
socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3
getuid32() 				= 0
setuid32(0) 				= 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(1025),
sin_addr=inet_addr("192.168.131.131")}, 16) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(32796),
sin_addr=inet_addr("192.168.123.10")}, [16]) = 0
close(4) = 0
setsockopt(3, SOL_RAW, ICMP_FILTER,
~(ICMP_ECHOREPLY|ICMP_DEST_UNREACH|ICMP_SOURCE_QUENCH|ICMP_REDIRECT|ICMP_T
IME_EXCEEDED|ICMP_PARAMETERPROB), 4) = 0
setsockopt(3, SOL_IP, IP_RECVERR, [1], 4) = 0
setsockopt(3, SOL_SOCKET, SO_SNDBUF, [324], 4) = 0
setsockopt(3, SOL_SOCKET, SO_RCVBUF, [65536], 4) = 0
getsockopt(3, SOL_SOCKET, SO_RCVBUF, [131072], [4]) = 0
brk(0) 					= 0x8062c80
brk(0x8063c80) 				= 0x8063c80
brk(0) 					= 0x8063c80
brk(0x8064000) 				= 0x8064000
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 6), ...}) = 0
    <lines deleted>
exit_group(0) = ?
[Previous] [Contents] [Next]