Skip to content

Commit

Permalink
fix(destination): avoid panic on missing managed fields timestamp (#1…
Browse files Browse the repository at this point in the history
…3378)

We received a report of a panic:

    runtime error: invalid memory address or nil pointer dereference

    panic({0x1edb860?, 0x37a6050?}
        /usr/local/go/src/runtime/panic.go:785 +0x132

    github.com/linkerd/linkerd2/controller/api/destination/watcher.latestUpdated({0xc0006b2d80?, 0xc00051a540?, 0xc0008fa008?})
        /linkerd-build/vendor/github.com/linkerd/linkerd2/controller/api/destination/watcher/endpoints_watcher.go:1612 +0x125

    github.com/linkerd/linkerd2/controller/api/destination/watcher.(*OpaquePortsWatcher).updateService(0xc0007d5480, {0x21fd160?, 0xc000d71688?}, {0x21fd160, 0xc000d71688})
        /linkerd-build/vendor/github.com/linkerd/linkerd2/controller/api/destination/watcher/opaque_ports_watcher.go:141 +0x68

The `latestUpdated` function does not properly handle the case where a atime is
omitted from a `ManagedFieldsEntry`.

    type ManagedFieldsEntry struct {
        // Time is the timestamp of when the ManagedFields entry was added. The
        // timestamp will also be updated if a field is added, the manager
        // changes any of the owned fields value or removes a field. The
        // timestamp does not update when a field is removed from the entry
        // because another manager took it over.
        // +optional
        Time *Time `json:"time,omitempty" protobuf:"bytes,4,opt,name=time"`

This change adds a check to avoid the nil dereference.
  • Loading branch information
olix0r authored Nov 22, 2024
1 parent abfdd69 commit 3c91fc6
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions controller/api/destination/watcher/endpoints_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,9 @@ func SetToServerProtocolExternalWorkload(k8sAPI *k8s.API, address *Address) erro
func latestUpdated(managedFields []metav1.ManagedFieldsEntry) time.Time {
var latest time.Time
for _, field := range managedFields {
if field.Time == nil {
continue
}
if field.Operation == metav1.ManagedFieldsOperationUpdate {
if latest.IsZero() || field.Time.After(latest) {
latest = field.Time.Time
Expand Down

0 comments on commit 3c91fc6

Please sign in to comment.