[UNIX] การ fork process และโปรแกรม shell
TL;DR : โปรแกรม shell เป็นโปรแกรมที่ทำงานอยู่ใน forever loop โดยเมื่อ user พิมพ์คำสั่ง โปรแกรม shell จะทำการ fork process เพื่อไปทำงานโปรแกรมนั้น ๆ
อย่างที่เราทราบกันดีว่าการ fork process เป็นการแยก process ออกจาก parent process เพื่อวัตถุประสงค์ เช่น ต้องการทำงานแบบ parallel
ก่อนอื่นเรามาทำความเข้าใจเกี่ยวกับการ fork process กันก่อน ซึ่งในที่นี้จะยกตัวอย่างเป็นภาษาซี
จะเห็นว่าเมื่อรันโปรแกรม จะ print คำว่า hello world แล้วตามด้วย process id ของ process ที่กำลังรันอยู่ โดยใช้คำสั่ง getpid()
หาก fork สำเร็จจะ return ค่ามากกว่าหรือเท่ากับศูนย์ โดยหากผลลัพธ์เป็น 0 แสดงว่าโค้ดบรรทัดนั้นรันอยู่ใน child process แต่หากผลลัพธ์มีค่ามากกว่า 0 แสดงว่าเป็น parent process ส่วนสาเหตุของการ fork ไม่สำเร็จอาจเกิดได้จากหลายปัจจัย เช่น memory ในขณะนั้นไม่เพียงพอ
ผลลัพธ์
คราวนี้ลอง advance ขึ้นอีกหน่อยโดยให้มีการรอ child process ให้ทำงานเสร็จก่อน แล้วค่อย callback มาที่ parent process โดยใช้คำสั่ง wait()
ผลลัพธ์
จะเห็นว่า child process ใช้เวลาในการทำงาน 1 วินาที (เป็นผลจากคำสั่ง sleep(1)) ก่อนจะปรากฎผลลัพธ์ในฝั่งของ parent process
พอจะเข้าใจคอนเซ็ปต์คร่าว ๆ ของการ fork process แล้วใช่มั้ยครับ คราวนี้มันเกี่ยวอะไรกับโปรแกรม shell ล่ะ? ลองมาดูตัวอย่างที่ 3 กัน
จากตัวอย่างที่ 3 พบว่าเราเปลี่ยนจากการให้ child process ทำการ sleep เป็นรันโปรแกรมจริง ๆ โดยเราจะให้รันโปรแกรม word count (ใช้คำสั่ง wc อย่าสับสนกับ wait system call นะ) เมื่อรันเสร็จแล้วให้ parent process แสดงผล pid ของตัวมันเองดังเช่นตัวอย่างอื่น ๆ ก่อนหน้า
ผลลัพธ์
จะเห็นว่าใน child process ได้ทำการแสดงค่าของจำนวนบรรทัด (number of lines) จำนวนของคำ (number of words) และจำนวนไบต์ (number of bytes) ตามลำดับ
เริ่มเอะใจแล้วใช่ไหมครับ เฉลยก็คือ โปรแกรม shell เป็นโปรแกรม forever loop (while(1)) ที่มีการ fork process เพื่อรันโปรแกรมอื่น ๆ (ที่ไม่ใช่ built-in command) โดยมีข้อควรระวังคือ
- คุณสมบัติต่าง ๆ ของ parent process จะถูกตกทอดไปยัง child process ด้วย
- address space จะถูก child process override
จากตรงนี้จะเห็นว่าหาก parrent process ถูกรันโดย root แล้ว child process ที่อยู่ภายใต้ parent process จะเป็น root ด้วย ดังนั้นต้องตระหนักเรื่องความปลอดภัยตรงนี้ด้วย
แล้วถ้าเป็น built-in commands ล่ะ จะเกิดอะไรขึ้น?
คำตอบก็คือ จะไม่มีการ fork process ขึ้นมาใหม่ (ใช้ pid เดิม) ตัวอย่างของ built-in commands คือ echo ซึ่ง source code ของ shell จะ implement คำสั่งพวกนี้ไว้ในตัว
มาดูโปรแกรม shell ที่ใกล้เคียงของจริงว่าหน้าตามันเป็นยังไง
บทความหน้าจะพูดถึงการใช้ช่องโหว่ต่าง ๆ ในการโจมตีระบบคอมพิวเตอร์ในอดีต สามารถติดตามโดยกด Follow ได้เลยครับ
อ้างอิง
[01204554] Data Encryption & Security by Paruj Ratanaworabhan