সি এর মধ্যে থেকে শেল কমান্ড কল করা কি ভাল ধারণা?


50

একটি ইউনিক্স শেল কমান্ড আছে ( udevadm info -q path -n /dev/ttyUSB2) যা আমি একটি সি প্রোগ্রাম থেকে কল করতে চাই। প্রায় এক সপ্তাহের লড়াইয়ের সাথে আমি নিজেই এটি পুনরায় বাস্তবায়ন করতে পারি, তবে আমি এটি করতে চাই না।

আমার কাছে কেবল কল করার পক্ষে এটি কি চর্চা করে ব্যাপকভাবে গ্রহণযোগ্য popen("my_command", "r");, বা অগ্রহণযোগ্য সুরক্ষা সমস্যাগুলি এবং সামঞ্জস্যতার সমস্যাগুলিকে ফরোয়ার্ড করবে? এটির মতো কিছু করা আমার পক্ষে খারাপ লাগছে, তবে কেন এটি খারাপ হবে তা নিয়ে আমি আঙুল রাখতে পারি না।


8
একটি বিষয় বিবেচনা করতে হবে ইনজেকশন আক্রমণ।
মেটাফাইট

8
আমি মূলত সেই ক্ষেত্রেই ভাবছিলাম যেখানে আপনি শেল কমান্ড আর্গুমেন্ট হিসাবে ব্যবহারকারী ইনপুট সরবরাহ করেছিলেন।
মেটাফাইট

8
কেউ কি udevadmআপনার প্রোগ্রামের মতো একই ডিরেক্টরিতে কোনও দূষিত এক্সিকিউটেবল রাখতে এবং সুবিধাগুলি বাড়ানোর জন্য এটি ব্যবহার করতে পারেন? আমি ইউনিক্স সুরক্ষা সম্পর্কে বেশি কিছু জানি না, তবে আপনার প্রোগ্রামটি কি চালানো হবে setuid root?
অ্যান্ড্রু পিলিজার

7
@ অ্যান্ড্রুপিলাইজার যদি বর্তমান ডিরেক্টরিটি যদি না থাকে PATH, তবে না - এটি দিয়ে চালানো উচিত ./udevadm। যদিও আইআইআরসি উইন্ডোজ একই-ডিরেক্টরি এক্সিকিউটেবলগুলি চালিত করবে।
ইজকাটা

4
যখনই সম্ভব শেলটি ছাড়াই পছন্দসই প্রোগ্রামটি সরাসরি আবেদন করুন।
কোডসইনচওস

উত্তর:


58

এটি বিশেষত খারাপ নয়, তবে কয়েকটি ক্যাভেট রয়েছে।

  1. আপনার সমাধানটি কী বহনযোগ্য হবে? আপনার নির্বাচিত বাইনারি কি সর্বত্র একই কাজ করবে, ফলাফলগুলিকে একই ফর্ম্যাটে আউটপুট দেবে? LANGইত্যাদির সেটিংসে কি এটি আলাদাভাবে আউটপুট পাবে ?
  2. এটি আপনার প্রক্রিয়াতে কত অতিরিক্ত বোঝা যুক্ত করে? বাইনারি ফলাফলগুলি আরও অনেক বেশি লোডের জন্য তৈরি করা এবং লাইব্রেরি কলগুলি সম্পাদন করার চেয়ে বেশি সংস্থান প্রয়োজন (সাধারণত কথা বলা)। এটি কি আপনার দৃশ্যে গ্রহণযোগ্য?
  3. সুরক্ষা সমস্যা আছে? কেউ কি আপনার নির্বাচিত বাইনারিটিকে অন্যের সাথে প্রতিস্থাপন করতে পারে এবং এরপরে ঘৃণ্য কাজ সম্পাদন করতে পারে? আপনি কি আপনার বাইনারি ব্যবহারকারীর দ্বারা সরবরাহিত আরোগুলি ব্যবহার করেন এবং সেগুলি সরবরাহ করতে পারে ;rm -rf /(উদাহরণস্বরূপ) (নোট করুন যে কয়েকটি এপিআই আপনাকে কমান্ড লাইনে সরবরাহ করার চেয়ে আরোগুলি আরও সুরক্ষিতভাবে নির্দিষ্ট করতে দেয়)

বাইনারি আউটপুট পার্স করা সহজ (যখন প্রয়োজন হয় - আপনার কেবলমাত্র একটি প্রস্থান কোডের প্রয়োজন হতে পারে) এবং আমারও এটি করার দরকার নেই এমন আমি যখন পরিবেশের পূর্বাভাস দিতে পারি তখন আমি সাধারণত বাইনারিগুলি নির্বাহ করে প্রায়ই।

