2011-05-10 8 views
15

मेरे पास एक ऐसा एप्लिकेशन है जिसमें दो बाहरी कर्नेल मॉड्यूल और एक उपयोगकर्ता स्पेस डिमन है। मैं स्टार्टअप पर सी में लिखे गए डेमॉन कोड से मॉड्यूल लोड करना चाहता हूं, और उन्हें साफ़ निकास पर उतारना चाहता हूं। क्या मैं उन्हें system("modprobe module"); करने से क्लीनर तरीके से लोड कर सकता हूं और संबंधित rmmod का उपयोग करके उन्हें अनलोड कर सकता हूं?सी कोड से लिनक्स कर्नेल मॉड्यूल कैसे लोड किए जा सकते हैं?

उत्तर

0

आप वही कार्य कर सकते हैं जो modprobe और कंपनी करते हैं, लेकिन मुझे संदेह है कि क्लीनर के रूप में चिह्नित किया जा सकता है।

1

मुझे यकीन नहीं है कि क्लीनरsystem से अधिक है।

लेकिन निश्चित रूप से, यदि आप अपने उपयोगकर्ता स्पेस डिमन से मॉड्यूल लोड/अनलोड करना चाहते हैं, तो आप रूट को * के रूप में डिमन चलाने के लिए मजबूर करते हैं, जिसे सुरक्षित के रूप में नहीं माना जा सकता है।

*: या आप सूडर्स फ़ाइल में स्पष्ट आदेश जोड़ सकते हैं, लेकिन यह आपके आवेदन को तैनात करते समय प्रबंधित करने के लिए एक दुःस्वप्न होगा।

3

मैं किसी भी डेमॉन कोड में system() के उपयोग के खिलाफ अनुशंसा करता हूं जो रूट अनुमतियों के साथ चलता है क्योंकि यह सुरक्षा दृष्टिकोण से शोषण करना अपेक्षाकृत आसान है। modprobe और rmmod, वास्तव में, नौकरी के लिए सही उपकरण हैं। हालांकि, यह एक स्पष्ट fork() + exec() का उपयोग करने के लिए थोड़ा क्लीनर और अधिक सुरक्षित होगा।

+1

क्या आपको लगता है .. कांटा और निष्पादन का उपयोग करके प्रक्रिया मॉड्यूल को हटाने के लिए क्लीनर बन जाती है। – kzs

9

insmod/कार्य init_module और delete_module यह करने के लिए है, जो भी एक मानव पेज उपलब्ध का उपयोग rmmod। वे दोनों हेडर को शामिल करने के बजाय extern के रूप में कार्य घोषित करते हैं, लेकिन मैन-पेज कहता है कि उन्हें <linux/module.h> में होना चाहिए।

11

मिनिमल runnable उदाहरण

एक QEMU + Buildroot वीएम और Ubuntu 16.04 मेजबान with this simple parameter printer module पर परीक्षण किया गया।

हम init_module और remove_moduleLinux system calls का उपयोग करते हैं।

ग्लिबैक उनके लिए सी रैपर प्रदान नहीं कर रहा है, इसलिए हम केवल syscall के साथ अपना स्वयं का निर्माण करते हैं।

insmod:

#define _GNU_SOURCE 
#include <fcntl.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <sys/syscall.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 

#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) 

int main(int argc, char **argv) { 
    const char *params; 
    int fd; 
    size_t image_size; 
    struct stat st; 
    void *image; 

    if (argc < 2) { 
     puts("Usage ./prog mymodule.ko [args]"); 
     return EXIT_FAILURE; 
    } 
    if (argc < 3) { 
     params = ""; 
    } else { 
     params = argv[2]; 
    } 
    fd = open(argv[1], O_RDONLY); 
    fstat(fd, &st); 
    image_size = st.st_size; 
    image = malloc(image_size); 
    read(fd, image, image_size); 
    close(fd); 
    if (init_module(image, image_size, params) != 0) { 
     perror("init_module"); 
     return EXIT_FAILURE; 
    } 
    free(image); 
    return EXIT_SUCCESS; 
} 

