Ada perintah shell unix ( udevadm info -q path -n /dev/ttyUSB2
) yang ingin saya panggil dari program C. Dengan mungkin sekitar satu minggu perjuangan, saya bisa menerapkannya sendiri, tetapi saya tidak ingin melakukannya.
Apakah ini praktik baik yang diterima secara luas untuk saya panggil saja popen("my_command", "r");
, atau akankah hal itu menimbulkan masalah keamanan yang tidak dapat diterima dan meneruskan masalah kompatibilitas? Rasanya salah bagi saya untuk melakukan sesuatu seperti ini, tetapi saya tidak dapat menjelaskan mengapa itu buruk.
udevadm
executable berbahaya dalam direktori yang sama dengan program Anda dan menggunakannya untuk meningkatkan hak istimewa? Saya tidak tahu banyak tentang keamanan unix, tetapi apakah program Anda akan dijalankansetuid root
?PATH
, maka tidak - itu harus dijalankan dengan./udevadm
. IIRC Windows akan menjalankan executable direktori yang sama.Jawaban:
Ini tidak terlalu buruk, tetapi ada beberapa peringatan.
LANG
dll.?;rm -rf /
(misalnya) (perhatikan bahwa beberapa API akan memungkinkan Anda untuk menentukan args lebih aman daripada hanya menyediakannya di baris perintah)Saya biasanya senang menjalankan binari ketika saya berada di lingkungan yang dikenal yang dapat saya prediksi, ketika keluaran biner mudah diurai (jika diperlukan - Anda mungkin hanya perlu kode keluar) dan saya tidak perlu melakukannya juga sering.
Seperti yang telah Anda catat, masalah lainnya adalah berapa banyak pekerjaan yang harus dilakukan untuk mereplikasi apa yang dilakukan biner? Apakah itu menggunakan perpustakaan Anda juga dapat memanfaatkan?
sumber
Forking a binary results in a lot more load and requires more resources than executing library calls (generally speaking).
Jika ini pada Windows, saya setuju. Namun, OP menetapkan Unix di mana forking adalah biaya yang cukup rendah sehingga sulit untuk mengatakan apakah secara dinamis memuat perpustakaan lebih buruk daripada forking.exec
daripada darifork
. Memuat bagian, menautkan objek bersama, menjalankan kode init untuk masing-masing. Dan kemudian harus mengubah semua data menjadi teks untuk diuraikan di sisi lain, baik untuk input dan output.udevadm info -q path -n /dev/ttyUSB2
juga tidak akan bekerja pada Windows sehingga seluruh diskusi forking sedikit berteori.Dibutuhkan sangat hati-hati untuk menjaga terhadap kerentanan injeksi setelah Anda memperkenalkan vektor potensial. Ini berada di garis depan pikiran Anda sekarang, tetapi nanti Anda mungkin perlu kemampuan untuk memilih
ttyUSB0-3
, maka daftar itu akan digunakan di tempat lain sehingga akan diperhitungkan untuk mengikuti prinsip tanggung jawab tunggal, maka pelanggan akan memiliki persyaratan untuk menempatkan perangkat sewenang-wenang dalam daftar, dan pengembang membuat yang perubahan akan tidak tahu bahwa daftar akhirnya akan digunakan dengan cara yang tidak aman.Dengan kata lain, kode seolah-olah pengembang paling ceroboh yang Anda kenal membuat perubahan yang tidak aman di bagian kode yang tampaknya tidak terkait.
Kedua, output dari alat CLI umumnya tidak dianggap sebagai antarmuka yang stabil kecuali jika dokumentasi secara khusus menandainya. Anda mungkin akan mengandalkan skrip yang Anda jalankan yang bisa Anda atasi sendiri, tetapi tidak untuk sesuatu yang Anda gunakan untuk pelanggan.
Ketiga, jika Anda menginginkan cara mudah untuk mengekstraksi nilai dari perangkat lunak Anda, kemungkinan orang lain juga menginginkannya. Cari perpustakaan yang sudah melakukan apa yang Anda inginkan.
libudev
sudah diinstal di sistem saya:Ada fungsi berguna lainnya di perpustakaan itu. Dugaan saya adalah jika Anda memerlukan ini, beberapa fungsi terkait mungkin berguna juga.
sumber
ttyUSB2
dan menggunakannyasprintf(buf, "udevadm info -q path -n /dev/%s", argv[1])
. Sekarang tampaknya cukup aman, tetapi bagaimana jikaargv[1]
itu"nul || echo OOPS"
?Dalam kasus spesifik Anda, di mana Anda ingin memohon
udevadm
, saya curiga Anda bisa masukudev
sebagai perpustakaan dan membuat fungsi yang sesuai dipanggil sebagai alternatif?mis., Anda dapat melihat apa yang sedang dilakukan udevadm ketika menjalankan mode "info": https://github.com/gentoo/eudev/blob/master/src/udev/udevadm-info.c dan melakukan panggilan yang sama tentang udevadm yang mereka buat.
Ini akan menghindari banyak kelemahan-pengorbanan yang disebutkan dalam jawaban luar biasa Brian Agnew - misalnya, tidak mengandalkan biner yang ada di jalur tertentu, menghindari biaya forking, dll.
sumber
Pertanyaan Anda sepertinya membutuhkan jawaban hutan, dan jawaban di sini seperti jawaban pohon, jadi saya pikir saya akan memberi Anda jawaban hutan.
Ini sangat jarang bagaimana program C ditulis. Selalu bagaimana skrip shell ditulis, dan kadang-kadang bagaimana program Python, perl atau Ruby ditulis.
Orang-orang biasanya menulis dalam bahasa C agar mudah menggunakan perpustakaan sistem dan mengarahkan akses tingkat rendah ke panggilan sistem OS serta untuk kecepatan. Dan C adalah bahasa yang sulit untuk ditulis, jadi jika orang tidak membutuhkan hal-hal itu, maka mereka tidak menggunakan C. Juga program C biasanya hanya bergantung pada pustaka bersama dan file konfigurasi.
Keluar ke sub-proses tidak terlalu cepat, dan tidak memerlukan akses yang baik dan terkendali ke fasilitas sistem tingkat rendah, dan memperkenalkan ketergantungan yang mungkin mengejutkan pada eksekusi eksternal, sehingga tidak biasa untuk melihat dalam program C.
Ada beberapa kekhawatiran tambahan. Masalah keamanan dan portabilitas yang disebutkan orang sepenuhnya valid. Mereka sama-sama valid untuk skrip shell tentu saja, tetapi orang-orang mengharapkan masalah semacam itu dalam skrip shell. Tetapi program C biasanya tidak diharapkan memiliki kelas masalah keamanan ini, yang membuatnya lebih berbahaya.
Tapi, menurut saya, masalah terbesar yang harus dilakukan dengan cara
popen
akan berinteraksi dengan seluruh program Anda.popen
harus membuat proses anak, membaca outputnya dan mengumpulkan status keluarnya. Sementara itu, stderr proses itu akan terhubung ke stderr yang sama dengan program Anda, yang dapat menyebabkan output membingungkan, dan stdinnya akan sama dengan program Anda, yang dapat menyebabkan masalah menarik lainnya. Anda dapat menyelesaikannya dengan memasukkan</dev/null 2>/dev/null
string yang Anda lewatipopen
karena ditafsirkan oleh shell.Dan
popen
menciptakan proses anak. Jika Anda melakukan sesuatu dengan penanganan sinyal atau proses forking sendiri, Anda mungkin akan mendapatkanSIGCHLD
sinyal aneh . Panggilan Anda untukwait
dapat berinteraksi secara aneh denganpopen
dan mungkin menciptakan kondisi balapan yang aneh.Masalah keamanan dan portabilitas tentu saja ada. Karena mereka untuk skrip shell atau apa pun yang menjalankan executable lain pada sistem. Dan Anda harus berhati-hati bahwa orang-orang menggunakan program Anda tidak bisa mendapatkan shell meta-charcaters ke string Anda masuk ke
popen
karena string yang diberikan langsung kesh
dengansh -c <string from popen as a single argument>
.Tapi saya tidak berpikir mereka mengapa aneh melihat program C menggunakan
popen
. Alasannya aneh adalah karena C biasanya bahasa tingkat rendah, danpopen
bukan tingkat rendah. Dan karena menggunakanpopen
batasan desain tempat pada program Anda karena itu akan berinteraksi aneh dengan input dan output standar program Anda dan membuatnya susah untuk melakukan manajemen proses atau penanganan sinyal Anda sendiri. Dan karena program C biasanya tidak diharapkan memiliki ketergantungan pada executable eksternal.sumber
Program Anda mungkin mengalami peretasan, dll. Salah satu cara untuk melindungi diri Anda dari jenis aktivitas ini adalah dengan membuat salinan lingkungan mesin Anda saat ini dan menjalankan program Anda menggunakan sistem yang disebut chroot.
Dari sudut pandang program Anda, pengeksekusiannya dalam lingkungan normal, dari aspek keamanan, jika seseorang merusak program Anda, program itu hanya memiliki akses ke elemen-elemen yang Anda berikan ketika membuat salinan.
Pengaturan seperti itu disebut jail chroot untuk detail lebih lanjut lihat chroot jail .
Biasanya digunakan untuk menyiapkan server yang dapat diakses publik, dll.
sumber