كيف يمكن العثور على موقع الملف القابل للتنفيذ على Linux عندما تفشل الطرق العادية؟
سؤال
في سؤال آخر، تنص الإجابة على ذلك في نظام يونكس مع /proc
, ، الطريقة الصحيحة والموثوقة حقًا هي أن readlink("/proc/self/exe", buf, bufsize)
ومن ثم يشرع في تقديم الحلول الاحتياطية على النحو التالي:
على أنظمة يونكس بدون /proc (أيإذا فشل أعلاه):
- إذا كان argv[0] يبدأ بـ "/" (المسار المطلق) فهذا هو المسار.
- وإلا إذا كان argv[0] يحتوي على "/" (مسار نسبي) فألحقه بـ cwd (على افتراض أنه لم يتم تغييره بعد).
getcwd(buf, bufsize); strncat(buf, "/", bufsize-strlen(buf)-1); strncat(buf, argv[0], bufsize-strlen(buf)-1);
- وإلا ابحث في الدلائل
$PATH
للتنفيذargv[0]
.
بعد ذلك قد يكون من المعقول التحقق مما إذا كان الملف القابل للتنفيذ ليس في الواقع رابطًا رمزيًا.إذا تم حلها بالنسبة إلى دليل الارتباط الرمزي.
الآن في حالتي، لسوء الحظ، لا يعمل أي مما سبق:
/proc/self/exe exists
ولكن تفشل في ذلكreadlink()
بسبب رفض الإذن errno 13.- ال
argv[0]
لا يملك/
للمسار المطلق أو النسبي. - ال
$PATH
لا يحتوي على الملف القابل للتنفيذ الموجود فيargv[0]
.
يبدو أن هذه المشكلة تتم مواجهتها أيضًا عند تشغيل تطبيقات sgid.في حالتي، فهو ليس sgid، ولكنه إطلاق inetd.
المحلول
حاول البحث في /proc من ثنائي suid.
نصائح أخرى
أفضل طريقة لحل هذه المشكلة هي في ملف التكوين /etc/xinetd.d/myApp، لإضافة متغير بيئة يحدد موقع الملف الثنائي مثل هذا:
service myApp
{
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/local/bin/myAppd
env = MY_APP_HOME=/usr/local/bin
port = 2354
disable = no
}
بعد ذلك، إذا تم رفض الإذن /proc/self/exe، فتحقق من وجود متغير env واستخدمه بدلاً من ذلك.
أعتقد أن الإجابة هي:يستسلم.
اطلب من المستخدم تمرير دليل التثبيت (أو أي شيء تبحث عنه) كوسيطة لسطر الأوامر.
كحل أخير، قم بتحليل الملف /etc/xinetd.d/myApp لسحب سطر الخادم الذي يتضمن المسار الكامل للملف القابل للتنفيذ الذي تم استدعاؤه عبر inetd.