Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure uid, gid, and mode are valid during parsing #13230

Merged
merged 3 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions doc/rest-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10224,19 +10224,19 @@ paths:
- description: Raw file content
in: body
name: raw_file
- description: File owner UID
- description: Base 10 32-bit integer for the file owner UID
example: 1000
in: header
name: X-LXD-uid
schema:
type: integer
- description: File owner GID
- description: Base 10 32-bit integer for the file owner GID
example: 1000
in: header
name: X-LXD-gid
schema:
type: integer
- description: File mode
- description: Base 10 (no leading `0`) or base 8 (leading `0`) unix permissions bits (other bits are truncated)
example: 420
in: header
name: X-LXD-mode
Expand Down
6 changes: 3 additions & 3 deletions lxd/instance_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,19 +390,19 @@ func instanceFileHead(s *state.State, inst instance.Instance, path string, r *ht
// description: Raw file content
// - in: header
// name: X-LXD-uid
// description: File owner UID
// description: Base 10 32-bit integer for the file owner UID
// schema:
// type: integer
// example: 1000
// - in: header
// name: X-LXD-gid
// description: File owner GID
// description: Base 10 32-bit integer for the file owner GID
// schema:
// type: integer
// example: 1000
// - in: header
// name: X-LXD-mode
// description: File mode
// description: Base 10 (no leading `0`) or base 8 (leading `0`) unix permissions bits (other bits are truncated)
// schema:
// type: integer
// example: 0644
Expand Down
26 changes: 21 additions & 5 deletions shared/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,27 +257,43 @@ func LogPath(path ...string) string {
return filepath.Join(items...)
}

// ParseLXDFileHeaders parses and validates the `X-LXD-*` family of file
// permissions headers.
// - `X-LXD-uid`, `X-LXD-gid`
// Base 10 integer
// - `X-LXD-mode`
// Base 10 integer (no leading `0`) or base 8 integer (leading `0`) for the
// unix permissions bits
// - `X-LXD-type`
// One of `file`, `symlink`, `directory`
// - `X-LXD-write`
// One of `overwrite`, `append`
func ParseLXDFileHeaders(headers http.Header) (uid int64, gid int64, mode int, type_ string, write string) {
uid, err := strconv.ParseInt(headers.Get("X-LXD-uid"), 10, 64)
uid, err := strconv.ParseInt(headers.Get("X-LXD-uid"), 10, 32)
if err != nil {
uid = -1
}

gid, err = strconv.ParseInt(headers.Get("X-LXD-gid"), 10, 64)
gid, err = strconv.ParseInt(headers.Get("X-LXD-gid"), 10, 32)
if err != nil {
gid = -1
}

mode, err = strconv.Atoi(headers.Get("X-LXD-mode"))
mode64, err := strconv.ParseInt(headers.Get("X-LXD-mode"), 10, 0)
if err != nil {
mode = -1
mode64 = -1
} else {
rawMode, err := strconv.ParseInt(headers.Get("X-LXD-mode"), 0, 0)
if err == nil {
mode = int(os.FileMode(rawMode) & os.ModePerm)
mode64 = rawMode
}
}

mode = -1
if mode64 >= 0 {
mode = int(mode64 & int64(os.ModePerm))
}

type_ = headers.Get("X-LXD-type")
/* backwards compat: before "type" was introduced, we could only
* manipulate files
Expand Down
Loading