dotnet / dotnet/dotnet-docker

In Azure Linux, installing packages does not automatically upgrade package dependencies

Open
#5,940 3 comments 0 reactions 1 assignee Claimed by @lbussell View on GitHub
area-dockerfiles
Dominant language
Dockerfile
Stars
4.9k
Forks
2k
Avg merge
1d 14h
Merged PRs (30d)
26

Description

### Describe the Bug

This situation is very similar to https://github.com/dotnet/dotnet-docker/issues/4776.

TDNF ("tiny" version of DNF), the package manager in CBL Mariner 2.0 and Azure Linux 3.0, has some incompatibilities with the way we aim to update packages in our Dockerfiles.

Assume that we have package `$a` which is already installed in the base image, and package `$b` which depends on package `$a`.

1. Running `tdnf install -y $a` upgrades package `$a` to the latest version, even when it's already installed (this is good)
1. If package `$b` is not installed, and we run `tdnf install -y $b`, package `$a` is not upgraded to the latest version.
2. If package `$b` is already installed, and there is no update for package `$b`, and we run `tdnf install -y $b`, then package `$a` is still not upgraded to the latest version.
3. I don't have an example for what happens if package `$b` has an update.

### Steps to Reproduce

This situation is happening between `git` and `expat` today. `git` does not have an update available, but `expat` does. I'm using this `aspnet` image to simulate what happens in our `sdk` Dockerfile.

```pwsh
$image = "mcr.microsoft.com/dotnet/aspnet:8.0-cbl-mariner2.0@sha256:f333342acc31b8bb78c5dc4931417685fe1f5e805b4d71ee32c227671c8ac35d"
```

First, check for package upgrades (current version of `expat` is `2.6.2-2.cm2`):

```pwsh
docker run --rm $image /bin/sh -c 'tdnf check-update'

Loaded plugin: tdnfrepogpgcheck
Refreshing metadata for: 'CBL-Mariner Official Microsoft 2.0 x86_64'
Refreshing metadata for: 'CBL-Mariner Official Extras 2.0 x86_64'
Refreshing metadata for: 'CBL-Mariner Official Base 2.0 x86_64'
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base
```

Scenario 1:

```
PS C:\s\dotnet-docker> docker run --rm $image /bin/sh -c 'printf "\nUpdates available:\n"; tdnf check-update -q; printf "\nInstalling expat...\n"; tdnf install -yq expat; printf "\nUpdates available:\n"; tdnf check-update -q'

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base

Installing expat...

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base
```

Scenario 2:

```
docker run --rm $image /bin/sh -c 'printf "\nUpdates available:\n"; tdnf check-update -q; printf "\nInstalling git...\n"; tdnf install -yq git; printf "\nExpat history:\n"; tdnf list history expat; printf "\nWhat requires expat:\n"; rpm -q --whatrequires expat; printf "\nUpdates available:\n"; tdnf check-update -q'

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base

Installing git...
using empty dict to provide pw_dict
switching pw_dict to cracklib-dicts
ownership of '/var/lib/sshd' retained as root:sys

Expat history:
Loaded plugin: tdnfrepogpgcheck
expat.x86_64 2.6.2-2.cm2 @System
expat.x86_64 2.4.8-1.cm2 mariner-official-base
expat.x86_64 2.4.8-2.cm2 mariner-official-base
expat.x86_64 2.5.0-1.cm2 mariner-official-base
expat.x86_64 2.6.2-1.cm2 mariner-official-base
expat.x86_64 2.6.2-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base

What requires expat:
core-packages-container-2.0-8.cm2.x86_64
apr-util-1.6.3-1.cm2.x86_64
python3-libs-3.9.19-5.cm2.x86_64
git-2.39.4-1.cm2.x86_64

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base
```

Scenario 3:

To simulate what happens when git is already installed I'm using the exact same command as scenario 2, but with the SDK image instead since it has git installed.

```pwsh
`$image = "mcr.microsoft.com/dotnet/sdk:8.0-cbl-mariner2.0@sha256:5ccee344ce708fadab98dd7b561a15495cc3a9ac7aa51d3b03efe45e24cabd80"`

docker run --rm $image /bin/sh -c 'printf "\nUpdates available:\n"; tdnf check-update -q; printf "\nInstalling git...\n"; tdnf install -yq git; printf "\nExpat history:\n"; tdnf list history expat; printf "\nWhat requires expat:\n"; rpm -q --whatrequires expat; printf "\nUpdates available:\n"; tdnf check-update -q'

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base
python3.x86_64 3.9.19-5.cm2 mariner-official-base
python3-libs.x86_64 3.9.19-5.cm2 mariner-official-base

Installing git...
Package git is already installed.
Nothing to do.

Expat history:
Loaded plugin: tdnfrepogpgcheck
expat.x86_64 2.6.2-2.cm2 @System
expat.x86_64 2.4.8-1.cm2 mariner-official-base
expat.x86_64 2.4.8-2.cm2 mariner-official-base
expat.x86_64 2.5.0-1.cm2 mariner-official-base
expat.x86_64 2.6.2-1.cm2 mariner-official-base
expat.x86_64 2.6.2-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base

What requires expat:
core-packages-container-2.0-8.cm2.x86_64
apr-util-1.6.3-1.cm2.x86_64
python3-libs-3.9.19-4.cm2.x86_64
git-2.39.4-1.cm2.x86_64

Updates available:
curl.x86_64 8.8.0-2.cm2 mariner-official-base
curl-libs.x86_64 8.8.0-2.cm2 mariner-official-base
expat.x86_64 2.6.3-1.cm2 mariner-official-base
expat-libs.x86_64 2.6.3-1.cm2 mariner-official-base
krb5.x86_64 1.21.3-2.cm2 mariner-official-base
krb5.x86_64 1.19.4-3.cm2 mariner-official-base
python3.x86_64 3.9.19-5.cm2 mariner-official-base
python3-libs.x86_64 3.9.19-5.cm2 mariner-official-base
```

### What does this mean

This means that when an indirect dependency of .NET or any of the tools in a .NET image has a vulnerability, simply re-building the image won't resolve that vulnerability. In this case, `git` is the tool and `expat` is its dependency.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.