স্ট্যাক ক্যানারি দূষণগুলি কীভাবে লগ হয়?


11

জিসিসি -ফস্ট্যাক-প্রটেক্টর পতাকাটি স্ট্যাক ওভারফ্লো সুরক্ষার জন্য স্ট্যাক ক্যানারিগুলির ব্যবহার সক্ষম করে। ডিফল্টরূপে এই পতাকাটির ব্যবহার সাম্প্রতিক বছরগুলিতে আরও বিশিষ্ট।

যদি কোনও প্যাকেজ -fstack- প্রটেক্টর দিয়ে সংকলিত হয়, এবং আমরা প্রোগ্রামে একটি বাফারকে উপচে ফেলেছি, আমরা সম্ভবত একটি ত্রুটি পেয়ে যাব:

*** buffer overflow detected ***: /xxx/xxx terminated

তবে, এই ত্রুটি বার্তাগুলির দায়িত্বে "কে"? এই বার্তাগুলি লগ কোথায় পাবেন? সিসলগ ডেমন কি এই বার্তাগুলি বাছাই করে?

উত্তর:


10

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

একবার এটি বার্তা আউটপুট হয়ে গেলে, libsspঅ্যাপ্লিকেশন ক্রাশ সহ প্রস্থান করার বিভিন্ন উপায় চেষ্টা করে; এটি অস্বাভাবিক বহির্গমন লগারদের একজনের দ্বারা ধরা পড়তে পারে, তবে এটির নিশ্চয়তা নেই।


1
এই ব্যাখ্যাটি আরও অন্বেষণ করার উপায় হিসাবে আমি একটি কংক্রিটের উদাহরণ পেশ করি। এই উদাহরণের জন্য nginx চয়ন করা যাক। আমি স্ট্যাক ক্যানারিগুলির সাথে এনগিনেক্স সংকলন করেছি। আমি যখন এনজিনেক্স চালাচ্ছি, এটি একটি প্রক্রিয়া শুরু করে তবে শেলের কোনও আউটপুট দেয় না। পরিবর্তে, কোনও বার্তা তার একাধিক লগ ফাইলগুলিতে লগ হয়। যদি এনজিনেক্স স্ট্যাক স্ম্যাশিং সনাক্ত করে, libsspতার বার্তাটি এনজিএনএক্স দ্বারা ব্যবহৃত স্ট্যাডার আউটপুট দ্বারা আউটপুট দেবে। তারপরে, libsspপ্রক্রিয়াটি (বা শিশু প্রসেসটি এনজিনেক্সের জন্য) প্রস্থান করার চেষ্টা করতে পারে। যদি অ্যাপ্লিকেশনটি ক্র্যাশ করার প্রয়োজন হয় না, তবে অস্বাভাবিক প্রস্থানকারী লগাররা এটি তুলবে না Iএটি কি সঠিক ব্যাখ্যা?
এডিসিভি

বেশ - এটা হবে আবেদন বিপর্যস্ত, ব্যবহার করার চেষ্টা করুন __builtin_trap()প্রথম যে তারপর যদি ব্যর্থ হয় একটি সেগমেন্ট লঙ্ঘন ঘটান বের করার চেষ্টা অবস্থা 127. সঙ্গে থেকে প্রস্থান, এবং যে শুধুমাত্র যদি ব্যর্থ হয়, তাহলে
স্টিফেন Kitt

মূল ফলন পদ্ধতি (যেমন abort()) এর মাধ্যমে প্রস্থানের চেয়ে বার্তার অংশের মুদ্রণের সাফল্যের আরও ভাল গ্যারান্টি নেই ।
maxschlepzig

7

সেন্টোস / ফেডোরার মতো আধুনিক লিনাক্স ডিস্ট্রিবিউশনগুলি ডিফল্টরূপে ক্র্যাশ হ্যান্ডলিং ডেমন সেট আপ করে (যেমন systemd-coredumpবা abortd)।