rmmod:

#define _GNU_SOURCE 
#include <fcntl.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <sys/syscall.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 

#define delete_module(name, flags) syscall(__NR_delete_module, name, flags) 

int main(int argc, char **argv) { 
    if (argc != 2) { 
     puts("Usage ./prog mymodule"); 
     return EXIT_FAILURE; 
    } 
    if (delete_module(argv[1], O_NONBLOCK) != 0) { 
     perror("delete_module"); 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

बिजीबॉक्स स्रोत व्याख्या

बिजीबॉक्स insmod प्रदान करता है, और के बाद से यह अतिसूक्ष्मवाद लिए बनाया गया है, हम कैसे यह अनुमान करने की कोशिश कर सकते हैं वहां से किया जाता है।

संस्करण 1.24.2 पर, प्रविष्टि बिंदु modutils/insmod.c फ़ंक्शन insmod_main पर है।

IF_FEATURE_2_4_MODULES पुराने लिनक्स कर्नेल 2.4 मॉड्यूल के लिए वैकल्पिक समर्थन है, इसलिए हम इसे अभी अनदेखा कर सकते हैं।

यह केवल modutils.c फ़ंक्शन bb_init_module पर आगे बढ़ता है।

  • mmaptry_to_mmap_module के माध्यम से याद करने के लिए फ़ाइल:

    bb_init_module दो बातें प्रयास करता है।

    यह image_size को .ko फ़ाइल के आकार में साइड इफेक्ट के रूप में सेट करता है।

  • यदि यह विफल रहता है, malloc फ़ाइल xmalloc_open_zipped_read_close के साथ स्मृति में फ़ाइल।

    यह फ़ंक्शन वैकल्पिक रूप से फ़ाइल को अनजिप करता है यदि यह ज़िप है, और यह अन्यथा इसे मैलॉक्स करता है।

    मुझे समझ में नहीं आता कि यह ज़िप व्यवसाय क्यों किया जाता है, क्योंकि हम इस पर भी भरोसा नहीं कर सकते क्योंकि try_to_mmap_module चीजों को अनजिप नहीं करता है।

अंत में कॉल आता है:

init_module(image, image_size, options); 

जहां image निष्पादन योग्य है कि स्मृति में डाल दिया गया था, और विकल्प सिर्फ "" यदि हमें और अधिक तर्क के बिना insmod file.elf कहते हैं।

#ifdef __UCLIBC__ 
extern int init_module(void *module, unsigned long len, const char *options); 
extern int delete_module(const char *module, unsigned int flags); 
#else 
# include <sys/syscall.h> 
# define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) 
# define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) 
#endif 

ulibc एक एम्बेडेड libc कार्यान्वयन है, और यह init_module प्रदान करने के लिए लगता है:

init_module से ऊपर प्रदान की जाती है।

यदि यह मौजूद नहीं है, मुझे लगता है कि glibc माना जाता है, लेकिन man init_module के रूप में कहते हैं:

init_module() सिस्टम कॉल glibc द्वारा समर्थित नहीं है। ग्लिबैक हेडर में कोई घोषणा नहीं की गई है, लेकिन, इतिहास के एक क्विर्क के माध्यम से, ग्लिबैक इस सिस्टम कॉल के लिए एबीआई निर्यात करता है। इसलिए, इस सिस्टम कॉल को नियोजित करने के लिए, अपने कोड में इंटरफ़ेस मैन्युअल रूप से घोषित करने के लिए पर्याप्त है; वैकल्पिक रूप से, आप सिस्कोल (2) का उपयोग कर सिस्टम कॉल का आह्वान कर सकते हैं।

बिजीबॉक्स बुद्धिमानी कि सलाह अनुसरण करता है और syscall का उपयोग करता है, जो glibc प्रदान करता है, और जो सिस्टम कॉल के लिए एक सी एपीआई प्रदान करता है।

संबंधित मुद्दे