2P by GN⁺ | ★ favorite | 댓글 1개
  • Ariel Miculas는 PowerPC32에서 gdbserver 멀티스레드 디버깅이 깨지는 문제를 추적해 Linux 커널의 메모리 손상 버그를 찾았지만, 최종 수정은 메인테이너의 별도 패치로 들어가 Reported-by 크레딧만 받음
  • 단서는 같은 증상을 다룬 과거 메일 스레드와 task_struct 안의 thread_struct thread 위치 변경 커밋이었고, 일부 스레드가 잘못된 프로세스 상태에 머물며 gdbserver가 제어를 잃는 현상으로 이어짐
  • 원인 분석에는 pahole, ftrace, PowerPC DABR 기반 하드웨어 브레이크포인트가 쓰였고, ptrace_put_fpr의 버퍼 오버플로가 task_struct.__state 같은 필드를 덮어쓴다는 점이 확인됨
  • 오버플로는 32비트 요소용 인덱스를 64비트 배열에 적용하면서 발생했고, 32개 항목뿐인 fp_state.fpr 배열 뒤로 사용자 측 gdbserver가 최대 256바이트까지 쓸 수 있는 상태였음
  • PowerPC 메인테이너 Michael Ellerman은 자체 수정안을 적용했으며, 이후 답장에는 Reported-by만으로는 기여가 제대로 반영되지 않았고 패치를 함께 발전시켰어야 했다는 사과가 담김

PowerPC32에서 깨진 gdbserver 디버깅

  • 약 1년 반 전, Ariel Miculas는 이전 회사에서 프로젝트의 디버깅 기능을 막고 있던 문제를 조사할 시간을 요청함
  • 문제는 PowerPC32 아키텍처에서 gdbserver가 멀티스레드 애플리케이션을 제대로 디버깅하지 못하는 상황이었음
    • gdbserver 연결이 끊기고 디버그 세션을 더 이상 제어할 수 없었음
    • 원인이 toolchain, gdbserver, Linux kernel, 커스텀 커널 패치 중 어디에 있는지 확실하지 않았음
  • 기존 조사와 검색 끝에 같은 증상을 다룬 메일 스레드를 찾음
    • 이 스레드는 문제를 유발한 커밋도 가리킴
    • 해당 패치는 task_struct 중간에 있던 thread_struct thread 정의를 끝으로 옮기는 변경이었음

스레드 상태에서 메모리 손상으로 좁혀진 단서

  • Holger Brunck의 기존 분석에 따르면 gdbserver는 각 스레드마다 커널에 SIGSTOP을 보내고 응답을 기다렸지만, 오류 상황에서는 커널이 일부 신호에만 응답함
  • 낮은 수준에서는 gdbserver와 상호작용한 뒤 일부 스레드가 잘못된 프로세스 상태에 놓였고, gdbserver는 이후 제어권을 잃음
  • Ariel은 PowerPC 관련 커밋 설명과 task_struct 주변 변경을 3~4일 동안 읽으며 이후 커널 버전에서 문제가 해결됐는지 확인했지만 해결책을 찾지 못함
  • thread_struct thread의 위치를 바꿔가며 재현 조건을 확인하고, paholetask_struct 레이아웃을 살핌
  • ftrace로 디버깅 대상 프로세스의 스레드가 언제 스케줄되는지 추적함
    • 멈춘 스레드들은 다른 스레드와 달리 한 번만 스케줄됨
    • 이 관찰로 메모리 손상 가능성을 다시 보게 됨

하드웨어 브레이크포인트로 찾은 실제 원인

  • x86의 debug registers처럼 PowerPC에도 DABR register를 이용한 유사 기능이 있음을 확인함
  • Linux에서 하드웨어 브레이크포인트를 쓰는 방법을 조사한 뒤, Stack Overflow 답변을 바탕으로 커널 모듈을 구현함
  • 이 모듈로 task_struct.__state 필드에 하드웨어 브레이크포인트를 걸어 누가 값을 쓰는지 추적함
  • 커스텀 커널 모듈이 task_struct.__state에 쓰는 위치의 스택 트레이스를 보여줬고, 그중 이상한 경로가 ptrace_put_fpr버퍼 오버플로로 이어짐
  • ptrace_put_fpr는 POKEUSER API에서 사용되며, 오버플로는 __state 같은 task_struct의 중요한 필드를 덮어씀
    • __state는 프로세스 상태를 저장함
    • 커널은 디버거에 의해 멈춘 프로세스를 추적할 때도 이 필드를 사용함