সুতরাং, যখন আপনার প্রোগ্রামটি অস্বাভাবিক ফ্যাশনে শেষ হয় (সেগফল্ট, অব্যাহতি ব্যতিক্রম, বাতিল, অবৈধ নির্দেশিকা ইত্যাদি) এই ইভেন্টটি এই ডেমন দ্বারা নিবন্ধিত এবং লগড হয়। সুতরাং, আপনি সিস্টেম জার্নালে কিছু বার্তা এবং সম্ভবত কিছু অতিরিক্ত বিশদ (যেমন কোর ফাইল, লগ, ইত্যাদি) সহ একটি ডিরেক্টরিতে একটি রেফারেন্স পাবেন।

উদাহরণ

$ cat test_stack_protector.c 
#include <string.h>

int f(const char *q)
{
  char s[10];
  strcpy(s, q);
  return s[0] + s[1];
}

int main(int argc, char **argv)
{
  return f(argv[1]);
}

কম্পাইল:

$ gcc -Wall -fstack-protector test_stack_protector.c -o test_stack_protector

এক্সিকিউট:

$ ./test_stack_protector 'hello world'
*** stack smashing detected ***: ./test_stack_protector terminated
======= Backtrace: =========
/lib64/libc.so.6(+0x7c8dc)[0x7f885b4388dc]
/lib64/libc.so.6(__fortify_fail+0x37)[0x7f885b4dfaa7]
/lib64/libc.so.6(__fortify_fail+0x0)[0x7f885b4dfa70]
./test_stack_protector[0x400599]
./test_stack_protector[0x4005bd]
/lib64/libc.so.6(__libc_start_main+0xea)[0x7f885b3dc50a]
./test_stack_protector[0x40049a]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:28 1151979                            /home/juser/program/stackprotect/test_stack_protector
00600000-00601000 r--p 00000000 00:28 1151979                            /home/juser/program/stackprotect/test_stack_protector
00601000-00602000 rw-p 00001000 00:28 1151979                            /home/juser/program/stackprotect/test_stack_protector
0067c000-0069d000 rw-p 00000000 00:00 0                                  [heap]
7f885b1a5000-7f885b1bb000 r-xp 00000000 00:28 1052100                    /usr/lib64/libgcc_s-7-20170915.so.1
7f885b1bb000-7f885b3ba000 ---p 00016000 00:28 1052100                    /usr/lib64/libgcc_s-7-20170915.so.1
7f885b3ba000-7f885b3bb000 r--p 00015000 00:28 1052100                    /usr/lib64/libgcc_s-7-20170915.so.1
7f885b3bb000-7f885b3bc000 rw-p 00016000 00:28 1052100                    /usr/lib64/libgcc_s-7-20170915.so.1
7f885b3bc000-7f885b583000 r-xp 00000000 00:28 945348                     /usr/lib64/libc-2.25.so
7f885b583000-7f885b783000 ---p 001c7000 00:28 945348                     /usr/lib64/libc-2.25.so
7f885b783000-7f885b787000 r--p 001c7000 00:28 945348                     /usr/lib64/libc-2.25.so
7f885b787000-7f885b789000 rw-p 001cb000 00:28 945348                     /usr/lib64/libc-2.25.so
7f885b789000-7f885b78d000 rw-p 00000000 00:00 0 
7f885b78d000-7f885b7b4000 r-xp 00000000 00:28 945341                     /usr/lib64/ld-2.25.so
7f885b978000-7f885b97b000 rw-p 00000000 00:00 0 
7f885b9b0000-7f885b9b3000 rw-p 00000000 00:00 0 
7f885b9b3000-7f885b9b4000 r--p 00026000 00:28 945341                     /usr/lib64/ld-2.25.so
7f885b9b4000-7f885b9b6000 rw-p 00027000 00:28 945341                     /usr/lib64/ld-2.25.so
7ffc59966000-7ffc59987000 rw-p 00000000 00:00 0                          [stack]
7ffc5999c000-7ffc5999f000 r--p 00000000 00:00 0                          [vvar]
7ffc5999f000-7ffc599a1000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
zsh: abort (core dumped)  ./test_stack_protector 'hello world'

প্রস্থান স্থিতি 134 যা 128 + 6, অর্থাৎ 128 প্লাস অ্যাওর্ট সিগন্যাল নম্বর।

সিস্টেম জার্নাল:

