From dac136f87b9d5fdda9b5c33dfa0f94dc8c9880c7 Mon Sep 17 00:00:00 2001
From: Tom Thorogood <me+google@tomthorogood.co.uk>
Date: Sat, 13 Mar 2021 00:27:30 +1030
Subject: [PATCH] archive/zip: fix character device handling in
 fileModeToUnixMode

The switch case for fs.ModeDevice can only be reached for block devices
while character devices match fs.ModeDevice | fs.ModeCharDevice. This
would cause character devices to wrongly be reported as regular files.

This bug has existed since the switch was first introduced in CL 5624048.

Change-Id: Icdbedb015e5376b385b3115d2e4574daa052f796
Reviewed-on: https://go-review.googlesource.com/c/go/+/300891
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
---
 src/archive/zip/struct.go      |  8 +++-----
 src/archive/zip/writer_test.go | 12 ++++++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/archive/zip/struct.go b/src/archive/zip/struct.go
index 4dd29f35fa6..3dc0c50122a 100644
--- a/src/archive/zip/struct.go
+++ b/src/archive/zip/struct.go
@@ -341,11 +341,9 @@ func fileModeToUnixMode(mode fs.FileMode) uint32 {
 	case fs.ModeSocket:
 		m = s_IFSOCK
 	case fs.ModeDevice:
-		if mode&fs.ModeCharDevice != 0 {
-			m = s_IFCHR
-		} else {
-			m = s_IFBLK
-		}
+		m = s_IFBLK
+	case fs.ModeDevice | fs.ModeCharDevice:
+		m = s_IFCHR
 	}
 	if mode&fs.ModeSetuid != 0 {
 		m |= s_ISUID
diff --git a/src/archive/zip/writer_test.go b/src/archive/zip/writer_test.go
index 5985144e5c2..3fa8bef0553 100644
--- a/src/archive/zip/writer_test.go
+++ b/src/archive/zip/writer_test.go
@@ -57,6 +57,18 @@ var writeTests = []WriteTest{
 		Method: Deflate,
 		Mode:   0755 | fs.ModeSymlink,
 	},
+	{
+		Name:   "device",
+		Data:   []byte("device file"),
+		Method: Deflate,
+		Mode:   0755 | fs.ModeDevice,
+	},
+	{
+		Name:   "chardevice",
+		Data:   []byte("char device file"),
+		Method: Deflate,
+		Mode:   0755 | fs.ModeDevice | fs.ModeCharDevice,
+	},
 }
 
 func TestWriter(t *testing.T) {
-- 
GitLab