Skip to content

Commit 8675503

Browse files
committed
Update filesystem to chmod the data dir and enforce gid limits
Signed-off-by: joshvanl <[email protected]>
1 parent 240f9aa commit 8675503

File tree

2 files changed

+74
-23
lines changed

2 files changed

+74
-23
lines changed

storage/filesystem.go

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ type Filesystem struct {
5959
// files, gid ownership of the volume's data directory will be changed to
6060
// the value. Attribute value must be a valid int64 value.
6161
// If FixedFSGroup is defined, this field has no effect.
62-
FSGroupVolumeAttributeKey *string
62+
FSGroupVolumeAttributeKey string
6363
}
6464

6565
// Ensure the Filesystem implementation is fully featured
@@ -194,7 +194,7 @@ func (f *Filesystem) RegisterMetadata(meta metadata.Metadata) (bool, error) {
194194
// to a custom gid.
195195
func (f *Filesystem) WriteFiles(meta metadata.Metadata, files map[string][]byte) error {
196196
// Data directory should be read, write and execute only to the fs user; read and executable to group
197-
if err := os.MkdirAll(f.dataPathForVolumeID(meta.VolumeID), 0750); err != nil {
197+
if err := os.MkdirAll(f.dataPathForVolumeID(meta.VolumeID), 0550); err != nil {
198198
return err
199199
}
200200

@@ -215,8 +215,28 @@ func (f *Filesystem) WriteFiles(meta metadata.Metadata, files map[string][]byte)
215215
return err
216216
}
217217

218-
payload := makePayload(files, fsGroup)
219-
return writer.Write(payload)
218+
payload := makePayload(files)
219+
if err := writer.Write(payload); err != nil {
220+
return err
221+
}
222+
223+
// If a fsGroup is defined, Chown all files within the data directory.
224+
if fsGroup != nil {
225+
dirName := f.dataPathForVolumeID(meta.VolumeID)
226+
entries, err := os.ReadDir(dirName)
227+
if err != nil {
228+
return fmt.Errorf("failed to list files in data directory: %w", err)
229+
}
230+
231+
for _, entry := range entries {
232+
// Set the uid to -1 which means don't change ownership in Go.
233+
if err := os.Chown(filepath.Join(dirName, entry.Name()), -1, int(*fsGroup)); err != nil {
234+
return err
235+
}
236+
}
237+
}
238+
239+
return nil
220240
}
221241

222242
// ReadFile reads the named file within the volume's data directory.
@@ -252,13 +272,12 @@ func (f *Filesystem) tempfsPath() string {
252272
return filepath.Join(f.baseDir, "inmemfs")
253273
}
254274

255-
func makePayload(in map[string][]byte, fsGroup *int64) map[string]util.FileProjection {
275+
func makePayload(in map[string][]byte) map[string]util.FileProjection {
256276
out := make(map[string]util.FileProjection, len(in))
257277
for name, data := range in {
258278
out[name] = util.FileProjection{
259-
Data: data,
260-
FsGroup: fsGroup,
261-
Mode: readOnlyUserAndGroupFileMode,
279+
Data: data,
280+
Mode: readOnlyUserAndGroupFileMode,
262281
}
263282
}
264283
return out
@@ -274,19 +293,27 @@ func (f *Filesystem) fsGroupForMetadata(meta metadata.Metadata) (*int64, error)
274293
}
275294

276295
// If the FSGroupVolumeAttributeKey is not defined, no ownership can change.
277-
if f.FSGroupVolumeAttributeKey == nil {
296+
if len(f.FSGroupVolumeAttributeKey) == 0 {
278297
return nil, nil
279298
}
280299

281-
fsGroupStr, ok := meta.VolumeContext[*f.FSGroupVolumeAttributeKey]
300+
fsGroupStr, ok := meta.VolumeContext[f.FSGroupVolumeAttributeKey]
282301
if !ok {
283302
// If the attribute has not been set, return no ownership change.
284303
return nil, nil
285304
}
286305

287306
fsGroup, err := strconv.ParseInt(fsGroupStr, 10, 64)
288307
if err != nil {
289-
return nil, fmt.Errorf("failed to parse %q, value must be a valid integer: %w", *f.FSGroupVolumeAttributeKey, err)
308+
return nil, fmt.Errorf("failed to parse %q, value must be a valid integer: %w", f.FSGroupVolumeAttributeKey, err)
309+
}
310+
311+
// fsGroup has to be between 1 and 4294967295 inclusive. 4294967295 is the
312+
// largest gid number on most modern operating systems. If the actual maximum
313+
// is smaller on the running machine, then we will simply error later during
314+
// the Chmod.
315+
if fsGroup <= 0 || fsGroup > 4294967295 {
316+
return nil, fmt.Errorf("%q: gid value must be greater than 0 and less than 4294967295: %d", f.FSGroupVolumeAttributeKey, fsGroup)
290317
}
291318

292319
return &fsGroup, nil

storage/filesystem_test.go

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,51 +122,75 @@ func Test_fsGroupForMetadata(t *testing.T) {
122122
intPtr := func(i int64) *int64 {
123123
return &i
124124
}
125-
strPtr := func(s string) *string {
126-
return &s
127-
}
128125

129126
tests := map[string]struct {
130127
fixedFSGroup *int64
131-
fsGroupVolumeAttributeKey *string
128+
fsGroupVolumeAttributeKey string
132129
volumeContext map[string]string
133130

134131
expGID *int64
135132
expErr bool
136133
}{
137-
"FixedFSGroup=nil FSGroupVolumeAttributeKey=nil, should return nil gid": {
134+
"FixedFSGroup=nil FSGroupVolumeAttributeKey='', should return nil gid": {
138135
fixedFSGroup: nil,
139-
fsGroupVolumeAttributeKey: nil,
136+
fsGroupVolumeAttributeKey: "",
140137
volumeContext: map[string]string{},
141138
expGID: nil,
142139
expErr: false,
143140
},
144-
"FixedFSGroup=10 FSGroupVolumeAttributeKey=nil, should return 10": {
141+
"FixedFSGroup=10 FSGroupVolumeAttributeKey='', should return 10": {
145142
fixedFSGroup: intPtr(10),
146-
fsGroupVolumeAttributeKey: nil,
143+
fsGroupVolumeAttributeKey: "",
147144
volumeContext: map[string]string{},
148145
expGID: intPtr(10),
149146
expErr: false,
150147
},
151148
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined but not present in context, should return nil": {
152149
fixedFSGroup: nil,
153-
fsGroupVolumeAttributeKey: strPtr("fs-gid"),
150+
fsGroupVolumeAttributeKey: "fs-gid",
154151
volumeContext: map[string]string{},
155152
expGID: nil,
156153
expErr: false,
157154
},
158155
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined and present in context, should return 20": {
159156
fixedFSGroup: nil,
160-
fsGroupVolumeAttributeKey: strPtr("fs-gid"),
157+
fsGroupVolumeAttributeKey: "fs-gid",
161158
volumeContext: map[string]string{
162159
"fs-gid": "20",
163160
},
164161
expGID: intPtr(20),
165162
expErr: false,
166163
},
164+
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined and present in context but value of 0, should error": {
165+
fixedFSGroup: nil,
166+
fsGroupVolumeAttributeKey: "fs-gid",
167+
volumeContext: map[string]string{
168+
"fs-gid": "0",
169+
},
170+
expGID: nil,
171+
expErr: true,
172+
},
173+
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined and present in context but value of -1, should error": {
174+
fixedFSGroup: nil,
175+
fsGroupVolumeAttributeKey: "fs-gid",
176+
volumeContext: map[string]string{
177+
"fs-gid": "-1",
178+
},
179+
expGID: nil,
180+
expErr: true,
181+
},
182+
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined and present in context but value greater than the max gid, should error": {
183+
fixedFSGroup: nil,
184+
fsGroupVolumeAttributeKey: "fs-gid",
185+
volumeContext: map[string]string{
186+
"fs-gid": "4294967296",
187+
},
188+
expGID: nil,
189+
expErr: true,
190+
},
167191
"FixedFSGroup=nil FSGroupVolumeAttributeKey=defined and present in context but with bad value, should return error": {
168192
fixedFSGroup: nil,
169-
fsGroupVolumeAttributeKey: strPtr("fs-gid"),
193+
fsGroupVolumeAttributeKey: "fs-gid",
170194
volumeContext: map[string]string{
171195
"fs-gid": "bad-value",
172196
},
@@ -175,7 +199,7 @@ func Test_fsGroupForMetadata(t *testing.T) {
175199
},
176200
"FixedFSGroup=10 FSGroupVolumeAttributeKey=defined and present in context, should return superseding FixedFSGroup (10)": {
177201
fixedFSGroup: intPtr(10),
178-
fsGroupVolumeAttributeKey: strPtr("fs-gid"),
202+
fsGroupVolumeAttributeKey: "fs-gid",
179203
volumeContext: map[string]string{
180204
"fs-gid": "20",
181205
},

0 commit comments

Comments
 (0)