Kernel space and user space 2: content of the system calling user space in the kernel space

Source: Internet
Author: User

How to operate User Files in Linux kernel: Use get_fs () and set_fs (kernel_ds) to call the system call to change permissions, and then use the Kernel File Operation Function to access user space.

(1) macro Introduction
The source code is defined in include/ASM/uaccess. h as follows:

    #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })     #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)     #define USER_DS MAKE_MM_SEG(PAGE_OFFSET)     #define get_ds() (KERNEL_DS)     #define get_fs() (current->addr_limit)     #define set_fs(x) (current->addr_limit = (x)) 

And its annotations are also clear:/** the FS value determines whether argument validity checking shoshould be completed MED or not. If get_fs () = user_ds, checking is already med,
Get_fs () = kernel_ds, checking is bypassed. for historical reasons, these macros are grossly misnamed .*/

Therefore, we can see that the FS value is a flag for checking the parameters. When the system call parameters are required to come from the user space and use the system call in the kernel, set_fs (get_ds () changes the user space limit, that is, expands the user space range, therefore, you can use the parameters in the kernel.

(2) function example: Create a new text in a module and write content to the text.

#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/syscalls.h>#include <asm/unistd.h>#include <asm/uaccess.h>#define MY_FILE "LogFile"//#define MY_FILE "/root/LogFile"asmlinkage long sys_open(const char __user *filename,int flags, int mode);char buf[128];struct file *file = NULL; static int __init init(void){        mm_segment_t old_fs;        int ret = 0;        printk("<0>""Hello, I'm the module that intends to write messages to file./n");        if(file == NULL)                file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);        //                 file = sys_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);        if (IS_ERR(file)) {                printk("<0>""error occured while opening file %s, exiting.../n", MY_FILE);                return 0;        }        memset(buf,0x61,128);        sprintf(buf,"%s", "The Messages is xjkdljflk.");        old_fs = get_fs();        printk("<0>""old_fs is %lx/n",old_fs.seg);        set_fs(KERNEL_DS);        old_fs = get_fs();        printk("<0>""old_fs is %lx/n",old_fs.seg);        printk("<0>""KERNEL_DS is %lx/n",KERNEL_DS);        ret = file->f_op->write(file, (char *)buf, sizeof(buf), &file->f_pos);        if(ret < 0)                printk("<0>""file write failed/n");        set_fs(old_fs);        return 0;}static void __exit fini(void){        if(file != NULL)                filp_close(file, NULL);}module_init(init);module_exit(fini);MODULE_LICENSE("GPL");

The makefile used is as follows:

ifeq ($(KERNELRELEASE),)KERNELDIR := /usr/src/linux-headers-2.6.32-28-genericPWD := $(shell pwd)modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_installclean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .PHONY:modules modules_install cleanelseobj-m := call.oendif

After compilation, execute insmod and rmmod to view the desired result.

(3) process description

Use the flip_open function to open the file and obtain the pointer FP of struct file. Use the pointer FP for corresponding operations. For example, you can use FP-> f_ops-> Read to read the file, and finally use the filp_close () function to close the file.

In short: to use the system call in the kernel space, the parameter address passed to-> write () is the address of the kernel space, on user_ds (user_ds ~ Kernel_ds). If no other processing is performed, in the write () function, the address is deemed to have exceeded the user_ds range. Therefore, the address is regarded as a "deliberate destruction" of the user space ", further execution is not allowed. To solve this problem, set_fs (kernel_ds) expands the space limit that can be accessed to kernel_ds, so that the system can be called smoothly in the kernel!

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.