우리는 다음과 같은 사용자 요청에 따라 출력을 인쇄하는 C로 작성된 거대한 클라이언트 서버 비즈니스 애플리케이션을 보유하고 있습니다.
system("/usr/local/sisis-pap/cups/bin/lpr ....");
위 lpr
명령에는 공유 라이브러리가 필요하며 동적 로더가 해당 라이브러리를 찾을 위치를 알 수 LD_LIBRARY_PATH
있도록 환경 변수를 통해 해당 라이브러리에 액세스합니다. ld-linux.so
환경 변수가 있습니다. 즉, 다음과 같습니다.
p = getenv("LD_LIBRARY_PATH");
printf("LD_LIBRARY_PATH env [%s]\n", p==NULL?"":p);
system("env | grep LD_LIBRARY_PATH");
잘 인쇄되지만 하위 쉘에서는 손실됩니다.
정확하게 말하면 이것은 애플리케이션 아래의 경우일 뿐이며 문제를 연구하기 위해 누락된 환경 변수를 시뮬레이션하기 위해 특별히 작성된 작은 C-pgm을 사용할 수 없습니다. 애플리케이션은 cron을 통해 루트로 시작됩니다(즉, 매일 아침 새로 고쳐짐).
리눅스는 SuSE SLES15입니다.
LD_LIBRARY_PATH
무엇이 사라지는 지 아시나요 system(3)
? 매뉴얼 페이지에는 그런 내용이 나와 있지 않습니다.
답변1
이 C 코드를 컴파일하고 실행하면 문제를 재현할 수 있습니다 root
.
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
char *p;
p = getenv("LD_LIBRARY_PATH");
printf("getenv(): LD_LIBRARY_PATH env [%s]\n", p==NULL?"":p);
seteuid(900118);
printf("effective uid now %d\n", geteuid());
system("echo LD_LIBRARY_PATH in child: ; env | grep LD_LIBRARY_PATH");
exit(0);
}
sys seteuid()
호출은 애플리케이션 서버가 소위 프로세스에서 실행되도록 하여 생성된 하위 프로세스를 secure-execution mode
제거합니다 .LD_LIBRARY_PATH