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

gh: Upgrade to 2.62.0 to address HIGH CVE-2024-52308 #11152

Open
wants to merge 3 commits into
base: fasttrack/3.0
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
From 82441ca6f9736bc542e699c8cbf46f80542ed618 Mon Sep 17 00:00:00 2001
From: Vince Perri <[email protected]>
Date: Tue, 19 Nov 2024 23:29:08 +0000
Subject: [PATCH] Fix false-negative in TestMigrationWriteErrors when root

---
internal/config/migrate_test.go | 44 ++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/internal/config/migrate_test.go b/internal/config/migrate_test.go
index 783f605..7557149 100644
--- a/internal/config/migrate_test.go
+++ b/internal/config/migrate_test.go
@@ -6,13 +6,20 @@ import (
"io"
"os"
"path/filepath"
+ "syscall"
"testing"
+ "unsafe"

ghmock "github.com/cli/cli/v2/internal/gh/mock"
ghConfig "github.com/cli/go-gh/v2/pkg/config"
"github.com/stretchr/testify/require"
)

+const (
+ FS_IOC_SETFLAGS = 0x40086602
+ FS_IMMUTABLE_FL = 0x00000010
+)
+
func TestMigrationAppliedSuccessfully(t *testing.T) {
readConfig := StubWriteConfig(t)

@@ -215,6 +222,9 @@ func TestMigrationWriteErrors(t *testing.T) {

// Then the error is wrapped and bubbled
require.ErrorContains(t, err, tt.wantErrContains)
+
+ // Make the file writeable again so we can clean up
+ makeFileWriteable(t, filepath.Join(tempDir, tt.unwriteableFile))
})
}
}
@@ -226,7 +236,39 @@ func makeFileUnwriteable(t *testing.T, file string) {
require.NoError(t, err)
f.Close()

- require.NoError(t, os.Chmod(file, 0000))
+ if os.Geteuid() == 0 {
+ fd, err := syscall.Open(file, syscall.O_RDONLY, 0)
+ require.NoError(t, err)
+ defer syscall.Close(fd)
+
+ var flags uint
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags)))
+ require.Zero(t, errno)
+
+ flags |= FS_IMMUTABLE_FL
+ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags)))
+ require.Zero(t, errno)
+ } else {
+ require.NoError(t, os.Chmod(file, 0000))
+ }
+}
+
+func makeFileWriteable(t *testing.T, file string) {
+ t.Helper()
+
+ if os.Geteuid() == 0 {
+ fd, err := syscall.Open(file, syscall.O_RDONLY, 0)
+ require.NoError(t, err)
+ defer syscall.Close(fd)
+
+ var flags uint
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags)))
+ require.Zero(t, errno)
+
+ flags &^= FS_IMMUTABLE_FL
+ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(FS_IOC_SETFLAGS), uintptr(unsafe.Pointer(&flags)))
+ require.Zero(t, errno)
+ }
}