256바이트까지 넘어갈 수 있던 배열 쓰기

  • 오버플로의 원인은 32비트 요소 배열에 쓰이도록 설계된 인덱스를 64비트 요소 배열에 적용한 데 있었음
  • FPR을 가리키는 인덱스는 64개였고, 64비트 요소 기준 접근 범위는 64 * 8 = 512바이트였음
  • 실제 fp_state.fpr 배열에는 32개 엔트리만 있었으며, 사용할 수 있는 메모리는 32 * 8 = 256바이트였음
  • 결과적으로 사용자, 즉 gdbserver가 배열 끝을 지나 최대 256바이트까지 쓸 수 있었음

업스트림 제출과 크레딧 갈등

  • Ariel은 프로세스 상태 메모리를 덮어쓸 수 있는 메모리 손상 문제가 보안 영향을 가질 수 있다고 보고 security@kernel.org로 패치를 보냄
    • 이 메일링 리스트는 비공개라 원래 제출한 패치는 링크할 수 없었음
  • PowerPC 메인테이너 Michael Ellerman은 개인적으로 연락해 문제를 다루겠다고 답함
  • Ariel은 두 가지 수정 패치를 보냄
    • 보안 메일링 리스트에 보낸 원래 패치
    • 원래 제출에 대한 제안을 반영한 다른 버전의 패치
  • 두 번째 패치는 PowerPC64에서 PowerPC32 동작을 에뮬레이션하던 기존 커널 코드를 기반으로 했고, 해당 코드는 FPR 인덱싱을 올바르게 처리하고 있었음
  • Michael Ellerman은 두 패치 모두 받아들이지 않고 자체 수정안을 구현함
  • Ariel은 이 문제를 고친 공로와 첫 커널 기여자로서의 크레딧을 위해 자신의 패치가 받아들여지길 원했고, 피드백을 반영해 후속 버전을 보낼 의사도 있었음
  • 실제로 받은 크레딧은 Reported-by 태그뿐이었고, Ariel은 원인 분석·수정·테스트·검증·사내 피드백 반영·최신 커널 적용에 들인 노력에 비해 부당하다고 느낌
    • Linux 문서상 Reported-by는 버그를 찾고 보고한 사람에게 크레딧을 주는 태그임
    • 해당 문제는 이미 6년 전에 보고된 적이 있었음

업데이트와 사과 답장

  • Hacker News 사용자는 Michael Ellerman이 “패치에 감사하지만 다르게 고치고 싶다. 아래 패치를 시험해 버그가 고쳐지는지 확인해줄 수 있느냐”고 쓴 메일을 지적함
  • 이 메일은 Michael Ellerman이 Ariel의 패치를 리뷰하기보다 자체 구현을 선택하고, Ariel에게 그 패치를 테스트해달라고 요청한 상황을 보여줌
  • Ariel은 보안 메일링 리스트에 보냈던 원래 패치를 찾아 linuxppc-dev로 메일 스레드를 전달
  • 이후 업데이트에는 패치 처리 방식에 대한 사과 답장이 포함됨
    • “당신의 패치를 함께 발전시키는 데 더 많은 시간을 썼어야 했다”는 내용이 포함됨
    • Reported-by 태그가 Ariel의 기여를 제대로 반영하지 못했다는 내용도 담김

댓글과 토론

