Skip to content

Commit

Permalink
merge #135 into openSUSE/libpathrs:main
Browse files Browse the repository at this point in the history
Aleksa Sarai (2):
  go bindings: switch to block comment for license
  go bindings: use links in godocs

LGTMs: cyphar
  • Loading branch information
cyphar committed Dec 9, 2024
2 parents 698a9d2 + 4f5b1ab commit 94ca5f8
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 186 deletions.
32 changes: 17 additions & 15 deletions go-pathrs/doc.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//go:build linux

// libpathrs: safe path resolution on Linux
// Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
// Copyright (C) 2019-2024 SUSE LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Package pathrs provides bindings for libpathrs, a library for safe path
// resolution on Linux.
Expand Down
32 changes: 17 additions & 15 deletions go-pathrs/error_linux.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//go:build linux

// libpathrs: safe path resolution on Linux
// Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
// Copyright (C) 2019-2024 SUSE LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package pathrs

Expand Down
94 changes: 52 additions & 42 deletions go-pathrs/handle_linux.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//go:build linux

// libpathrs: safe path resolution on Linux
// Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
// Copyright (C) 2019-2024 SUSE LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package pathrs

Expand All @@ -23,25 +25,30 @@ import (
"os"
)

// Handle is a handle for a path within a given Root. This handle references an
// already-resolved path which can be used for only one purpose -- to "re-open"
// the handle and get an actual *os.File which can be used for ordinary
// operations.
// Handle is a handle for a path within a given [Root]. This handle references
// an already-resolved path which can be used for only one purpose -- to
// "re-open" the handle and get an actual [os.File] which can be used for
// ordinary operations.
//
// It is critical that perform all relevant operations through this Handle
// (rather than fetching the file descriptor yourself with IntoRaw), because
// the security properties of libpathrs depend on users doing all relevant
// filesystem operations through libpathrs.
// If you wish to open a file without having an intermediate [Handle] object,
// you can try to use [Root.Open] or [Root.OpenFile].
//
// It is critical that perform all relevant operations through this [Handle]
// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]),
// because the security properties of libpathrs depend on users doing all
// relevant filesystem operations through libpathrs.
//
// [os.File]: https://pkg.go.dev/os#File
type Handle struct {
inner *os.File
}

// HandleFromFile creates a new Handle from an existing file handle. The handle
// will be copied by this method, so the original handle should still be freed
// by the caller.
// HandleFromFile creates a new [Handle] from an existing file handle. The
// handle will be copied by this method, so the original handle should still be
// freed by the caller.
//
// This is effectively the inverse operation of Handle.IntoRaw, and is used for
// "deserialising" pathrs root handles.
// This is effectively the inverse operation of [Handle.IntoRaw], and is used
// for "deserialising" pathrs root handles.
func HandleFromFile(file *os.File) (*Handle, error) {
newFile, err := dupFile(file)
if err != nil {
Expand All @@ -50,21 +57,21 @@ func HandleFromFile(file *os.File) (*Handle, error) {
return &Handle{inner: newFile}, nil
}

// Open creates an "upgraded" file handle to the file referenced by the Handle.
// Note that the original Handle is not consumed by this operation, and can be
// opened multiple times.
// Open creates an "upgraded" file handle to the file referenced by the
// [Handle]. Note that the original [Handle] is not consumed by this operation,
// and can be opened multiple times.
//
// The handle returned is only usable for reading, and this is method is
// shorthand for handle.OpenFile(os.O_RDONLY).
// shorthand for [Handle.OpenFile] with os.O_RDONLY.
//
// TODO: Rename these to "Reopen" or something.
func (h *Handle) Open() (*os.File, error) {
return h.OpenFile(os.O_RDONLY)
}

// OpenFile creates an "upgraded" file handle to the file referenced by the
// Handle. Note that the original Handle is not consumed by this operation, and
// can be opened multiple times.
// [Handle]. Note that the original [Handle] is not consumed by this operation,
// and can be opened multiple times.
//
// The provided flags indicate which open(2) flags are used to create the new
// handle.
Expand All @@ -80,14 +87,17 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) {
})
}