আপনি যেমন উল্লেখ করেছেন, অন্য সমস্যাটি হ'ল বাইনারি যা করে তা প্রতিলিপি করা কতটা কাজ? এটি কোনও লাইব্রেরি ব্যবহার করে আপনি কীভাবে সুবিধা অর্জন করতে পারেন?


13
Forking a binary results in a lot more load and requires more resources than executing library calls (generally speaking). এটি যদি উইন্ডোতে থাকে তবে আমি সম্মত হব। যাইহোক, ওপি ইউনিক্স নির্দিষ্ট করে যেখানে কাঁটাচামচ কম খরচ হয় তা বলার অপেক্ষা রাখে না যে লাইব্রেরিটি লোডিংয়ের চেয়ে গতিময়ভাবে লোড করা খারাপ কিনা say
ওয়ালেক

1
আমি সাধারণত একটি লাইব্রেরি একবার লোড হবে আশা করি , বাইনারি একাধিকবার কার্যকর করা যেতে পারে। সর্বদা হিসাবে, এটি ব্যবহারের পরিস্থিতির উপর নির্ভরশীল, তবে এটি বিবেচনা করা দরকার (যদি পরে তা বরখাস্ত করা হয়)
ব্রায়ান অগ্নিউ

3
কোন Windows এ "forking", তাই উদ্ধৃতি হয়েছে ইউনিক্স-নির্দিষ্ট হতে হবে।
কোডি গ্রে

5
এনটি কার্নেল কাঁটাচামচ সমর্থন করে, যদিও এটি উইন 32 এর মাধ্যমে উন্মুক্ত হয় না। যাইহোক, আমি বিশ্বাস করব যে কোনও বাহ্যিক প্রোগ্রাম পরিচালনার ব্যয়টি ২০১ from সালের execচেয়ে বেশি আসবে fork। বিভাগ লোড হচ্ছে, ভাগ করা অবজেক্টগুলিতে লিঙ্ক করা, প্রতিটির জন্য চালক কোড চালানো। এবং তারপরে ইনপুট এবং আউটপুট উভয়ের জন্য সমস্ত তথ্যকে অন্য দিকে পাঠ্যকে অন্যদিকে পার্স করতে হবে।
স্পেকট্রা

8
ন্যায়সঙ্গত হওয়ার জন্য, udevadm info -q path -n /dev/ttyUSB2উইন্ডোজটিতে যেভাবেই কাজ করা যাচ্ছে না তাই পুরো ফোর্কিং আলোচনাটি কিছুটা তাত্ত্বিক।
এমসাল্টারস

37

একবার আপনি কোনও সম্ভাব্য ভেক্টর পরিচয় করিয়ে দেওয়ার পরে ইঞ্জেকশন দুর্বলতার বিরুদ্ধে রক্ষা করার জন্য এটি অত্যন্ত যত্নবান হয়। এটি এখন আপনার মনের সর্বাগ্রে রয়েছে, তবে পরে আপনাকে বাছাই করার দক্ষতার প্রয়োজন হতে পারে ttyUSB0-3, তারপরে সেই তালিকাটি অন্য জায়গায় ব্যবহার করা হবে যাতে এটি একক দায়িত্বের নীতিটি অনুসরণ করতে ফ্যাক্টর হয়ে যায়, তারপরে কোনও গ্রাহকের প্রয়োজনের প্রয়োজন হয় তালিকার একটি স্বেচ্ছাসেবক ডিভাইস, এবং বিকাশকারীরা যে পরিবর্তনটি করে তা কোনও ধারণা রাখে না যে তালিকাটি শেষ পর্যন্ত অনিরাপদভাবে ব্যবহার করে gets

অন্য কথায়, কোডটি যেন আপনি জানেন যে সবচেয়ে অসতর্ক বিকাশকারী কোডের আপাতদৃষ্টিতে সম্পর্কযুক্ত অংশে একটি অনিরাপদ পরিবর্তন করছে।

দ্বিতীয়ত, ডকুমেন্টেশন নির্দিষ্টভাবে সেগুলিকে চিহ্নিত না করে সিএলআই সরঞ্জামগুলির আউটপুট সাধারণত স্থিতিশীল ইন্টারফেস হিসাবে বিবেচিত হয় না। আপনি যে স্ক্রিপ্টটি চালাচ্ছেন তার জন্য আপনি এগুলি গণনা ঠিক করতে পারেন যে আপনি নিজেরাই সমস্যার সমাধান করতে পারেন, তবে কোনও গ্রাহকের কাছে আপনি মোতায়েন করার মতো কিছু নয়।