Hacker News 의견들
  • 전체 패치를 받아들이지 않더라도 Ariel Miculas에게 공로를 주는 편이 더 적절했음
    이 보안 이슈는 그가 찾아내고 수정안을 보내지 않았다면 아무도 고치지 않았을 가능성이 큼
    Michael이 그의 패치를 읽고 스타일만 일부 바꾼 뒤 자기 이름으로 제출했다면 공로를 주지 않는 건 비윤리적이며, 코드가 형편없었더라도 여전히 협업이었기 때문에 그렇게 당하면 다시 같이 일하고 싶지 않을 것임

    • 예전에는 남의 기여를 가져와 내 브랜치에서 완전히 다시 작성해 병합하거나, GitHub PR에 새 커밋으로 재작성해 넣는 게 괜찮다고 생각했음
      후자는 그래도 Co-Authored-By가 남지만, 누군가 내 프로젝트 코드를 커밋 이력 없이 자기 저장소에 덤프해 “포크”한 뒤에야 기여자 입장에서는 꽤 씁쓸한 경험이라는 걸 깨달았음
      코드가 나빴더라도 병합된 리팩터링된 수정은 그 코드 없이는 존재하지 않았을 것이고, “내 버전이 더 좋다”는 말은 꽤 무시하는 태도로 느껴질 수 있음
      다만 유지관리자의 실제 답변을 링크한 답글을 보니 마지막 문장은 성립하지 않음
    • 동의함. 유지관리자가 품질 때문에 커널에 들어갈 코드는 직접 쓰겠다고 할 수는 있고, 그 자체는 이해됨
      하지만 이 경우 글쓴이는 그 패치의 공동 저자에 가까움
      학술 출판으로 치면 누군가에게 프리프린트를 보냈더니, 그 사람이 같은 주제로 논문을 내면서 감사의 글에만 올리고 공동 저자로는 넣지 않은 것과 비슷함
      여기서는 출판이 아니라 커널 개발이지만, 저자 표기는 전문 이력서에서 여전히 중요함
    • 경험 많은 유지관리자의 역할은 다른 사람의 기여가 깔끔하게 들어가도록 최대한 돕는 조력자라고 봄
      스타일과 구조 일관성에 대한 피드백은 필요하지만, 훌륭한 유지관리자는 공로를 인정하고 뒤에서 일이 부드럽게 흘러가게 만드는 사람임
    • Linux 커널에 처음 몇 번 패치를 보냈을 때는 LKML을 통한 반자동 제출도 가능하기 전이라 유지관리자와 대화하면서 진행했음
      그때 Ted Tso가 내 작업의 정확성에 만족하자 패치를 넣었고, 나는 공로를 요구하지도 받지도 않았음
      내 관심은 커널 개선뿐이었고 이름을 남기는 데는 관심이 없었음
      몇 년 뒤 다른 일로 기여자 목록에 이름이 들어가긴 했지만, 어느 쪽이든 신경 쓰지 않았음
    • 그는 공로를 받았음. 커밋에 Reported-by: Ariel Miculas라고 되어 있고, 정확해 보임
  • 유지관리자의 패치가 더 나음

    1. 32비트 케이스에서 fpidx < (PT_FPSCR - PT_FPR0) 검사를 잃지 않음
    2. put 함수에서 fpidx가 범위를 벗어났을 때 쓰이는 *data = child->thread.fp_state.fpscr; 대체 대입을 잃지 않음
    3. TS_FPRWIDTH가 1이면 항등식으로 줄어드는 불필요한 FPRINDEX 매크로를 피함
      원래 패치 커밋 메시지는 “PPC32에서는 TS_FPRWIDTH가 1이라고 가정해도 된다”고 해놓고도 FPRNUMBER, FPRHALF, FPRINDEX를 포함했음
      단순히 고칠 수 있는 배열 불일치를 찾았다고 해서 버그 있는 패치를 그대로 받아들여야 하는 건 아님
      다만 유지관리자는 Miculas가 단순 신고만 한 게 아니라 조사해서 근본 원인을 찾고 거의 같은 간단한 수정의 자기 버전까지 만들었다는 점은 인정했어야 함
      Reported-by는 해당 당사자가 철저히 조사하고 원인까지 규명했다는 뉘앙스를 담기엔 부정확함
    • 유지관리자의 작업이 더 낫다는 데는 동의함. 하지만 그냥 패치에 대해 코드 리뷰를 하고 업데이트를 요청할 수 있었음
      새 기여자에게는 프로젝트에서 흔히 그렇게 하고, 그게 올바른 방식임
      사람을 가르치고 적응시키는 과정인데, 작업을 그냥 다시 해버리면 기여 의욕을 꺾고 배울 기회도 없애게 됨
    • 디버깅은 어렵고, 때로는 매우 어려움. 익숙한 코드베이스에서 수정안을 작성하는 건 비교적 사소한 일이고, 특히 앞선 수정의 동작 버전이 안내서로 있으면 더 쉬움
      두 번째 버전을 쓰는 건 언제나 더 쉬움
      이걸 단순한 수정이라고 하는 건 소프트웨어 개발에서 버그 수정에 들어가는 작업량을 이해하지 못하는 것임
      여기서 Michael도 처음에는 재현하지 못했고 나중에야 확정했다고 인정했음
      이는 OP가 디버깅과 수정에 들인 작업량을 잘 보여주며, 그 작업을 빼앗는 건 옳지 않음
    • “단순히 고칠 수 있는 배열 불일치를 찾았다고 해서 버그 있는 패치를 그대로 받아들여야 하는 건 아님”이라는 말은 남의 말을 억지로 바꿔 넣는 것임
      원문에서는 패치를 받아 공로를 얻고 커널 기여자가 되고 싶었고, 피드백을 반영해 후속 버전도 보낼 의향이 있었다고 했음
    • 아무도 원 패치를 그대로 받아들여야 했다고 말하는 게 아님
      유지관리자는 OP의 코드를 체크아웃해서 원하는 변경을 한 뒤 공동 저자로 커밋하는 데 필요한 2분 정도를 쓰면 됐음
      그렇게 하면 가장 좋은 수정이 병합되고 다른 사람의 작업도 인정받음
      특히 OP가 공로를 인정받고 싶다고 명확히 표현했기 때문에 그게 최선이었음
      다만 이런 저장소 유지관리자들은 사회적 예의를 자주 놓치는 것 같아 놀랍지는 않음
    • 여러 오픈소스에 수많은 패치와 PR을 보냈고, 대부분은 내 불편을 해결하려는 목적이었음
      PR은 여러 이유로 받아들여지지 않는 경우가 많지만 신경 쓰지 않음
      코드를 공개해두기 위해 PR을 보내는 것이고, 병합될 만큼 “좋게” 만들려고 시간을 쓰지는 않음
      그대로 제공하고, 누군가 충분히 마음에 들면 그 사람이 절차를 처리하면 됨
      어떤 것은 그대로 병합됐고, 어떤 것은 저장소 소유자가 조금 고쳐서 병합했음
      오픈소스 코드를 영광이나 인기 때문에 쓰는 게 아니라 좋아서 하는 것임
      80년대와 90년대가 그리움
  • Linux 커널은 보상이 아니고, OP에게 공감은 하지만 커뮤니티에서 온 버전보다 유지보수하기 좋은 해법을 선호하는 게 맞음
    그래서 유지관리자는 권한 범위 안에 있었음
    그렇지만 수정에 기여한 사람에게 공로 표시를 하는 건 아주 쉬움
    Node.js에서는 릴리스 노트에서 공로를 주고, PR의 일부 작업을 가져와 수정했을 때는 Co-Authored-By:를 추가하려고 노력함
    오래 유지관리하다 보면 공로가 자신에게는 덜 중요해지기 때문에, 새 기여자에게는 그것이 매우 중요하다는 사실을 잊기 쉬움
    이 경우처럼 공로 공유가 OP에게 중요했고 또 마땅했던 상황에서 더 세심하지 못했던 건 OP와 해당 Linux 영역 모두에게 손실임

    • 프로젝트에 많은 노력을 들여 기여를 수정했는데 마지막에 “내 버전이 더 좋으니 가라”는 말을 들으면 화날 것임
      커뮤니티 노력에 의존하는 프로젝트가 지속될 방식이 아님
      Linux 커널처럼 크고 존중받는 프로젝트라면 프로젝트의 최선도 챙기고 새 기여자도 존중할 줄 아는 사람들이 있을 거라고 생각했음
      최선이 아닌 해법을 새 기여자라는 이유만으로 받아들이자는 사람은 없을 것임
      올바른 방식은 패치를 리뷰하고, 무엇이 왜 문제인지 설명하고, 어떻게 다시 쓰면 좋을지 제안하며, 필요하면 그 부분을 함께 작성해 공동 저자가 되는 것임
      그래야 앞으로도 관심을 갖는 기여자 흐름이 생김
    • “Linux 커널은 보상이 아니다”라는 말은 이 글을 보면 최악의 의미로 맞는 것 같음
    • 그는 Reported-By 태그로 공로를 받은 것처럼 보임
  • 커널 문서에는 태그 관례 중 하나로 Suggested-by가 정의되어 있음
    Suggested-by: 태그는 패치 아이디어를 해당 사람이 제안했음을 나타내며, 그 아이디어에 대한 공로를 보장함
    특히 그 아이디어가 공개 포럼에 올라온 것이 아니라면 제안자의 허락 없이 추가하면 안 된다고 되어 있음
    아이디어 제보자에게 성실히 공로를 주면, 그들이 앞으로도 다시 도와줄 가능성이 커진다는 취지도 적혀 있음
    이 상황에는 Suggested-by가 더 적절했을 수 있음
    문제의 해법을 찾았지만 프로젝트에 익숙하지 않아 패치의 정확한 문법은 유지되지 않았다는 의미를 더 잘 전달함
    참고: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...

    • 패치들을 비교해보지는 않았지만, 아래 댓글 [1]에 따르면 받아들여진 패치와 제안된 패치의 유일한 차이는 수정 위치라고 함
      한쪽은 if 밖의 ifdef에 있고, 다른 쪽은 내부 if문에 있다는 차이뿐이며 기술적 차이가 아니라 스타일 차이라는 것임
      그렇다면 작성자는 단순히 패치 아이디어를 “제안”한 것보다 훨씬 많이 한 것임
      이슈를 디버깅하고 전체 패치를 작성했고, 작은 변경 하나로 받아들여진 셈임
      1: https://news.ycombinator.com/item?id=37672558
    • 그 방식도 가능하지만, 보안 이슈가 아닌 경우에 더 잘 맞을 것 같음
      보안 이슈에서는 형식보다 속도와 정확성이 더 중요하고, 커널 유지관리자들은 Reported-by로 공로를 준 점에서 올바르게 처리했음
      Suggested-by가 조금 더 낫긴 하겠지만 OP가 원하는 것은 아니며, OP는 아주 작은 패치를 근거로 “커널 기여자”라는 표식을 원한 것처럼 보임
  • 이 스레드의 일부 반응을 보니, 몇몇은 특히 주니어나 중급 개발자를 관리하지 않았으면 좋겠음
    팀에 열정적인 주니어가 있고, 어떤 이슈에 도움이 되지만 품질은 부족한 PR을 냈다면, “충분히 좋지 않다”고 꾸짖고 코드를 버린 뒤 직접 다시 쓰는 건 최악의 대응임
    사기를 꺾고, 그 사람과 자신의 시간을 낭비하고, 아무것도 배우지 못하게 만들며, 다음번에는 개선하거나 의미 있게 기여하지 못하게 하고, 도움 요청이나 자발적 기여도 꺼리게 만듦
    복잡한 코드 영역에 뛰어든 경우라도 더 나은 상호작용 방식이 있음

    • 회사나 팀에서 주니어를 관리하고 코칭하는 것과, 인터넷의 임의의 사람이 작은 패치를 보내는 것은 다름
      팀의 주니어는 한동안 머무를 것이라는 기대가 있고, 면접을 통해 기본 역량도 어느 정도 확인했으니 성장 가능성을 신뢰할 수 있음
      인터넷의 임의의 사람은 계속 남을 의무가 없고, 이런 “드라이브바이” 수정은 대부분 남지 않음
      그 사람이 실제로 어떤 능력이 있는지, 수정 요청에 어떻게 반응할지도 모름
      관리 관점에서 가장 답답한 일 중 하나는 누군가가 임의의 사람을 내 보고 라인에 넣고 그 사람의 성과를 책임지게 만드는 것임
      이제 인터넷의 자격의식 강한 누군가가 며칠 들여 수준 낮은 수정을 만들었고, 내가 그 사람의 관리자처럼 코칭해야 한다고 상상해보면 이 비유는 말이 안 됨
      GitHub에서 프로젝트를 호스팅하면 원치 않는 PR 때문에 왜 난리인지 예전에는 궁금했지만, 이제 이해가 됨
      임의의 PR을 상대하기 싫어하면 “사기를 꺾고 시간을 낭비시키는 나쁜 관리자”라고 비난받는다는 건 과한 자격의식임
      예: https://news.ycombinator.com/item?id=25940799
    • 지나치게 의욕적인 주니어가 우선순위도 아니고 맡은 일도 아닌 작업을 일주일 동안 해결했다면, 따로 불러 “이건 지금은 보류하고 나중에 다시 보자. 지금은 X가 우선이라 여기에 시간을 쓸 수 없다”고 말할 수 있음
      프로가 된다는 건 자기 자신과 작업물을 분리하고, 동료가 악의적인 계획으로 나를 방해하려는 게 아니라는 점을 배우는 일이기도 함
      누구나 몇 달 작업한 프로젝트가 취소된 적이 있고, 코드 리뷰에서 거친 코멘트를 받은 적이 있음
      그런 일을 받아들이고 배우는 건 프로로서의 몫임
      물론 직설적이고 무례한 사람들도 그런 태도가 많은 관계를 망친다는 걸 배워야 함
      우리는 예술가가 아니라 프로임
      주니어 토목 엔지니어가 구조 결함이 있는 다리를 설계했고 선임이 “미안하지만 이건 이제 구제하기 어려우니 전부 다시 해야겠다”고 했다면 선임은 문제없음
      주니어의 자존심을 지키려고 허술한 다리를 운전하고 싶지는 않음
      큰 오픈소스 프로젝트를 유지관리해본 경험이 많지 않은 댓글들이 유지관리자를 유독 독하다고 보는 것 같음
      작은 오픈소스 프로젝트를 유지해보면 임의의 사람의 PR을 받는 건 일이 많고, 종종 직접 하는 것보다 더 많은 시간이 듦
      코드를 꼼꼼히 리뷰하고, 기여자와 소통해 문제를 고치고, 기대 품질과 관례를 맞추는 데 드는 시간이 큼
      직장 주니어는 이미 면접을 거쳤지만, 여기서는 임의의 낯선 사람이 변경을 요청하는 것임
      PR이 거절되면 속상하지만 양쪽 입장을 모두 이해함
      유지관리자의 대화를 보면 특별히 못되거나 무례해 보이지는 않음
    • 다시 읽어보는 게 좋겠음. 실제로 그런 일이 벌어진 것처럼 보이지 않고, 적어도 한쪽의 감정적인 재구성일 가능성이 있음
    • 정말 실망스럽게도 이 스레드에는 독한 댓글이 많음
      거의 LKML의 안 좋은 스레드처럼 느껴짐
      그 사람이 말 그대로 95%의 작업을 했는데, 그 공로를 인정받고 싶어 한다고 비판받고 있음
      대체 왜 그러는지 모르겠음
    • 이 스레드는 나쁜 대인관계를 드러내는 피뢰침 같고, HN 독자 연령대를 생각하면 꽤 민망함
  • 두 패치를 비교해보면 분명한 차이가 보임
    링크된 글의 기여는 if...else 양쪽 분기의 동작을 바꾸지만, 최종 기여는 if 분기 안의 경로만 바꿈
    유지관리자가 코드를 바꾼 데에는 이유가 있었을 것임
    그래도 실제 수정은 거의 100% 복사된 것이므로 원 패치 작성자에게 공로를 주는 게 적절했음

    • 위 메일 대화의 원래 패치도 마찬가지임
      원래 결과는 PPC32 아키텍처에서 flush_fp_to_thread도 없고 else 조건도 없음
      최종 패치는 flush_fp_to_thread(child);를 호출하고, fpidx 범위 검사 안에서 CONFIG_PPC32 여부에 따라 처리한 뒤, 범위 밖이면 fpscr를 대입함
      그래서 두 해법 사이에는 실제 차이가 있음
      어느 쪽이 맞거나 더 나은지는 말할 수 없지만, 결과가 다르다는 점은 분명함
    • 오래 C를 써온 입장에서는 커스텀 매크로가 잔뜩 들어간 코드가 오면 조심스러울 것임
      C에 대한 미숙함을 나타낼 수도 있음
      큰 코드베이스 유지보수는 절반은 불 끄기이고, 절반은 이름 충돌 회피
    • 글 작성자임. 안타깝게도 내가 보낸 원래 패치는 Linux 커널 보안 메일링 리스트에만 보냈기 때문에 링크할 수 없음
      그 패치는 꽤 달랐고, 보여줄 수 있게 어딘가에 저장해둘 걸 그랬음
  • 이건 커널 기여의 일반적인 일부임
    문제를 가장 간결하게 전달하는 방식이 패치인 경우가 많아서 패치를 보내는 것이고, 기대치는 그들이 그 패치를 쓰지 않을 것이라는 쪽이어야 함
    떠오르는 것만 해도 나에게 이런 일이 최소 세 번 [1][2][3] 있었음
    솔직히 화낼 생각도 해본 적이 없는데, 내 주된 목표는 버그를 고치는 것이었고 그렇게 되어 기뻤기 때문임
    OP에게 진심으로 권하자면 이 블로그 글은 지우는 게 좋음. 나중에 후회할 것임
    [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
    [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
    [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...

    • 상대 이름을 공개해 버스 밑으로 밀어 넣는 건 정말 안 좋아 보임
      다른 사람의 이름을 보고 꽤 놀랐음
  • 오픈소스 프로젝트에서는 이런 일이 늘 일어나고, 결국 추가 기여 의욕만 꺾음
    작년에 몇 년간 열려 있던 이슈를 맡아 PR을 만들고 테스트 코드도 고치고, 빌드 문제를 고치는 별도 작업까지 했음
    유지관리자는 빌드 문제를 고치는 PR만 가져가고 원래 이슈는 그냥 무시했음
    그 프로젝트에 다시 시간을 써서 기여할 가능성은 전혀 없음

    • 어떤 사람들은 GitHub 이력서 전체가 복사해 붙인 기여로 되어 있음
      PR을 열고, 변경 요청 코멘트를 받음
      며칠 뒤 시간이 나서 고치려 하면, 자주 기여하는 사람이 낸 다른 PR로 이미 닫혀 있음
      그 PR을 보면 내 코드와 거의 같고 변수 이름 하나만 바뀌어 있으며, “친구” 리뷰 기준으로 즉시 승인됨
      그 사람 프로필을 보면 거의 모든 기여가 다른 사람 코드를 복사한 것임
    • 작은 프로젝트 유지관리자로서 사람들이 코드나 테스트를 기여해주면 좋음
      코드베이스의 나머지 부분에 맞게 정리하도록 도우려 노력하는데, 이게 가장 어려움
      대부분 개발자는 프로젝트 관례를 먼저 배우기보다 고친 내용을 그냥 밀어 넣고 싶어 하기 때문임
      그래도 코드가 대략 맞고 병합 후 내가 15분 정도 다듬고 테스트를 조금 더하면 될 수준이면 받아들임
      이번 경우도 그런 상황으로 보이고, 유지관리자가 그렇게 했어야 함
      기여자는 공로를 얻고, 유지관리자는 상류에 받아들여질 만큼 필요한 정리만 몇 분 하면 모두 행복했을 것임
      “내 버전이 더 낫다”는 말은 실제로 더 낫든 아니든 매우 거만하고 비전문적임
      이슈가 처음 보고된 뒤 6년 동안 고치지 못했다면, 그 사람의 기여가 없었다면 당신의 수정도 없었을 것이라는 점을 인정해야 함
      “해법”을 본 뒤 그 수정을 가져가는 건 사실상 훔치는 것에 가까움
    • 내 경험상 코드 프로젝트가 원하는 기여는 버그 보고와 개선 아이디어이지, 꼭 당신의 코드가 아님
      사람들은 자기 코드가 받아들여지지 않거나 다시 작성되면 개인적으로 받아들이지만, 프로젝트를 운영하는 데서 코드 작성은 작은 부분이라는 점을 놓침
    • 흔한 문제임
      나는 보통 버그 리포트와 병합 요청을 살펴보며 패치가 어떻게 취급될지 가늠함
      기여하기 좋아 보이지 않는 프로젝트에서는 많은 버그 수정을 그냥 포기했고, 2003년의 Linux 커널도 그런 예였음
      어떤 프로젝트는 그냥 그런 식이라 엮이지 않는 게 낫고, 대개 시간 낭비가 됨
      이제는 AI 혁명 이후 오픈소스 라이선스가 광범위하게 위반되고 있어서, 그 뒤로 오픈소스 코드를 제출하지 않았고 앞으로도 하지 않을 것임
  • 여기의 독성을 정말 이해하기 어려움
    “인정, 별, 보상, 이력서 같은 걸 위해 하면 안 된다”는 식의 말은 미친 소리처럼 들림
    그런 말을 하는 사람들은 직업이 있나? 있다면 완전히 무료로 일해야 일관됨
    급여도 기여에 대한 인정의 한 형태
    개인적으로 최종 해법이 제안된 것과 달라졌더라도, 원래 해법의 발견을 바탕으로 했다면 공동 저자를 추가하는 건 아주 작은 일임
    작성자가 이 점에 대해 불평할 타당한 이유가 있고, 누군가의 기여가 인정받지 못한다고 느끼는 일은 처음도 마지막도 아닐 것임

    • 사람들은 우리가 잘한 일에 대한 인정을 전혀 원하지 않는 코드 로봇인 것처럼 굴고 있음
      패치 자체가 열등했더라도 디버깅 노력은 결코 그렇지 않았음
    • 고용 관계와는 다른 상황임
      고용에서는 사용자와 직원이 보상을 대가로 일을 한다는 합의를 맺음
      예고 없이 어떤 회사에 걸어 들어가 아무도 요청하지 않은 일을 시작했다면, 보상을 받을 권리가 있다고 주장할 사람은 거의 없음
      OP에게 일어난 일에 더 정확한 비유는 이쪽임
    • 원 작성자를 인정하고 자신은 편집자로 제시하는 편이 더 공정했을 것임
  • “미안하지만 내 버전이 더 좋아. Linux 커널 기여자가 되고 싶다면 여기 고칠 수 있는 이슈가 있어”라는 식의 대응은, 누군가가 다시는 돕지 않게 만들고 다른 사람들의 의욕까지 꺾는 훌륭한 방법임

    • 실제 표현은 달랐음
      유지관리자는 gdbserver로 크래시는 재현하지 못했지만 버그를 보여주는 테스트 케이스가 있어 확인하고 수정 테스트를 했다고 했고, “패치 고맙지만 다르게 고치고 싶었다. 아래 패치를 시도해 보고 버그가 고쳐지는지 확인해줄 수 있나?”라고 썼음
      https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-June/24...
      또 언급되지 않은 다른 리뷰 코멘트도 있었음
      PPC32만을 위한 매크로에 어떤 이점이 있는지 모르겠고, #ifdef는 가능한 피해야 하며, Michael의 패치가 더 이해하기 쉽다는 내용이었음
      https://lists.ozlabs.org/pipermail/linuxppc-dev/2022-June/24...
    • 유지관리자가 실제로 그렇게 말한 게 아님
      OP가 상대의 입에 말을 넣고 거기에 화내는 것이고, 특히 텍스트 소통에서는 좋은 전략이 아님
    • 특히 OP가 이 이슈가 6년 전에 보고된 뒤 무시됐다고 적은 뒤라면, 유지관리자의 행동은 꽤 별로임
    • 실제로는 전혀 그렇게 일어나지 않았음
      OP는 대화가 무례했던 것처럼 보이게 만들지만, 실제로는 그렇지 않았음
    • 더구나 유지관리자가 다음에도 또 “내 버전이 더 좋다”고 하면서 또 다른 버그를 가리키지 않으리라는 보장이 어디 있음?