c - Copying a 2D array of char * to user space from kernel space? -


कर्नेल अंतरिक्ष में, मेरे पास निम्न है:

  char * myData [MAX_BUF_SIZE] [ 2];  

मुझे एक कर्नेल विधि परिभाषित करने की आवश्यकता है जो इस डेटा को यूज़र स्पेस में प्रतिलिपि बनाता है, तो मैं इस पद्धति को परिभाषित करने के बारे में कैसे जाना होगा? मुझे निम्नलिखित मिल गया है, लेकिन मुझे पूरा यकीन है कि मैं क्या कर रहा हूं।

  asmlinkage int sys_get_my_data (char __user *** डेटा, int rowLen, int bufferize) {if ( पंक्तिलेन & lt; 1 || बफर साइज़ & lt; 1 || पंक्ति लैन & gt; MAX_BUF_SIZE || बफर आकार & gt; MAX_BUF_SIZE) {वापसी -1; } अगर (copy_to_user (डेटा, मायडाटा, पंक्तिलेन * बफर साइज़ * डेटाकॉन्टर * 2)) {printk (सभी मिनेफाइल प्राप्त करने के लिए उपयोगकर्ता विफलता में कॉपी करें) \ n "); वापसी -1; } वापसी 0; }  

सहायता

आपकी टिप्पणी के अनुसार, ये चार * * मान नल-टर्मिनेटेड स्ट्रिंग्स को इंगित करता है।

अब, आप केवल उस संपूर्ण fileDataMap मेमोरी ब्लॉक यूज़रस्पेस पर कॉपी नहीं कर सकते हैं - ये सिर्फ यूजरस्पेस को चार * मानों का एक समूह देते हैं जो कि कर्नेल स्थान में इंगित करते हैं, इसलिए यह वास्तव में उनका उपयोग करने में सक्षम नहीं होगा। आपको तारों को खुद को यूज़रस्पेस पर प्रतिलिपि बनाने की जरूरत है, न कि केवल संकेत (यह एक "गहरी प्रतिलिपि" है)।

अब, आप इस बारे में कुछ तरीके देख सकते हैं। सबसे सरल यह है कि सभी स्ट्रिंग्स को एक दूसरे के बाद, एक बड़ा char यूज़रस्पेस में सरणी में पैक करें। फिर ब्लॉक के माध्यम से स्कैन करने के लिए यूज़रस्पेस तक, पॉइंटर्स के पुनर्निर्माण के लिए:

  asmlinkage int sys_get_my_data (char __user * डेटा, size_t बफर आकार) {size_t i; के लिए (i = 0; i & lt; MAX_BUF_SIZE; i ++) {size_t s0_len = strlen (फ़ाइल डेटामैप [i] [0]) + 1; आकार_टी s1_len = strlen (फ़ाइल डेटामैप [आई] [1]) + 1; अगर (s0_len + s1_len & gt; बफ़रसिझ) {return -ENOSPC; } यदि (copy_to_user (डेटा, फ़ाइल डेटामैप [i] [0], s0_len)) {वापसी- EINVAL; } डेटा + = s0_len; बफर साइज़ - = s0_len; अगर (copy_to_user (डेटा, फ़ाइल डेटामैप [i] [1], s1_len)) {वापसी- EINVAL; } डेटा + = s1_ len; बफर साइज़ - = s1_ len; } वापसी 0; }  

यह केवल तब ही काम करेगा जब हमेशा MAX_BUF_SIZE स्ट्रिंग-जोय, क्योंकि यूज़रस्पेस को यह जानना होगा कि यह कितनी तार है उन्हें सुरक्षित रूप से उनके माध्यम से स्कैन करने में सक्षम होने के लिए प्राप्त करने की अपेक्षा यदि ऐसा नहीं है, तो आपको उस जानकारी को किसी तरह वापस करना होगा - शायद syscall का रिटर्न वैल्यू स्ट्रिंग-जोड़ी की संख्या हो सकती है?

यदि आप कर्नेल को पॉइंटर तालिका में पुन: निर्माण करना चाहते हैं यूजरस्पेस, आपको ऊपर के रूप में तार की प्रतिलिपि करना होगा, और फिर पॉइन्टर टेबल को भरना होगा - यूज़रस्पेस को दो बफ़र्स पास करना होगा, एक स्ट्रिंग के लिए और पॉइंटर्स के लिए एक होगा।


Comments

Popular posts from this blog

c# - How to capture HTTP packet with SharpPcap -

php - Multiple Select with Explode: only returns the word "Array" -

php - jQuery AJAX Post not working -