Skip to content

Commit b50845e

Browse files
committed
Stopped passing non-UTF8 attributes in the metadata map over gRPC, as protobuf does not support this
1 parent 5fe6445 commit b50845e

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

changelog/unreleased/eos-nonutf8.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Bugfix: stop sending non-UTF8 strings over gRPC
2+
3+
EOS supports having non-UTF8 attributes, which get returned in a Stat. This is problematic for us, as we pass these attributes in the ArbitraryMetadata, which gets sent over gRPC. However, the protobuf language specification states:
4+
5+
> A string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot be longer than 2^32.
6+
7+
An example of such an attribute is:
8+
9+
user.$KERNEL.PURGE.SEC.FILEHASH="S��ϫ]���z��#1}��uU�v��8�L0R�9j�j��e?�2K�T<sJ�*�l���Dǭ��_[�>η�...��w�w[��Yg"
10+
11+
We fix this by stripping non-UTF8 metadata entries before sending the ResourceInfo over gRPC
12+
13+
https://github.com/cs3org/reva/pull/5119

internal/grpc/services/gateway/storageprovider.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,7 @@ func (s *svc) stat(ctx context.Context, req *provider.StatRequest) (*provider.St
12181218
}
12191219
rsp, err := c.Stat(ctx, req)
12201220
if err != nil || rsp.Status.Code != rpc.Code_CODE_OK {
1221-
log.Error().Err(err).Any("Status", rsp.Status).Msg("Failed to stat " + resPath)
1221+
log.Error().Err(err).Msg("Failed to stat " + resPath)
12221222
return rsp, err
12231223
}
12241224
return rsp, nil

internal/grpc/services/storageprovider/storageprovider.go

+26-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"sort"
3030
"strconv"
3131
"strings"
32+
"unicode/utf8"
3233

3334
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
3435
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -800,6 +801,7 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
800801
}, nil
801802
}
802803
s.fixPermissions(md)
804+
s.stripNonUtf8Metadata(ctx, md)
803805
res := &provider.StatResponse{
804806
Status: status.NewOK(ctx),
805807
Info: md,
@@ -826,6 +828,28 @@ func (s *service) fixPermissions(md *provider.ResourceInfo) {
826828
}
827829
}
828830

831+
// This method removes any entries in the ArbitraryMetadata map that
832+
// are not valid UTF-8
833+
// This is necessary because protobuf requires strings to only contain valid UTF-8
834+
func (s *service) stripNonUtf8Metadata(ctx context.Context, md *provider.ResourceInfo) {
835+
log := appctx.GetLogger(ctx)
836+
if md.ArbitraryMetadata == nil {
837+
return
838+
}
839+
840+
toDelete := []string{}
841+
for k, v := range md.ArbitraryMetadata.Metadata {
842+
if !utf8.ValidString(v) {
843+
toDelete = append(toDelete, k)
844+
}
845+
}
846+
847+
for _, k := range toDelete {
848+
log.Debug().Str("attribute", k).Msg("Dropping non-UTF8 metadata entry")
849+
delete(md.ArbitraryMetadata.Metadata, k)
850+
}
851+
}
852+
829853
func (s *service) statVirtualView(ctx context.Context, ref *provider.Reference) (*provider.StatResponse, error) {
830854
// The reference in the request encompasses this provider
831855
// So we need to stat root, and update the required path
@@ -945,7 +969,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
945969
case errtypes.PermissionDenied:
946970
st = status.NewPermissionDenied(ctx, err, "permission denied")
947971
default:
948-
log.Error().Str("path", newRef.Path).Err(err).Msg("storageprovider: error listing container")
972+
log.Error().Any("ref", newRef).Err(err).Msg("storageprovider: error listing container")
949973
st = status.NewInternal(ctx, err, "error listing container: "+req.Ref.String())
950974
}
951975
return &provider.ListContainerResponse{
@@ -962,6 +986,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
962986
}, nil
963987
}
964988
s.fixPermissions(md)
989+
s.stripNonUtf8Metadata(ctx, md)
965990
infos = append(infos, md)
966991
}
967992
res := &provider.ListContainerResponse{

pkg/storage/utils/eosfs/eosfs.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st
11211121
// and lightweight accounts don't have a uid
11221122
auth, err := fs.getDaemonAuth(ctx)
11231123
if err != nil {
1124-
return nil, fmt.Errorf("error getting daemon aut")
1124+
return nil, fmt.Errorf("error getting daemon auth")
11251125
}
11261126

11271127
if ref.ResourceId != nil {

0 commit comments

Comments
 (0)