Oct 16 20:57:59 example.org audit[17645]: ANOM_ABEND auid=1000 uid=1000 gid=1000 ses=3 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 pid=17645 comm="test_stack_prot" exe="/home/juser/program/stackprotect/test_stack_protector" sig=6 res=1
Oct 16 20:57:59 example.org systemd[1]: Started Process Core Dump (PID 17646/UID 0).
Oct 16 20:57:59 example.org audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-coredump@21-17646-0 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Oct 16 20:57:59 example.org systemd-coredump[17647]: Process 17645 (test_stack_prot) of user 1000 dumped core.

                           Stack trace of thread 17645:
                           #0  0x00007f885b3f269b raise (libc.so.6)
                           #1  0x00007f885b3f44a0 abort (libc.so.6)
                           #2  0x00007f885b4388e1 __libc_message (libc.so.6)
                           #3  0x00007f885b4dfaa7 __fortify_fail (libc.so.6)
                           #4  0x00007f885b4dfa70 __stack_chk_fail (libc.so.6)
                           #5  0x0000000000400599 f (test_stack_protector)
                           #6  0x00000000004005bd main (test_stack_protector)
                           #7  0x00007f885b3dc50a __libc_start_main (libc.so.6)
                           #8  0x000000000040049a _start (test_stack_protector)
Oct 16 20:57:59 example.org audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=systemd-coredump@21-17646-0 comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Oct 16 20:58:00 example.org abrt-notification[17696]: Process 17645 (test_stack_protector) crashed in __fortify_fail()

আপনার কাছ থেকে লগ-ইন করুন এর মানে হল যে auditdনিরীক্ষণ ডেমন এবংsystemd-coredump ক্র্যাশ হ্যান্ডলার।

ক্র্যাশ হ্যান্ডলিং ডেমন কনফিগার করা হয়েছে কিনা তা যাচাই করতে আপনি পরীক্ষা করতে পারেন /proc, যেমন:

$ cat /proc/sys/kernel/core_pattern
|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %e

(ফেডোরার 26, x86-64 এ সমস্ত কিছু পরীক্ষিত)


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

@ এএডসিভি, এটি অনেকটা গল্প - আরও স্পষ্ট করে বলার জন্য: স্ট্যাকের স্ম্যাকিং চেকিং কোড কলগুলি abort()একটি গর্ভপাত সিগন্যাল দেয়, অর্থাত্ কোনও বিভাগ বিভাজন চলছে না। এটি ঠিক যে গর্ভপাত / সেগমেন্টেশন ত্রুটি ইত্যাদির জন্য ডিফল্ট সংকেত হ্যান্ডলারগুলি একই ক্রিয়া দেয়: কোর লিখুন এবং প্রস্থানটি অসম শূন্যের সাথে প্রসেসটি প্রস্থান করুন যা সংকেত সংখ্যাটি এনকোড করে। মূল রচনাটি কার্নেল দ্বারা সম্পন্ন হয় এবং এর আচরণটি কনফিগার করে /proc/.../core_pattern। উপরের উদাহরণে একটি ব্যবহারকারী-স্থান সহায়তা কনফিগার করা হয়েছে এবং এভাবে বলা হয়। কার্নেলটি নিরীক্ষাও ট্রিগার করে।
maxschlepzig

@ ম্যাক্সচলেপজিগ এটি বেশ নয় abort(), এসএসপি কোড ব্যবহার করে __builtin_trap()(তবে প্রভাবটি একই রকম)।
স্টিফেন কিট

1
@ স্টেফেনকিট, ভাল, উপরের উদাহরণে স্ট্যাক ট্রেসটি একবার দেখুন। সেখানে আপনি পরিষ্কারভাবে দেখতে পাবেন কীভাবে abort()বলা হয়।
maxschlepzig

1
@ ম্যাক্সচলেপজিগ হ্যাঁ, অবশ্যই, তবে এটি একটি বাস্তবায়ন বিশদ (জিসিসি কোডের __builtin_trap()উপর সুস্পষ্ট নির্ভরতা এড়াতে ব্যবহার করে abort())। অন্যান্য বিতরণে বিভিন্ন স্ট্যাকের চিহ্ন রয়েছে।
স্টিফেন কিট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.