툴과 개발 환경6 분 읽기

쓸 수는 있는데 읽을 수 없는 디렉터리

파일은 만들 수도 지울 수도 있는데 `open()`만 안 됐습니다. `Operation not permitted`. 전체 디스크 접근은 이미 켜져 있고 샌드박스도 무관했습니다. 범인은 TCC가 아니라 EndpointSecurity 기반 DLP 에이전트였고, 판별의 열쇠는 '현재 프로세스가 방금 만든 파일만 읽힌다'는 비대칭이었습니다.

#macos#endpointsecurity#filesystem#gotchas
개념 도식: 한 디렉터리에서 create/delete/stat은 초록으로 통과하고 read/ls/append만 빨갛게 막힌다. Full Disk Access는 이미 부여됨. 이 비대칭이 TCC가 아니라 EndpointSecurity 확장의 신호.
현재 프로세스가 방금 만든 파일은 읽히고, 이전 세션 파일은 안 읽힌다 — 파일시스템 권한으로는 불가능한 구분.

한 디렉터리에 세션 간 메모를 파일로 쌓아두고 있었습니다. 새 파일은 잘 만들어졌습니다. 그런데 이전에 만든 파일을 다시 읽으려니 전부 실패했습니다.

Operation not permitted

파일은 분명히 있습니다. stat도 됩니다. 만들 수도 지울 수도 있습니다. open()만 안 됩니다.

쓸 수는 있는데 읽을 수 없다

정확히 이런 상태였습니다.

  • 파일 생성 — 된다
  • 파일 삭제 — 된다
  • stat — 된다
  • 기존 파일 열기 — 실패 (cat, head, cp, 모든 읽기 도구)
  • append (>>, tee -a) — 실패
  • 해당 디렉터리 ls — 실패 (그래서 경로를 미리 알고 있어야 한다)
  • 현재 프로세스가 방금 만든 파일 — 읽힌다

마지막 줄이 진단의 열쇠였습니다. 같은 세션에서 만든 파일은 읽히고, 이전 세션이 만든 파일은 안 읽힙니다. 파일시스템 권한이라면 이런 구분을 할 수 없습니다. 프로세스 단위로 판단하는 무언가가 중간에 끼어 있다는 뜻입니다.

원인은 EndpointSecurity 시스템 확장이었습니다. 조직에서 배포한 DLP(정보 유출 방지) 에이전트가 홈 디렉터리 일부를 보호 대상으로 잡고, 허가되지 않은 프로세스의 open()을 거부하고 있었습니다.

TCC가 아니라는 게 핵심이다

그래서 흔한 해결책이 전부 안 통합니다.

  • 전체 디스크 접근 권한 — 이미 부여돼 있었다. 무관하다.
  • 샌드박스 비활성화 옵션 — 차이 없다.
  • 권한 재설정, tccutil — 무관하다.

보호 대상 밖의 경로는 완전히 정상이었습니다. 디스크도 파일시스템도 멀쩡하고, 특정 경로에 대해서만 커널 확장이 거부하고 있었습니다.

여기서 진짜 위험이 나옵니다. 메모 디렉터리가 사실상 write-only가 됐습니다. 새 메모는 계속 쌓이는데 다시 읽히지 않고, 인덱스 파일은 append가 안 되니 갱신도 안 됩니다.

만약 이 상황을 모르고 "인덱스를 갱신하자"며 지우고 새로 쓰는 방식을 택했다면, 기존 19KB짜리 인덱스를 읽지도 못한 채 파괴했을 겁니다. 삭제와 생성은 되고 읽기만 안 되는 조합이 정확히 그 사고를 유도합니다.

판별 기준

증상 확인:

touch ~/protected/new.txt && cat ~/protected/new.txt   # OK (같은 세션 생성)
cat ~/protected/old.txt                                # Operation not permitted
ls ~/protected                                          # Operation not permitted
echo x >> ~/protected/old.txt                           # Operation not permitted
stat ~/protected/old.txt                                # OK

활성 EndpointSecurity 확장 확인:

systemextensionsctl list

여기에 DLP/EDR 계열 확장이 떠 있으면 TCC를 아무리 뒤져도 답이 안 나옵니다. 그쪽을 봐야 합니다.

전체 디스크 접근 = 부여됨  &&  특정 경로만 open() 실패
  &&  현재 프로세스 생성 파일은 읽힘
→ TCC 가 아니라 EndpointSecurity 확장을 의심할 것

정직하게

  • 진단이 늦었습니다. 처음엔 권한 문제로 보고 전체 디스크 접근을 확인했고, 이미 켜져 있으니 다음엔 샌드박스를 의심했습니다. 둘 다 아니었습니다. "같은 세션에서 만든 파일만 읽힌다"는 비대칭을 더 일찍 봤어야 했습니다.
  • 근본 해결을 못 했습니다. 선택지는 두 개인데 둘 다 제 손 밖입니다 — 작업 디렉터리를 보호 대상 밖으로 옮기거나, 해당 프로세스를 허용 목록에 넣도록 요청하거나. 결국 디렉터리를 옮기는 쪽으로 처리했습니다.
  • 같은 원인으로 git clone이 "Unable to read current working directory"로 실패하는 것도 나중에야 연결됐습니다. 증상이 전혀 달라 보여 별개 문제로 취급하고 있었습니다.
  • 이 현상이 어느 범위의 프로세스에 적용되는지 체계적으로 확인하지 않았습니다. 특정 도구만 막히는 건지, 서명되지 않은 모든 프로세스가 막히는 건지 모릅니다.

이 글의 쓸모는 "특정 제품이 이렇더라"가 아니라 "TCC를 아무리 만져도 안 풀리는 파일 접근 거부가 있고, 판별 기준은 이것" 입니다. 당신이 Operation not permitted를 만났는데 전체 디스크 접근이 이미 켜져 있다면 — 방금 만든 파일은 읽히는지 한 번 확인해 보세요. 그 비대칭이 답을 반쯤 알려줍니다.

관련 글