// IntoFile unwraps the Handle into its underlying *os.File.
// IntoFile unwraps the [Handle] into its underlying [os.File].
//
// You almost certainly want to use [Handle.OpenFile] to get a non-O_PATH
// version of this [Handle].
//
// You almost certainly want to use OpenFile() to get a non-O_PATH version of
// this Handle.
// This operation returns the internal [os.File] of the [Handle] directly, so
// calling [Handle.Close] will also close any copies of the returned [os.File].
// If you want to get an independent copy, use [Handle.Clone] followed by
// [Handle.IntoFile] on the cloned [Handle].
//
// This operation returns the internal *os.File of the Handle directly, so
// Close()ing the Handle will also close any copies of the returned *os.File.
// If you want to get an independent copy, use Clone().IntoFile().
// [os.File]: https://pkg.go.dev/os#File
func (h *Handle) IntoFile() *os.File {
// TODO: Figure out if we really don't want to make a copy.
// TODO: We almost certainly want to clear r.inner here, but we can't do
Expand All @@ -96,13 +106,13 @@ func (h *Handle) IntoFile() *os.File {
return h.inner
}

// Clone creates a copy of a Handle, such that it has a separate lifetime to
// Clone creates a copy of a [Handle], such that it has a separate lifetime to
// the original (while referring to the same underlying file).
func (h *Handle) Clone() (*Handle, error) {
return HandleFromFile(h.inner)
}

// Close frees all of the resources used by the Handle.
// Close frees all of the resources used by the [Handle].
func (h *Handle) Close() error {
return h.inner.Close()
}
32 changes: 17 additions & 15 deletions go-pathrs/libpathrs_linux.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//go:build linux

// libpathrs: safe path resolution on Linux
// Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
// Copyright (C) 2019-2024 SUSE LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package pathrs

Expand Down
52 changes: 31 additions & 21 deletions go-pathrs/procfs_linux.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
//go:build linux

// libpathrs: safe path resolution on Linux
// Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
// Copyright (C) 2019-2024 SUSE LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2024 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2024 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package pathrs

Expand Down Expand Up @@ -66,7 +68,9 @@ func (b ProcBase) namePrefix() string {
}

// ProcHandleCloser is a callback that needs to be called when you are done
// operating on an *os.File fetched using [ProcThreadSelfOpen].
// operating on an [os.File] fetched using [ProcThreadSelfOpen].
//
// [os.File]: https://pkg.go.dev/os#File
type ProcHandleCloser func()

// TODO: Should we expose procOpen?
Expand Down Expand Up @@ -115,7 +119,7 @@ func ProcRootOpen(path string, flags int) (*os.File, error) {
//
// This method is recommend for getting process information about the current
// process for almost all Go processes *except* for cases where there are
// runtime.LockOSThread threads that have changed some aspect of their state
// [runtime.LockOSThread] threads that have changed some aspect of their state
// (such as through unshare(CLONE_FS) or changing namespaces).
//
// For such non-heterogeneous processes, /proc/self may reference to a task
Expand All @@ -128,6 +132,8 @@ func ProcRootOpen(path string, flags int) (*os.File, error) {
// Unlike [ProcThreadSelfOpen], this method does not involve locking the
// goroutine to the current OS thread and so is simpler to use and
// theoretically has slightly less overhead.
//
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
func ProcSelfOpen(path string, flags int) (*os.File, error) {
file, closer, err := procOpen(ProcBaseSelf, path, flags)
if closer != nil {
Expand All @@ -149,12 +155,16 @@ func ProcSelfOpen(path string, flags int) (*os.File, error) {
//
// Because Go can change the running OS thread of your goroutine without notice
// (and then subsequently kill the old thread), this method will lock the
// current goroutine to the OS thread (with runtime.LockOSThread) and the
// current goroutine to the OS thread (with [runtime.LockOSThread]) and the
// caller is responsible for unlocking the the OS thread with the
// ProcHandleCloser callback once they are done using the returned file. This
// callback MUST be called AFTER you have finished using the returned *os.File.
// This callback is completely separate to (*os.File).Close, so it must be
// called regardless of how you close the handle.
// callback MUST be called AFTER you have finished using the returned
// [os.File]. This callback is completely separate to [os.File.Close], so it
// must be called regardless of how you close the handle.
//
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
// [os.File]: https://pkg.go.dev/os#File
// [os.File.Close]: https://pkg.go.dev/os#File.Close
func ProcThreadSelfOpen(path string, flags int) (*os.File, ProcHandleCloser, error) {
return procOpen(ProcBaseThreadSelf, path, flags)
}
Expand Down
Loading

0 comments on commit 94ca5f8

Please sign in to comment.