ทำไมทุบตีถึงทำให้แจง / เรียกใช้เนื้อหาในตัวแปรสภาพแวดล้อม


9

ShellShockข้อผิดพลาดในการทำงานทุบตีโดยวิธีการของตัวแปรสภาพแวดล้อม สุจริตฉันประหลาดใจด้วยความจริงที่ว่ามีคุณสมบัติเช่น:

"การส่งผ่านนิยามฟังก์ชันผ่าน env vars"

ดังนั้นคำถามนี้ในขณะที่อาจไม่ได้กำหนดอย่างสมบูรณ์คือการขอตัวอย่างหรือกรณีที่จำเป็นต้องมีคุณสมบัตินี้?

โบนัส. เชลล์อื่น ๆ zsh, dash ฯลฯ มีคุณสมบัตินี้ด้วยหรือไม่?


มันใช้ env vars เพื่อส่งผ่านนิยามฟังก์ชัน คุณหมายความว่าอย่างไรกับ "ทำไมมันไม่ทำให้ตัวแปรสภาพแวดล้อมพร้อมใช้งาน / เข้าถึงได้" ?
Anthon

@Athon ขอบคุณสำหรับความคิดเห็น บางทีฉันควรจะชัดเจนและใช้ถ้อยคำใหม่ ด้วยเหตุผลใดที่จำเป็นต้องส่งผ่านนิยามฟังก์ชันผ่าน env vars?
humanityANDpeace

1
ฉันไม่แน่ใจ 100% แต่ฉันคิดว่านั่นเป็นวิธีที่ GNU parallelรับฟังก์ชั่นการแจกแจงนิยามถ้ามันเรียกใช้อินสแตนซ์ทุบตีหลาย ๆ หากไม่ได้อยู่ในลักษณะนั้นจะต้องเขียนสิ่งเหล่านั้นลงในไฟล์ว่าแต่ละอินสแตนซ์ที่เรียกใช้อ่านแล้วคุณต้องจัดการกับปัญหาเช่นเมื่อไฟล์นั้นสามารถลบออกได้
Anthon

2
หัวข้อนี้มีประวัติบางส่วน ฟังก์ชั่นการส่งออกแม้ว่าจะบ้า หากคุณต้องการให้เชลล์ใหม่สืบทอดคำสั่งที่ใช้งานได้ของเชลล์เก่าคุณต้อง.dotใช้ไฟล์เดียวกันกับที่เชลล์เก่าทำ thats วิธีทำมัน - และที่ทำให้รู้สึก - หรือคุณฟีเปลือกใหม่ไฟล์เป็น input เมื่อexecไอเอ็นจี เมื่ออ่านแล้วไฟล์จะถูกแคชโดยเคอร์เนลอยู่ดี
mikeserv

@mikeserv ฉันเข้าใจถูกต้องหรือไม่ส่วนใหญ่ของ shellshock นั้นเกี่ยวกับคุณลักษณะนี้ซึ่งไม่สำคัญอะไรมาก?
มนุษยชาติ

คำตอบ:


4

เมื่อสคริปต์เรียกใช้สคริปต์อื่นตัวแปรของสคริปต์หลักสามารถส่งออกได้จากนั้นสคริปต์เหล่านั้นจะปรากฏในสคริปต์ลูก ฟังก์ชั่นการส่งออกเป็นลักษณะทั่วไปที่ชัดเจน: ส่งออกฟังก์ชั่นจากผู้ปกครองทำให้มองเห็นได้ในเด็ก

สภาพแวดล้อมเป็นวิธีที่สะดวกเพียงอย่างเดียวที่กระบวนการสามารถส่งผ่านข้อมูลไปยังลูกโดยพลการ ข้อมูลจะต้องถูกจัดเรียงในสตริงที่ไม่มีไบต์ว่างซึ่งไม่ยากสำหรับฟังก์ชั่นเชลล์ มีวิธีที่เป็นไปได้อื่น ๆ เช่นบล็อกหน่วยความจำที่แชร์หรือไฟล์ชั่วคราวที่ส่งผ่านตัวอธิบายไฟล์ แต่สิ่งเหล่านี้อาจทำให้เกิดปัญหากับโปรแกรมระดับกลางที่ไม่รู้ว่าจะทำอย่างไรกับพวกเขาหรือจะปิดพวกเขา โปรแกรมคาดหวังให้ทำงานในสภาพแวดล้อมที่มีตัวแปรที่พวกเขาไม่รู้หรือสนใจดังนั้นพวกเขาจะไม่เขียนทับหรือลบทิ้ง

ทางเลือกในการใช้ชื่อฟังก์ชั่นเป็นชื่อของตัวแปรสภาพแวดล้อมเป็นสิ่งที่แปลก สำหรับสิ่งหนึ่งนั่นหมายความว่าตัวแปรที่ส่งออกขัดแย้งกับฟังก์ชันที่ส่งออกที่มีชื่อเดียวกัน

