socat: EXEC가 올바르게 전달되지 않았습니다.

socat: EXEC가 올바르게 전달되지 않았습니다.

먼저 사용자에게 문자열을 출력한 다음 입력을 받아들이는 작은 프로그램이 있습니다. 대신, 포트에서 보내고 받는 방식으로 프로그램이 작동하기를 원합니다. 이를 시도하고 달성하기 위해 명령을 실행했습니다 socat TCP4-LISTEN:1337,reuseaddr,fork EXEC:./program. 이 명령을 사용하여 nc 127.0.0.1 1337프로그램을 실행하고 기대할 수 있기를 원합니다 .

  1. 프로그램에서 메시지 받기
  2. 입력을 제공할 수 있는
  3. 연결 끊김

그런데 이를 이용해 프로그램을 실행하면 socat다음과 같다 .

  1. 의견을 제시하다
  2. 프로그램에서 받은 메시지
  3. 다른 입력 제공
  4. 연결 끊김

왜 이런 일이 발생하는지 이해하지 못합니다. 이 명령을 사용하는 데 문제가 있습니까 socat? 그렇다면 무엇이 빠졌거나 잘못되었는지 알려주세요.

이것이 절차입니다.

#include <stdio.h>

void vuln(void) {
    printf("Input\n");
    char buffer[256];
    gets(buffer); // potential buffer overflow
}

int main(void) {
    vuln();
    return 0;
}

답변1

C에서는 printf버퍼링된 I/O 라이브러리의 일부입니다. 스트림에 기록된 데이터는 메모리에 "버퍼링"됩니다(즉, 커널에 직접 기록되지 않음).

기본적으로 stdout(데이터가 기록되는 스트림 printf)은라인 버퍼스트리밍은 개행이 스트림에 기록될 때까지(또는 플러시를 트리거하는 다른 상황) 바이트가 메모리 버퍼에 저장됨을 의미합니다.

표준 출력이 터미널과 연관되지 않은 stdout경우블록 버퍼스트리밍은 버퍼가 가득 찰 때까지 바이트가 메모리 버퍼에 저장됨을 의미합니다.

터미널에서 프로그램을 실행하면 다음을 호출하여 플러시가 트리거 '\n'됩니다 printf(라인 버퍼링되기 때문에).

$ ./a.out
Input
whatever-you-type
$

출력을 파일로 리디렉션하면 다른 동작이 나타납니다.

Terminal 1               Terminal 2
--------------------     --------------------
$ ./a.out > /tmp/out
                         $ cat /tmp/out
                         $
type-input
$
                         $ cat /tmp/out
                         Input
                         $ 

socat없이 실행하면 pts출력 스트림은 블록 버퍼 모드이고, 출력 스트림과 함께 실행하면 pts라인 버퍼 모드입니다.

이 동작을 재정의하려는 경우 몇 가지 옵션이 있습니다. 버퍼링된 데이터를 명시적으로 플러시하는 함수를 호출할 수 있습니다.

printf("Input\n");
fflush(stdout);

또는 다음을 호출하기 전에 출력 스트림의 버퍼링 모드를 명시적으로 설정할 수 있습니다 printf.

setvbuf(stdout, NULL, _IONBF, 0); // _IONBF = Unbuffered
printf("Input\n");

Robert Love의 책 3장을 참조하세요.리눅스 시스템 프로그래밍더 자세한 설명을 원하시면.

관련 정보