func mockMigration(doFunc func(config *ghConfig.Config) error) *ghmock.MigrationMock {
--
2.34.1

102 changes: 102 additions & 0 deletions SPECS/gh/generate-tarballs.sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe our automation might be expective certain arguments to be passed such as srcTarball, outFolder and pkgVersion, I believe the file might also need to be called generate-tarball.sh. Would you be able to confirm that with Nicolas Guibourge?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mykhailo is right about your comment (see https://github.com/microsoft/azurelinux/blob/3.0/SPECS/coredns/generate_source_tarball.sh for example)
Adding the params and taking them in to account will let auto-upgrade work for that spec

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# This script downloads the source tarball and uses it to generate the
# vendor tarball for the gh package. It also updates the package's
# signatures.json file for both tarballs, although it doesn't account for
# version changes.
#
# Notes:
# - You require GNU tar version 1.28+.
# - The additional options passed to tar enable generation of a tarball
# with the same hash every time regardless of the environment. See:
# https://reproducible-builds.org/docs/archives/
# - For the value of "--mtime" we use the date "2021-04-26 00:00Z" to
# simplify future updates.
set -eux

# get_spec_value extracts the parsed value of a tag from a spec file.
# - spec: The path to the spec file.
# - tag: The tag whose value is extracted.
# The extracted value is returned via stdout.
get_spec_value() {
local spec="$1"
local tag="$2"
local tmp=$(mktemp)
rpmspec -P "$spec" > "$tmp"
grep -E "^${tag}:" "$tmp" | sed -E "s/^$tag:\s*//"
rm "$tmp"
}

# set_signature_value adds or updates the value of a signature in the
# signatures.json file.
# - signatures_json: The path to the signatures.json file.
# - path: The path to the file whose signature is updated.
set_signature_value() {
local signatures_json="$1"
local path="$2"
local name=$(basename "$path")
local sum=$(sha256sum "$path" | cut -d' ' -f1)
signatures_tmp=$(mktemp)
jq --indent 1 ".Signatures.\"$name\" = \"$sum\"" "$signatures_json" > "$signatures_tmp"
mv "$signatures_tmp" "$signatures_json"
}

script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
spec_file=$(ls "$script_dir"/*.spec)
signatures_file=$(ls "$script_dir"/*.signatures.json)

name=$(get_spec_value "$spec_file" "Name")
if [[ -z "$name" ]]; then
echo "Error: Unable to determine the package name from the spec file."
exit 1
fi

version=$(get_spec_value "$spec_file" "Version")
if [[ -z "$version" ]]; then
echo "Error: Unable to determine the package version from the spec file."
exit 1
fi

source_url=$(get_spec_value "$spec_file" "Source0")
if [[ -z "$source_url" ]]; then
echo "Error: Unable to determine the source0 URL from the spec file."
exit 1
fi

source_tarball_name=$(echo "$source_url" | grep -oP '(?<=#/)[^/]+')
if [[ -z "$source_tarball_name" ]]; then
echo "Error: Unable to determine the source0 tarball name from the source URL."
exit 1
fi

vendor_tarball_name=$(get_spec_value "$spec_file" "Source1")
if [[ -z "$vendor_tarball_name" ]]; then
echo "Error: Unable to determine the source1 tarball name from the spec file."
exit 1
fi

source_tarball="$script_dir/$source_tarball_name"
vendor_tarball="$script_dir/$vendor_tarball_name"

# Download the source tarball and calculate its sha256 sum
wget -O "$source_tarball" "$source_url"
set_signature_value "$signatures_file" "$source_tarball"

# Extract the source tarball and generate the vendor tarball and its sha256 sum
source_dir=$(mktemp -d)
trap "rm -rf '$source_dir'" EXIT
tar -C "$source_dir" -xf "$source_tarball"
cd "$source_dir"/*
go mod vendor
tar --sort=name \
--mtime="2021-04-26 00:00Z" \
--owner=0 \
--group=0 \
--numeric-owner \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
-c \
-f "$vendor_tarball" \
vendor
set_signature_value "$signatures_file" "$vendor_tarball"
4 changes: 2 additions & 2 deletions SPECS/gh/gh.signatures.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Signatures": {
"cli-2.43.1.tar.gz": "1ea3f451fb7002c1fb95a7fab21e9ab16591058492628fe264c5878e79ec7c90",
"gh-2.43.1-vendor.tar.gz": "27791885c92900deae2baec254ada1d64d4dfabcfece5886a214f3279eb119f0"
"gh-2.62.0.tar.gz": "8b0d44a7fccd0c768d5ef7c3fbd274851b5752084e47761f146852de6539193e",
"gh-2.62.0-vendor.tar.gz": "2b39f75a9a45aa5e7b8d95e6b5fd7a11a7504e6cd7c92e904027f129abe48599"
}
}
30 changes: 10 additions & 20 deletions SPECS/gh/gh.spec
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
Summary: GitHub official command line tool
Name: gh
Version: 2.43.1
Release: 2%{?dist}
Version: 2.62.0
Release: 1%{?dist}
License: MIT
Vendor: Microsoft Corporation
Distribution: Azure Linux
Group: Applications/Tools
URL: https://github.com/cli/cli
Source0: https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz#/cli-%{version}.tar.gz
# Below is a manually created tarball, no download link.
Source0: https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz

# Below is a manually created tarball, no download link. It is generated by running ./generate-tarballs.sh.
# We're using pre-populated Go modules from this tarball, since network is disabled during build time.
# How to re-build this file:
# 1. wget https://github.com/cli/cli/archive/refs/tags/v%{version}.tar.gz -O cli-%%{version}.tar.gz
# 2. tar -xf cli-%%{version}.tar.gz
# 3. cd cli-%%{version}
# 4. go mod vendor
# 5. tar --sort=name \
# --mtime="2021-04-26 00:00Z" \
# --owner=0 --group=0 --numeric-owner \
# --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
# -cf %%{name}-%%{version}-vendor.tar.gz vendor
#
# NOTES:
# - You require GNU tar version 1.28+.
# - The additional options enable generation of a tarball with the same hash every time regardless of the environment.
# See: https://reproducible-builds.org/docs/archives/
# - For the value of "--mtime" use the date "2021-04-26 00:00Z" to simplify future updates.
Source1: %{name}-%{version}-vendor.tar.gz

Patch0: 0001-Fix-false-negative-in-TestMigrationWriteErrors-when-.patch

BuildRequires: golang < 1.23
BuildRequires: git
Requires: git
Expand Down Expand Up @@ -70,6 +57,9 @@ make test
%{_datadir}/zsh/site-functions/_gh

%changelog
* Mon Nov 18 2024 Vince Perri <[email protected]> - 2.62.0-1
- Update to v2.62.0

* Tue Oct 15 2024 Muhammad Falak <[email protected]> - 2.43.1-2
- Pin golang version to <= 1.22

Expand Down
4 changes: 2 additions & 2 deletions cgmanifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4270,8 +4270,8 @@
"type": "other",
"other": {
"name": "gh",
"version": "2.43.1",
"downloadUrl": "https://github.com/cli/cli/archive/refs/tags/v2.43.1.tar.gz"
"version": "2.62.0",
"downloadUrl": "https://github.com/cli/cli/archive/refs/tags/v2.62.0.tar.gz"
}
}
},
Expand Down
Loading