তৃতীয়ত, আপনি যদি আপনার সফ্টওয়্যার থেকে কোনও মান আহরণের সহজ উপায় চান, তবে অন্য কেউও এটি চান এমন সম্ভাবনা রয়েছে। একটি লাইব্রেরির সন্ধান করুন যা ইতিমধ্যে আপনি যা চান তা করে। libudevআমার সিস্টেমে ইতিমধ্যে ইনস্টল করা ছিল:

#include <libudev.h>
#include <sys/stat.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    struct stat statbuf;

    if (stat("dev/ttyUSB2", &statbuf) < 0)
        return -1;
    struct udev* udev = udev_new();
    struct udev_device *dev = udev_device_new_from_devnum(udev, 'c', statbuf.st_rdev);

    printf("%s\n", udev_device_get_devpath(dev));

    udev_device_unref(dev);
    udev_unref(udev);
    return 0;
}

সেই লাইব্রেরিতে আরও কার্যকর কার্যকারিতা রয়েছে। আমার অনুমান যদি আপনার এটির প্রয়োজন হয় তবে সম্পর্কিত কিছু কাজ খুব কার্যকর হয়ে যেতে পারে।


2
ধন্যবাদ. আমি এতদিন লাইবুদেবের সন্ধানে কাটিয়েছি। আমি সন্ধান করতে পারি না!
johnny_boy

2
আমি দেখতে পাচ্ছি না যে "ইঞ্জেকশন দুর্বলতাগুলি" কীভাবে এখানে একটি ইস্যু, যদি না অন্য ব্যবহারকারীটির পরিবেশের উপর নিয়ন্ত্রণ থাকে যখন ওপি'র প্রোগ্রামটি চালু না করা হয় যা মূলত স্যুডের ক্ষেত্রে হয় (সম্ভবত, তবে কিছুটা হলেও কিছু কম হয়) সিজি এবং এসএস জোর করে-আদেশ)। সাধারণ প্রোগ্রামগুলি যেভাবে তারা চালাচ্ছেন তাদের বিরুদ্ধে কঠোর করার কোনও কারণ নেই।
আর ..

2
@ আর ..: "ইনজেকশন দুর্বলতা" হ'ল আপনি যখন সাধারণ ttyUSB2ব্যবহার এবং ব্যবহার করেন sprintf(buf, "udevadm info -q path -n /dev/%s", argv[1])। এখন এটি মোটামুটি নিরাপদ বলে মনে হচ্ছে তবে তা হলে argv[1]কী হবে "nul || echo OOPS"?
এমসাল্টারস

3
@ আর ..: আপনার আরও কল্পনা দরকার। প্রথমে এটি একটি স্থির স্ট্রিং, তারপরে এটি ব্যবহারকারী দ্বারা সরবরাহ করা একটি যুক্তি, তারপরে এটি একটি যুক্তি যা ব্যবহারকারী দ্বারা চালিত অন্য কোনও প্রোগ্রাম দ্বারা সরবরাহ করা হয় তবে তারা বুঝতে পারে না, তবে এটি একটি যুক্তি যা তাদের ব্রাউজারটি একটি ওয়েব পৃষ্ঠা থেকে সরিয়ে নিয়েছিল। যদি জিনিসগুলি "উতরাই" অব্যাহত থাকে, তবে অবশেষে কারও কাছে ইনপুট স্যানিটাইজ করার জন্য দায়িত্ব নিতে হবে, এবং কার্ল বলছেন যে যেখানেই যেদিকেই আসতে পারে সেই জায়গাটি চিহ্নিত করতে চূড়ান্ত যত্ন নেওয়া উচিত।
স্টিভ জেসোপ

6
যদিও যদি সতর্কতামূলক নীতিটি সত্যিই "আপনারা জানেন এমন সবচেয়ে অসতর্ক বিকাশকারীকে ধরে নিন যে একটি অনিরাপদ পরিবর্তন আনছে", এবং আমাকে এখনই কোডটি লিখতে হয়েছিল যার ফলে কোনও শোষণ ঘটতে পারে না, তবে ব্যক্তিগতভাবে আমি বিছানা থেকে উঠতে পারিনি। আমি জানি সবচেয়ে অসতর্ক বিকাশকারীরা মাচিভিলিকে এমন দেখাচ্ছে যেন তিনি চেষ্টা করছেন না ।
স্টিভ জেসোপ

16

আপনার সুনির্দিষ্ট ক্ষেত্রে, যেখানে আপনি প্রার্থনা করতে চান udevadm, আমি সন্দেহ করি আপনি udevএকটি লাইব্রেরি হিসাবে টানতে পারেন এবং বিকল্প হিসাবে উপযুক্ত ফাংশন কল করতে পারেন?

