Why does a transparent interprit flag cause a segmentation error in C?

I am learning some basics of assembly and C. for training. I decided to write a simple program that disables interrupts and when the user wants to type something in the console that he / she cannot:

#include <stdio.h> int main(){ int a; printf("enter your number : "); asm ("cli"); scanf("%d", &a); printf("your number is %d\n" , a); return 0; } 

but when I compile this with GCC, I got a segmentation error:

 Segmentation fault (core dumped) 

And when I debug it with gdb , I got this message when the program reaches the line asm("cli"); :

 Program received signal SIGSEGV, Segmentation fault. main () at cli.c:6 6 asm ("cli"); 
+6
source share
2 answers

This is because you cannot disable interrupts from a user-space program. All interrupts are controlled by the kernel. You need to do this from kernel space. Before you do this, you first need to study the insides of the kernel, and interrupt play is very important and requires knowledge of the kernel in accordance with my knowledge.

You need to write a kernel module that can interact with user space through the / dev / (or some other) interface. User space code must request a kernel module to disable interrupts.

+12
source

cli is a privileged instruction. This raises the exception #GP(0) "If the CPL is greater (has fewer privileges) than the IOPL of the current program or procedure . " This #GP is what forces Linux to supply SIGSEGV for your process.

On Linux, you can make an iopl(3) system call to increase your IO level to match your 3 CPL ring, and then you can disable interrupts from user space. ( But donโ€™t do this, it is not supported by AFAIK . The alleged use case for iopl is to use in and out instructions from user space with high port numbers, not cli / sti . X86 just uses the same permissions for both.)

You will probably damage your system if you do not immediately enable interrupts, or maybe even if you do. Or at least ruin this processor in a multi-core system. Basically, do not do this if you are not ready to press the reset button, that is, turn off X11, save your files and run sync . Also remount your read-only file systems.

Or try it on a virtual machine or simulator such as BOCHS, which will allow you to work with the debugger, even if interrupts are disabled. Or try it when booting from a USB drive.

Note that disabling interrupts disables external interrupts. Software generated interrupts, such as int $0x80 , are still accepted, but system calls with interrupts disabled are probably even worse ideas. (This may work, but the kernel saves / restores EFLAGS, so it probably wonโ€™t return to user space with interrupts re-enabled. However, if interrupts are disabled for a long time, this is a bad thing to delay the interrupt.)


If you want to play with disabling interrupts as a beginner, you should probably do this from a toy boot sector program that uses BIOS calls for I / O. Or just look at the source of the Linux kernel in some places where it disables / enables interrupts if you are wondering why this can be done.

IMO, "normal" asm in user space is very interesting. With performance counters, you can see how the processor decodes and executes instructions. See the links in the wiki tags for tutorials, manuals, and performance tuning information.

+2
source

All Articles