ฟังก์ชั่นที่ส่งออกเป็นคุณสมบัติเก่า มีการเพิ่มฟังก์ชั่นในเชลล์เป้าหมายใน SVR2และฟังก์ชั่นที่ส่งออกในเชลล์เวอร์ชัน 8เปิดตัวในปีเดียวกัน (1984) ในเชลล์นั้นตัวแปรและฟังก์ชั่นใช้เนมสเปซเดียวกัน ฉันไม่รู้ว่าการส่งออกฟังก์ชั่นทำงานอย่างไร Heirloom เปลือกจะขึ้นอยู่กับตัวแปรบอร์นซึ่งมีฟังก์ชั่น แต่ไม่ได้ส่งออก

ATT ksh ควรรองรับฟังก์ชั่นการส่งออก แต่เมื่อดูที่แหล่งที่มาหรือเล่นกับมันฉันไม่เห็นว่ามันจะเป็นเช่นนั้นในฐานะของ ksh93u

env -i /usr/bin/ksh -c 'f=variable; f () { echo function; }; typeset -fx f; /usr/bin/env; ksh -c f'
_=*25182*/usr/bin/env
PWD=/home/gilles
SHLVL=1
A__z="*SHLVL
ksh: f: not found

โคลโดเมนสาธารณะของ Ksh (pdksh, mksh), ขีดกลางและ zsh ไม่รองรับฟังก์ชั่นการส่งออก


1
ขอบคุณ! ดังนั้นหากไม่มีฟังก์ชั่นการส่งออกฟังก์ชั่นการทำงานจะหายไป แต่มีบางเชลล์เช่น dash, zsh และ pdksh เป็นต้นซึ่งไม่มีฟังก์ชั่นนี้ฉันอ่านมันใช่ไหม?
มนุษยชาติ

BASH_FUNC_f%%=() { echo hi }แต่เมื่อผมได้ฟังก์ชั่นการส่งออกในทุบตีก็จะเข้าสู่ตัวแปรเช่น ทำไมทุบตีวิเคราะห์ตัวแปรสภาพแวดล้อมอื่น ๆ ? ทำไมถึงต้องแยกวิเคราะห์BASH_FUNC_g%%เมื่อฉันโทรมาเท่านั้นf? (เห็นได้ชัดว่า pre-shellshock ตัวแปรสภาพแวดล้อมเพิ่งถูกเรียกfหรือg- แต่ฉันยังคงสงสัยว่าทำไมgจะถูกแยกวิเคราะห์ถ้าฉันไม่เคยโทรหาgในสคริปต์ของฉัน)
Metamorphic

@Met มันต้องดูตัวแปรสภาพแวดล้อมทั้งหมดเพื่อหาว่าอันไหนคือนิยามของฟังก์ชัน มันสามารถจดจำความจริงนั้นและหลีกเลี่ยงการแยกโค้ดของฟังก์ชันได้จนกว่าจะเป็นครั้งแรกที่ต้องการ แต่นั่นจะเป็นความซับซ้อนเพิ่มเติมเพื่อผลประโยชน์เพียงเล็กน้อย มันง่ายกว่าที่จะมีฟังก์ชั่นประเภทเดียวและไม่ใช่สอง ("ฟังก์ชั่นปกติ" และ "ฟังก์ชั่นจากตัวแปรสภาพแวดล้อมที่ต้องการการแยกวิเคราะห์เล็กน้อย")
Gilles 'หยุดชั่วร้าย'

ไม่ชัดเจน. ฉันแนะนำว่าสิ่งที่ชัดเจนที่ต้องทำคือเมื่อฉันเรียกใช้สิ่งที่เรียกว่าf(1) ตรวจสอบฟังก์ชันเชลล์ที่เรียกว่าf(2) ตรวจสอบตัวแปรสภาพแวดล้อมที่เรียกว่าfและลองแยกวิเคราะห์ (3) ตรวจสอบ แต่ละองค์ประกอบสำหรับการปฏิบัติการที่เรียกว่าPATH fการแยกวิเคราะห์ตัวแปรสภาพแวดล้อมทั้งหมดเป็นรหัสเชลล์เมื่อเริ่มต้นเชลล์ดูเหมือนการออกแบบที่ซับซ้อนน้อยลงได้อย่างไร
Metamorphic

@ Metamorphic คุณกำลังแนะนำให้เพิ่มอีกขั้นตอนที่จะต้องมีรูปแบบในทุกคำสั่ง คุณต้องเพิ่มอีกขั้นตอนหนึ่งเมื่อกำหนดหรือยกเลิกการกำหนดฟังก์ชั่น (หลังจากunset -f fooทุบตีต้องไม่มองหาคำจำกัดความของฟังก์ชั่นสำหรับfooในสภาพแวดล้อมอีกต่อไป) เมื่อรายการฟังก์ชั่น (คุณจะจัดการdeclare -fอื่น ๆ และอะไรก็ได้ที่ฉันไม่ได้คิด การออกแบบของคุณดูเหมือนง่ายขึ้นเพราะคุณทิ้งมันไว้เกือบทั้งหมด ในทางตรงกันข้ามการทำทุกอย่างเมื่อเริ่มต้นเป็นโค้ดชิ้นเดียวและหลังจากนั้นทุกอย่างก็ใช้ได้
Gilles 'หยุดชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.