{"thread":{"id":"37280","subject":"[PATCH] archive: honor tar.umask even for pax headers","startedAt":"2014-08-03T03:02:03Z","lastAt":"2014-08-03T03:02:03Z","messageCount":1,"participants":["brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"247189","messageId":"1407034923-120683-1-git-send-email-sandals@crustytoothpaste.net","threadId":"37280","inReplyTo":null,"subject":"[PATCH] archive: honor tar.umask even for pax headers","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-08-03T03:02:03Z","receivedAt":"2014-08-03T03:02:03Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"git archive's tar format uses extended pax headers to encode metadata\ninto the archive.  Most tar implementations correctly treat these as\nmetadata, but some that do not understand the pax format extract these\nas files instead.  Apply the tar.umask setting to these entries to\nprevent tampering by other users.\n\nSigned-off-by: brian m. carlson <sandals@crustytoothpaste.net>\n---\nTechnically, this is a security issue.  However, the files created are\nnot very useful[0] and the only implementations I found that write these\nfiles are GNU cpio, Debian/MirBSD/OpenBSD pax, and 7zip, none of which\nare commonly used to handle tar archives on Unix.  The latter two also\nhonor the user's umask by default, making this even less problematic.\nGiven the unlikely situation, I feel treating this as a regular bug is\nfine.\n\nnode tar, FreeBSD tar, GNU tar, and Schily tar all handle pax headers\ncorrectly.\n\n[0] Okay, yes, you can exhaust someone else's quota.\n\n archive-tar.c                   | 4 ++--\n t/t5004-archive-corner-cases.sh | 5 +++++\n 2 files changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 719b629..603650f 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -192,7 +192,7 @@ static int write_extended_header(struct archiver_args *args,\n \tunsigned int mode;\n \tmemset(&header, 0, sizeof(header));\n \t*header.typeflag = TYPEFLAG_EXT_HEADER;\n-\tmode = 0100666;\n+\tmode = 0100666 & ~tar_umask;\n \tsprintf(header.name, \"%s.paxheader\", sha1_to_hex(sha1));\n \tprepare_header(args, &header, mode, size);\n \twrite_blocked(&header, sizeof(header));\n@@ -300,7 +300,7 @@ static int write_global_extended_header(struct archiver_args *args)\n \tstrbuf_append_ext_header(&ext_header, \"comment\", sha1_to_hex(sha1), 40);\n \tmemset(&header, 0, sizeof(header));\n \t*header.typeflag = TYPEFLAG_GLOBAL_HEADER;\n-\tmode = 0100666;\n+\tmode = 0100666 & ~tar_umask;\n \tstrcpy(header.name, \"pax_global_header\");\n \tprepare_header(args, &header, mode, ext_header.len);\n \twrite_blocked(&header, sizeof(header));\ndiff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh\nindex 305bcac..83d20c4 100755\n--- a/t/t5004-archive-corner-cases.sh\n+++ b/t/t5004-archive-corner-cases.sh\n@@ -113,4 +113,9 @@ test_expect_success 'archive empty subtree by direct pathspec' '\n \tcheck_dir extract sub\n '\n \n+test_expect_success 'archive applies umask even for pax headers' '\n+\tgit archive --format=tar HEAD >archive.tar &&\n+\t! grep 0666 archive.tar\n+'\n+\n test_done\n-- \n2.0.1\n"}]}