この記事はLinux Advent Calendar 2021の18日目の記事です。
stable kernelへのコントリビュート
コントリビュートの方法としては次のような方法があると思います。
テストする
patchをレビューする
patchをバックポートする
その他
本記事ではpatchをバックポートする場合について書いてみたいと思います。基本的にはEverything you ever wanted to know about Linux -stable releases — The Linux Kernel documentationを読みましょうというところではありますが😑
patchをバックポートする理由
通常、mainlineに入ったバグ修正のpatchはstable treeに取り込まれますが、何かしらの理由で取り込まれていなかったり、patchが当たらずにエラーになったりして取り込まれないという場合があります。後者の場合は特にpatchの修正が必要になってきます。
patchをバックポートする
git-amを使ってpatchを当ててコンフリクトしたところを直してといった感じで通常通りに修正すればOKです。
stable kernel固有のお作法
バックポートしたpatchの先頭はこのような行が必要です。2行目のcommit hashの行は何パターンか書き方がある感じです。ここでは自分が書いてる書き方です。
From: <Author name><author email> commit <commit hash> upstream.
git-amでpatchを当てて、コミットメッセージを修正してcommit hashの行をつけてます。Fromの行についてはコミットメッセージには含めないで大丈夫です。これはgit-send-emailがつけてくれます。
適当なリポジトリを作って流れを試してみる
適当にリポジトリを作って流れを見てみましょう。branchはこんな感じになっています。signed-offに使うメールアドレスや名前は~/.gitconfigとリポジトリ内の.git/configを使い分けてやってます。
masami@moon:~/test-prg$ git branch * main test-1.y
ここでこんなコミットを作ったとします。この段階ではAuthorはmasami256です。
commit e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a (HEAD -> main) Author: masami256 <masami256+test@gmail.com> Date: Sat Dec 11 19:43:35 2021 +0900 Add show() to display argv Add new function show() to display argv values. Signed-off-by: masami256 <masami256+test@gmail.com>
git-format-patchでtest-1.yブランチ向けにpatchを作ります。
masami@moon:~/test-prg$ git format-patch -1 e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a test-1.y 0001-Add-show-to-display-argv.patch
できたpatchはこのようになります。
masami@moon:~/test-prg$ cat 0001-Add-show-to-display-argv.patch From e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a Mon Sep 17 00:00:00 2001 From: masami256 <masami256+test@gmail.com> Date: Sat, 11 Dec 2021 19:43:35 +0900 Subject: [PATCH] Add show() to display argv Add new function show() to display argv values. Signed-off-by: masami256 <masami256+test@gmail.com> --- test.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test.c b/test.c index c0e2886..704995c 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,13 @@ #include <stdio.h> -int main(int argc, char **argv) +void show(char **av) { - while (*argv) - printf("%s\n", *argv++); + while (*av) + printf("%s\n", *av++); +} +int main(int argc, char **argv) +{ + show(argv); return 0; } -- 2.33.1
ここで、patchが素直に当たらないようにtest-1.yブランチのコードを適当に変えてみましょう。こんな感じにします。
diff --git a/test.c b/test.c index c0e2886..b36a1ab 100644 --- a/test.c +++ b/test.c @@ -2,8 +2,8 @@ int main(int argc, char **argv) { - while (*argv) - printf("%s\n", *argv++); + for (int i = 0; i < argc; i++) + printf("%s\n", argv[i]); return 0; }
そして、test-1.yブランチから適当なブランチ(ここではtest-1.y-work)を作ってそこでgit-amを実行すると当然patchが当たらないのでエラーになります。
masami@moon:~/test-prg$ git am --reject 0001-Add-show-to-display-argv.patch Applying: Add show() to display argv Checking patch test.c... error: while searching for: #include <stdio.h> int main(int argc, char **argv) { while (*argv) printf("%s\n", *argv++); return 0; } error: patch failed: test.c:1 Applying patch test.c with 1 reject... Rejected hunk #1. Patch failed at 0001 Add show() to display argv hint: Use 'git am --show-current-patch=diff' to see the failed patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".
--rejectオプションをつけてるので.rejファイルもできてます。
masami@moon:~/test-prg$ cat test.c.rej diff a/test.c b/test.c (rejected hunks) @@ -1,9 +1,13 @@ #include <stdio.h> -int main(int argc, char **argv) +void show(char **av) { - while (*argv) - printf("%s\n", *argv++); + while (*av) + printf("%s\n", *av++); +} +int main(int argc, char **argv) +{ + show(argv); return 0; }
それはさておき、0001-Add-show-to-display-argv.patchを適用するようにコードを修正しましょう。。。
masami@moon:~/test-prg$ git am --continue Applying: Add show() to display argv
コミットメッセージを修正します。
masami@moon:~/test-prg$ git commit --amend -s
こんな感じのコミットメッセージにしました。commit hashを足したのと、最下部のsigned-offは-sオプションでついたもの、その上のfix ~は自分で書いたものです。
commit 870abfd3042fb950e59c4f1ad9e156d0b68df259 (HEAD -> test-1.y-work) Author: masami256 <masami256+test@gmail.com> Date: Sat Dec 11 19:43:35 2021 +0900 Add show() to display argv commit e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a upstream. Add new function show() to display argv values. Signed-off-by: masami256 <masami256+test@gmail.com> [fix conflict to use show()] Signed-off-by: Masami Ichikawa <masami256@gmail.com>
test-1.yブランチ向けにgit-format-patchでpatchを再作成します。
masami@moon:~/test-prg$ git format-patch -1 870abfd3042fb950e59c4f1ad9e156d0b68df259 test-1.y 0001-Add-show-to-display-argv.patch masami@moon:~/test-prg$ cat 0001-Add-show-to-display-argv.patch From 870abfd3042fb950e59c4f1ad9e156d0b68df259 Mon Sep 17 00:00:00 2001 From: masami256 <masami256+test@gmail.com> Date: Sat, 11 Dec 2021 19:43:35 +0900 Subject: [PATCH] Add show() to display argv commit e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a upstream. Add new function show() to display argv values. Signed-off-by: masami256 <masami256+test@gmail.com> [fix conflict to use show()] Signed-off-by: Masami Ichikawa <masami256@gmail.com> --- test.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test.c b/test.c index 4f83ff9..704995c 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,13 @@ #include <stdio.h> -int main(int argc, char **argv) +void show(char **av) { - for (int i; i < argc; i++) - printf("%s\n", argv[i]); + while (*av) + printf("%s\n", *av++); +} +int main(int argc, char **argv) +{ + show(argv); return 0; } -- 2.33.1
これをgit-send-emailでメールします。
masami@moon:~/test-prg$ git send-email --to=masami256+test@gmail.com ./0001-Add-show-to-display-argv.patch ./0001-Add-show-to-display-argv.patch (mbox) Adding cc: masami256 <masami256+test@gmail.com> from line 'From: masami256 <masami256+test@gmail.com>' (body) Adding cc: masami256 <masami256+test@gmail.com> from line 'Signed-off-by: masami256 <masami256+test@gmail.com>' (body) Adding cc: Masami Ichikawa <masami256@gmail.com> from line 'Signed-off-by: Masami Ichikawa <masami256@gmail.com>' From: Masami Ichikawa <masami256@gmail.com> To: masami256+test@gmail.com Cc: Masami Ichikawa <masami256@gmail.com> Subject: [PATCH] Add show() to display argv Date: Sat, 11 Dec 2021 20:37:23 +0900 Message-Id: <20211211113723.79728-1-masami256@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The Cc list above has been expanded by additional addresses found in the patch commit message. By default send-email prompts before sending whenever this occurs. This behavior is controlled by the sendemail.confirm configuration setting. For additional information, run 'git send-email --help'. To retain the current behavior, but squelch this message, run 'git config --global sendemail.confirm auto'. Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll):
まず、e[dit]でメールのサブジェクトを変更します。
From 870abfd3042fb950e59c4f1ad9e156d0b68df259 Mon Sep 17 00:00:00 2001 From: masami256 <masami256+test@gmail.com> Date: Sat, 11 Dec 2021 19:43:35 +0900 Subject: [PATCH for test-1.y] Add show() to display argv commit e8757ffa89dc4aeb1dedec7f811b3fecaf4de75a upstream. Add new function show() to display argv values. Signed-off-by: masami256 <masami256+test@gmail.com> [fix conflict to use show()] Signed-off-by: Masami Ichikawa <masami256@gmail.com>
この時点では送信するpatchのコミットメッセージはオリジナルのままです。 変更したらエディタを終了してメニューに戻ります。そして、y[es]で送信しましょう。
(mbox) Adding cc: masami256 <masami256+test@gmail.com> from line 'From: masami256 <masami256+test@gmail.com>' (body) Adding cc: masami256 <masami256+test@gmail.com> from line 'Signed-off-by: masami256 <masami256+test@gmail.com>' (body) Adding cc: Masami Ichikawa <masami256@gmail.com> from line 'Signed-off-by: Masami Ichikawa <masami256@gmail.com>' From: Masami Ichikawa <masami256@gmail.com> To: masami256+test@gmail.com Cc: Masami Ichikawa <masami256@gmail.com> Subject: [PATCH for test-1.y] Add show() to display argv Date: Sat, 11 Dec 2021 20:37:24 +0900 Message-Id: <20211211113723.79728-1-masami256@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y OK. Log says: Server: smtp.gmail.com MAIL FROM:<masami256@gmail.com> RCPT TO:<masami256+test@gmail.com> RCPT TO:<masami256@gmail.com> From: Masami Ichikawa <masami256@gmail.com> To: masami256+test@gmail.com Cc: Masami Ichikawa <masami256@gmail.com> Subject: [PATCH for test-1.y] Add show() to display argv Date: Sat, 11 Dec 2021 20:37:24 +0900 Message-Id: <20211211113723.79728-1-masami256@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Result: 250
届いたメールを確認するとこのようになっていて、Fromの行が先頭に追加され、ここはオリジナルのAuthorが設定されているのがわかります。
ここまでの手順をstable kernelの場合も行うことになります。
メーリングリストにpatchを送る
git-format-patchでpatchが作れたらあとはメールを送るだけです。もし、バックポート対象のpatchがバックポートしたいブランチに当てるのに失敗していた場合はloreの該当メールにgit-send-emailでpatchを送る方法が書かれています。こんな感じで。なので指示の通りにメールを送りましょう。そうでない場合はmainlineにpatchを送るときと同様に必要な宛先を調べてto、ccをセットしましょう。
まとめ
この記事ではstable kernelにpatchをバックポートする流れを紹介してみました。どんなpatchをバックポートするかですが、自分は CIP Kernel Team: Helping CIP Sustain Industrial Grade Systemsのkernel teamの作業の一環として脆弱性の修正をバックポートする感じでやってます。