diff --git a/core/chaincode/platforms/golang/platform.go b/core/chaincode/platforms/golang/platform.go index 874148ec165..ba816726d1e 100644 --- a/core/chaincode/platforms/golang/platform.go +++ b/core/chaincode/platforms/golang/platform.go @@ -138,7 +138,7 @@ func (goPlatform *Platform) ValidateCodePackage(code []byte) error { // the container itself needs to be the last line of defense and be configured to be // resilient in enforcing constraints. However, we should still do our best to keep as much // garbage out of the system as possible. - re := regexp.MustCompile(`(/)?src/.*`) + re := regexp.MustCompile(`^(/)?(src|META-INF)/.*`) is := bytes.NewReader(code) gr, err := gzip.NewReader(is) if err != nil { diff --git a/core/chaincode/platforms/golang/platform_test.go b/core/chaincode/platforms/golang/platform_test.go index 2fb6f7085ff..945ae288235 100644 --- a/core/chaincode/platforms/golang/platform_test.go +++ b/core/chaincode/platforms/golang/platform_test.go @@ -88,7 +88,11 @@ func TestValidateCDS(t *testing.T) { specs := make([]spec, 0) specs = append(specs, spec{CCName: "NoCode", Path: "path/to/nowhere", File: "/bin/warez", Mode: 0100400, SuccessExpected: false}) specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/src/path/to/somewhere/main.go", Mode: 0100400, SuccessExpected: true}) + specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/bad-src/path/to/somewhere/main.go", Mode: 0100400, SuccessExpected: false}) specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/src/path/to/somewhere/warez", Mode: 0100555, SuccessExpected: false}) + specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/META-INF/path/to/a/meta1", Mode: 0100555, SuccessExpected: false}) + specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/META-Inf/path/to/a/meta2", Mode: 0100400, SuccessExpected: false}) + specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "META-INF/path/to/a/meta3", Mode: 0100400, SuccessExpected: true}) for _, s := range specs { cds, err := generateFakeCDS(s.CCName, s.Path, s.File, s.Mode) diff --git a/core/chaincode/platforms/node/platform.go b/core/chaincode/platforms/node/platform.go index 0840a599da5..a59b24970e9 100644 --- a/core/chaincode/platforms/node/platform.go +++ b/core/chaincode/platforms/node/platform.go @@ -88,7 +88,7 @@ func (nodePlatform *Platform) ValidateCodePackage(code []byte) error { // the container itself needs to be the last line of defense and be configured to be // resilient in enforcing constraints. However, we should still do our best to keep as much // garbage out of the system as possible. - re := regexp.MustCompile(`(/)?src/.*`) + re := regexp.MustCompile(`^(/)?(src|META-INF)/.*`) is := bytes.NewReader(code) gr, err := gzip.NewReader(is) if err != nil { diff --git a/core/chaincode/platforms/node/platform_test.go b/core/chaincode/platforms/node/platform_test.go index 9bf37551f45..b463c20582a 100644 --- a/core/chaincode/platforms/node/platform_test.go +++ b/core/chaincode/platforms/node/platform_test.go @@ -27,6 +27,11 @@ var _ = platforms.Platform(&Platform{}) var platform = &Platform{} +type packageFile struct { + packagePath string + mode int64 +} + func TestValidatePath(t *testing.T) { err := platform.ValidatePath("there/is/no/way/this/path/exists") if err == nil { @@ -52,7 +57,7 @@ func TestValidateCodePackage(t *testing.T) { t.Fatalf("should have returned an error about opening the invalid archive, but got '%v'", err) } - cp, err := makeCodePackage("filename.txt", 0100744) + cp, err := makeCodePackage([]*packageFile{{"filename.txt", 0100744}}) if err != nil { t.Fatal(err) } @@ -64,7 +69,7 @@ func TestValidateCodePackage(t *testing.T) { t.Fatalf("should have returned error about illegal file detected, but got '%s'", err) } - cp, err = makeCodePackage("src/filename.txt", 0100744) + cp, err = makeCodePackage([]*packageFile{{"src/filename.txt", 0100744}}) if err != nil { t.Fatal(err) } @@ -76,7 +81,7 @@ func TestValidateCodePackage(t *testing.T) { t.Fatalf("should have returned error about illegal file mode detected, but got '%s'", err) } - cp, err = makeCodePackage("src/filename.txt", 0100666) + cp, err = makeCodePackage([]*packageFile{{"src/filename.txt", 0100666}}) if err != nil { t.Fatal(err) } @@ -88,7 +93,18 @@ func TestValidateCodePackage(t *testing.T) { t.Fatalf("should have returned error about no package.json found, but got '%s'", err) } - cp, err = makeCodePackage("src/package.json", 0100666) + cp, err = makeCodePackage([]*packageFile{{"src/package.json", 0100666}, {"META-INF/path/to/meta", 0100744}}) + if err != nil { + t.Fatal(err) + } + + err = platform.ValidateCodePackage(cp) + if err == nil { + t.Fatalf("should have failed to validate because file in the archive is executable") + } else if !strings.HasPrefix(err.Error(), "illegal file mode detected for file") { + t.Fatalf("should have returned error about illegal file mode detected, but got '%s'", err) + } + cp, err = makeCodePackage([]*packageFile{{"src/package.json", 0100666}, {"META-INF/path/to/meta", 0100666}}) if err != nil { t.Fatal(err) } @@ -191,23 +207,25 @@ func TestGenerateDockerBuild(t *testing.T) { } } -func makeCodePackage(packagePath string, mode int64) ([]byte, error) { +func makeCodePackage(pfiles []*packageFile) ([]byte, error) { contents := []byte("fake file's content") payload := bytes.NewBuffer(nil) gw := gzip.NewWriter(payload) tw := tar.NewWriter(gw) - if err := tw.WriteHeader(&tar.Header{ - Name: packagePath, - Mode: mode, - Size: int64(len(contents)), - }); err != nil { - return nil, fmt.Errorf("Error write header: %s", err) - } - - if _, err := tw.Write(contents); err != nil { - return nil, fmt.Errorf("Error writing contents: %s", err) + for _, f := range pfiles { + if err := tw.WriteHeader(&tar.Header{ + Name: f.packagePath, + Mode: f.mode, + Size: int64(len(contents)), + }); err != nil { + return nil, fmt.Errorf("Error write header: %s", err) + } + + if _, err := tw.Write(contents); err != nil { + return nil, fmt.Errorf("Error writing contents: %s", err) + } } // Write the tar file out