Skip to content

Commit

Permalink
Fix ReadAt with offset==EOF (#51)
Browse files Browse the repository at this point in the history
* Fix ReadAt with offset==EOF

Fix a problem when a `ReadAt` requests a read at the offset that in plaintext corresponds exactly to a block starting at the EOF.

We forward to where the block *would* be, thereby we never read the previous block header, and therefore do not get the "final" marker set

We fix by reading (and skipping) the previous block if a request starts exactly at a block boundary to pick up the "final" marker.

We calculate `t`, to be the number of full blocks to skip and `k` to be the number of bytes to skip before the response starts:

```
	t := offset / int64(maxPayloadSize)
	k := offset % int64(maxPayloadSize)
```

We add the following if we start at a block boundary after the first block:

```
	if offset > 0 && k == 0 {
		k = maxPayloadSize
		t--
	}
```

This will read the previous block to read the "final" flag and skip its content.
  • Loading branch information
klauspost committed Mar 1, 2023
1 parent a9cfd77 commit 8e38d8c
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 122 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: "Code scanning - action"

on:
push:
pull_request:
schedule:
- cron: '0 19 * * 0'

jobs:
CodeQL-Build:

# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
35 changes: 22 additions & 13 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,57 @@ on:

jobs:
build:
name: Build Go ${{ matrix.go-version }}
name: Lint ${{ matrix.go-version }}
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [1.15.x, 1.16.x]
go-version: [1.20.x]
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v1
uses: actions/checkout@v2

- name: Build
env:
GO111MODULE: on
- name: go vet
run: go vet ./...

- name: go fmt
run: diff <(gofmt -d .) <(printf "")

- name: golangci-lint
run: |
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.33.0
$(go env GOPATH)/bin/golangci-lint run --config ./.golangci.yml
go vet ./...
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.51.2
$(go env GOPATH)/bin/golangci-lint run --config ./.golangci.yml
test:
name: Testing Go ${{ matrix.go-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
go-version: [1.16.x]
go-version: [1.18.x, 1.19.x, 1.20.x]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
uses: actions/setup-go@v1
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v1
uses: actions/checkout@v2

- name: Test on ${{ matrix.os }}
env:
GO111MODULE: on
run: |
go test ./...
- name: Test on race ${{ matrix.os }}
env:
GO111MODULE: on
run: |
go test -race ./...
4 changes: 1 addition & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ linters:
- goimports
- misspell
- govet
- golint
- ineffassign
- gosimple
- deadcode
- unused
- structcheck
- prealloc
- unconvert
- revive

issues:
exclude-use-default: false
Expand Down
8 changes: 4 additions & 4 deletions cmd/ncrypt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
//
// Usage: ncrypt [FLAGS] [ARGUMENTS...]
//
// -cipher string Specify cipher - default: platform depended
// -d Decrypt
// -list List supported algorithms
// -p string Specify the password - default: prompt for password
// -cipher string Specify cipher - default: platform depended
// -d Decrypt
// -list List supported algorithms
// -p string Specify the password - default: prompt for password
//
// Examples:
//
Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module github.com/minio/sio

require (
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f
golang.org/x/sys v0.0.0-20190412213103-97732733099d
golang.org/x/crypto v0.6.0
golang.org/x/sys v0.5.0
)

go 1.13
require golang.org/x/term v0.5.0 // indirect

go 1.18
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
3 changes: 1 addition & 2 deletions reader-v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package sio
import (
"errors"
"io"
"io/ioutil"
)

type encReaderV10 struct {
Expand Down Expand Up @@ -237,7 +236,7 @@ func (r *decReaderAtV10) ReadAt(p []byte, offset int64) (n int, err error) {
}
decReader.SeqNum = uint32(t)
if k := offset % int64(maxPayloadSize); k > 0 {
if _, err := io.CopyN(ioutil.Discard, &decReader, k); err != nil {
if _, err := io.CopyN(io.Discard, &decReader, k); err != nil {
return 0, err
}
}
Expand Down
10 changes: 7 additions & 3 deletions reader-v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package sio
import (
"errors"
"io"
"io/ioutil"
"sync"
)

Expand Down Expand Up @@ -291,6 +290,11 @@ func (r *decReaderAtV20) ReadAt(p []byte, offset int64) (n int, err error) {
if t+1 > (1<<32)-1 {
return 0, errUnexpectedSize
}
k := offset % int64(maxPayloadSize)
if offset > 0 && k == 0 {
k = maxPayloadSize
t--
}

decReader := decReaderV20{
authDecV20: r.ad,
Expand All @@ -300,8 +304,8 @@ func (r *decReaderAtV20) ReadAt(p []byte, offset int64) (n int, err error) {
}
defer decReader.recycle()
decReader.SeqNum = uint32(t)
if k := offset % int64(maxPayloadSize); k > 0 {
if _, err := io.CopyN(ioutil.Discard, &decReader, k); err != nil {
if k > 0 {
if _, err := io.CopyN(io.Discard, &decReader, k); err != nil {
return 0, err
}
}
Expand Down

0 comments on commit 8e38d8c

Please sign in to comment.