উদাহরণস্বরূপ, "তথ্য" মোডে প্রার্থনা করার সময় আপনি উদেবডম নিজে যা করছেন তা একবার দেখে নিতে পারেন: https://github.com/gentoo/eudev/blob/master/src/udev/udevadm-info.c এবং সমমান কল করার জন্য যেমন উদেবম তৈরি করছে।

এটি ব্রায়ান অ্যাগ্নিউর দুর্দান্ত উত্তরে অঙ্কিত প্রচুর ডাউন-ট্রেড অফগুলি এড়াতে পারে - যেমন, কোনও নির্দিষ্ট পথে বাইনারিটির উপর নির্ভর না করা, কাঁটাচামড়ার ব্যয় এড়ানো ইত্যাদি।


ধন্যবাদ, আমি সেই সঠিক রেপোটি খুঁজে পেলাম এবং আমি এটির জন্য কিছুটা সন্ধান করেছি।
johnny_boy

1
… এবং লাইবদেব ব্যবহার করা বিশেষত কঠিন নয়। এর ত্রুটি পরিচালনার ক্ষেত্রে কিছুটা অভাব রয়েছে, তবে গণনা, অনুসন্ধান এবং এপিআই পর্যবেক্ষণগুলি বেশ সোজা। আপনি যদি একবার চেষ্টা করে দেখেন তবে আপনার ভয়টি 2 ঘন্টারও কম হতে পারে fear
স্পেকট্রা

7

আপনার প্রশ্নটি বনের উত্তর চেয়েছিল বলে মনে হয়েছিল, এবং এখানে উত্তরগুলি গাছের উত্তরের মতো মনে হচ্ছে, তাই আমি ভেবেছিলাম যে আমি আপনাকে একটি বন উত্তর দেব।

এটি সি প্রোগ্রামগুলি কীভাবে লেখা হয় তা খুব কমই হয়। এটি সর্বদা শেল স্ক্রিপ্টগুলি কীভাবে লেখা হয় এবং কখনও কখনও পাইথন, পার্ল বা রুবি প্রোগ্রামগুলি কীভাবে লেখা হয় তা is

সিস্টেম গ্রন্থাগারগুলির সহজ ব্যবহার এবং ওএস সিস্টেম কলগুলিতে সরাসরি নিম্ন স্তরের অ্যাক্সেসের পাশাপাশি গতির জন্য লোকেরা সিতে সাধারণত লেখেন। এবং সি লিখতে একটি কঠিন ভাষা, সুতরাং লোকেরা যদি এই জিনিসগুলির প্রয়োজন না হয় তবে তারা সি ব্যবহার করে না Also এছাড়াও সি প্রোগ্রামগুলি সাধারণত ভাগ করা লাইব্রেরি এবং কনফিগারেশন ফাইলগুলির উপর নির্ভরতা রাখার প্রত্যাশা করে।

উপ-প্রক্রিয়াতে শেলিং করা বিশেষত দ্রুত নয়, এবং এটি নিম্ন-স্তরের সিস্টেম সুবিধাগুলিতে সূক্ষ্ম দানাযুক্ত এবং নিয়ন্ত্রিত অ্যাক্সেসের প্রয়োজন হয় না এবং এটি একটি বাহ্যিক নির্বাহযোগ্যের উপর সম্ভবত অবাক করা নির্ভরশীলতার পরিচয় দেয়, তাই এটি দেখার বিষয়টি অস্বাভাবিক নয় see সি প্রোগ্রামে।

কিছু অতিরিক্ত উদ্বেগ আছে। লোকেরা যে সুরক্ষা এবং বহনযোগ্যতার উদ্বেগ প্রকাশ করেছে তা সম্পূর্ণ বৈধ। এগুলি অবশ্যই শেল স্ক্রিপ্টগুলির জন্য সমানভাবে বৈধ, তবে লোকেরা শেল স্ক্রিপ্টগুলিতে এই জাতীয় সমস্যা আশা করে। তবে সি প্রোগ্রামগুলি সাধারণত এই শ্রেণীর সুরক্ষা উদ্বেগের আশা করে না, যা এটি আরও বিপজ্জনক করে তোলে।

তবে, আমার মতে, সবচেয়ে বড় উদ্বেগ যেভাবে করা উচিত popenতা আপনার বাকি প্রোগ্রামের সাথে ইন্টারঅ্যাক্ট করবে। popenএকটি শিশু প্রক্রিয়া তৈরি করতে হবে, এর আউটপুটটি পড়তে হবে এবং তার প্রস্থান স্থিতি সংগ্রহ করতে হবে। এরই মধ্যে, সেই প্রক্রিয়াটির স্ট্যাডার আপনার প্রোগ্রামের মতো একই স্ট্যাডারের সাথে সংযুক্ত থাকবে, যা বিভ্রান্তিকর আউটপুট তৈরি করতে পারে এবং এর স্টিডিনটি আপনার প্রোগ্রামের মতোই হবে, যা অন্যান্য আকর্ষণীয় সমস্যার কারণ হতে পারে। আপনি যে </dev/null 2>/dev/nullস্ট্রিংটি popenশেল দ্বারা ব্যাখ্যা করা হয়েছে তাতে অন্তর্ভুক্ত করে আপনি এটি সমাধান করতে পারেন ।

এবং popenএকটি শিশু প্রক্রিয়া তৈরি করে। আপনি যদি সিগন্যাল হ্যান্ডলিং বা নিজেকে কাঁটা প্রক্রিয়া দিয়ে কিছু করেন তবে আপনি বিজোড় SIGCHLDসংকেত পেতে পারেন । আপনার কলগুলি waitঅদ্ভুতভাবে ইন্টারঅ্যাক্ট করতে পারে popenএবং সম্ভবত অদ্ভুত বর্ণের পরিস্থিতি তৈরি করতে পারে।

সুরক্ষা এবং বহনযোগ্যতা উদ্বেগ অবশ্যই আছে। যেমন এটি শেল স্ক্রিপ্ট বা এমন কোনও কিছুর জন্য যা সিস্টেমে অন্য এক্সিকিউটেবল শুরু করে। আর তুমি সাবধান আপনার প্রোগ্রাম ব্যবহার মানুষ স্ট্রিং আপনি মধ্যে পাস মধ্যে শেল মেটা-charcaters পেতে সক্ষম হয় না হতে হবে popenকারণ যে স্ট্রিং সরাসরি দেওয়া হয় shসঙ্গে sh -c <string from popen as a single argument>

তবে আমি মনে করি না যে তারা কেন সি প্রোগ্রাম ব্যবহার করে দেখতে অবাক লাগে popen। এটি আশ্চর্যের কারণ হ'ল সি সাধারণত নিম্ন স্তরের ভাষা এবং popenনিম্ন স্তরের নয়। এবং popenআপনার প্রোগ্রামে জায়গাগুলির নকশার সীমাবদ্ধতার কারণ এটি আপনার প্রোগ্রামের স্ট্যান্ডার্ড ইনপুট এবং আউটপুটটির সাথে অদ্ভুতভাবে ইন্টারেক্ট করবে এবং এটি আপনার নিজের প্রক্রিয়া পরিচালনা বা সিগন্যাল হ্যান্ডলিংয়ে ব্যথা করে। এবং কারণ সি প্রোগ্রামগুলি সাধারণত বাহ্যিক এক্সিকিউটেবলের উপর নির্ভরতা রাখে বলে আশা করা যায় না।


0

আপনার প্রোগ্রাম হ্যাকিং সম্পর্কিত হতে পারে ইত্যাদি activity এই ধরনের ক্রিয়াকলাপ থেকে নিজেকে রক্ষা করার একটি উপায় হ'ল আপনার বর্তমান মেশিন এনভ্রনমেন্টের একটি অনুলিপি তৈরি করা এবং ক্রোট নামক একটি সিস্টেম ব্যবহার করে আপনার প্রোগ্রামটি চালানো।

আপনার প্রোগ্রামের দৃষ্টিকোণ থেকে এটি একটি সাধারণ এনভ্রোমেন্টে কার্যকর হয়, সুরক্ষা দিক থেকে যদি কেউ আপনার প্রোগ্রামটি ভেঙে দেয় তবে আপনি অনুলিপি তৈরি করার সময় এটি সরবরাহ করা উপাদানগুলিতে কেবল অ্যাক্সেস পেতে পারে।

এই ধরণের সেটআপটিকে ক্রুট জেল বলা হয় আরও বিশদের জন্য ক্রুট জেল দেখুন

এটি সাধারণত সর্বজনীনভাবে অ্যাক্সেসযোগ্য সার্ভার ইত্যাদি সেটআপ করার জন্য ব্যবহৃত হয়


3
ওপি তার নিজের সিস্টেমে অবিশ্বস্ত বাইনারি বা উত্সের সাথে না খেলে অন্যান্য লোকদের চালনার জন্য একটি প্রোগ্রাম লিখছে।
পিটার কর্ডেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.