[MIR] wsl-pro-service

Bug #2052495 reported by Jean-Baptiste Lallement
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
wsl-pro-service (Ubuntu)
Fix Released
Undecided
Unassigned
Focal
New
Undecided
Unassigned
Jammy
New
Undecided
Unassigned
Noble
Fix Released
Undecided
Unassigned

Bug Description

[Availability]
The package wsl-pro-service is already available in Ubuntu universe.
The package wsl-pro-service build for the architectures it is designed to work on.
It currently builds and works for architectures: amd64, arm64, armhf, ppc64el, riscv64, s390x

Link to package https://launchpad.net/ubuntu/+source/wsl-pro-service

[Rationale]
Ubuntu Pro for WSL is a set of applications to manage Ubuntu WSL instances, grant them Pro status, orchestrate instances from Landscape and manage their lifecycle. Wsl-pro-service serves as a bridge between the agent running on Windows and Ubuntu instances. It controls the Pro and Landscape status.
The package wsl-pro-service is required to be in main to seed it by default on WSL images.
The package wsl-pro-service will generally be useful for corporate users.
No package in main or universe currently offers these capabilities.

The target release is all the LTS releases from 20.04 onwards.

[Security]
This is a new software developed and maintained by Canonical. It has no security history.

It is a new software and no CVEs/security issues in this software in the past.

- no `suid` or `sgid` binaries
- The package installs a systemd service called wsl-pro-service
- It installs a service in /usr/libexec/wsl-pro-service, running as root. The service has some systemd confinement.
- Packages does not open privileged ports (ports < 1024)
- Packages does not contain extensions to security-sensitive software
- Communication between wsl-pro-service and the agent running on Windows is done over gRPC.
- Security has been kept in mind and common isolation/risk-mitigation patterns are in place utilizing systemd isolation features.

*This requires a security review.*

[Quality assurance - function/usage]
The package works well right after installation.

[Quality assurance - maintenance]
The Ubuntu Desktop team (~desktop-packages) maintains this package. It doesn’t have any long-term and critical, open bugs:
- https://github.com/canonical/ubuntu-pro-for-windows/issues
- https://bugs.launchpad.net/ubuntu/+source/wsl-pro-service

[Quality assurance - testing]
There is a comprehensive, non-trivial, testsuite. The testsuite includes integration and functional tests.
The testsuite runs at build time. The branch coverage is over 88%:
- https://github.com/canonical/ubuntu-pro-for-windows/actions/workflows/qa.yaml?query=branch%3Amain
- https://app.codecov.io/gh/canonical/ubuntu-pro-for-wsl

The same test suite runs as autopkgtest. It is passing on all supported architectures. Links to test logs:
- https://autopkgtest.ubuntu.com/packages/wsl-pro-service

Upstream CI also includes code sanity checks (golangci-lint, including gosec) and vulnerability scanning (govulneck).

[Quality assurance - packaging]
- There is no debian/watch because wsl-pro-service is a native package.
- debian/control defines a correct Maintainer field:
- Maintainer: Ubuntu Developers <email address hidden>

This package does not yield massive lintian Warnings, Errors
```
   W: wsl-pro-service: no-manual-page [usr/libexec/wsl-pro-service]
```

Full output from `lintian --pedantic`:

```
   W: wsl-pro-service: no-manual-page [usr/libexec/wsl-pro-service]
```

- Lintian overrides are not present.
- This package does not rely on obsolete or about to be demoted packages.
- This package has no python2 or GTK2 dependencies
- The package will be installed by default but does not ask debconf questions.

Packaging and build is easy:
- https://github.com/canonical/ubuntu-pro-for-windows/blob/main/wsl-pro-service/debian/rules

[UI standards]
Application is not end-user facing. However some strings are translatable and used for error messages via standard intltool/gettext or similar build and runtime internationalization system:

The system for internationalization is in place of the project and the mo and po files are generated. It’s a question of taking the time to mark the appropriate strings for translations. It is a background service. Strings are used for logging and are not immediately visible to the user.

[Dependencies]
No further depends or recommends dependencies that are not yet in main.

[Standards compliance]
- This package correctly follows FHS
- This package violates Debian Policy. It vendorizes various Go libraries (in vendor/). We are maintaining them up to date with dependabot in our upstream CI. The Go part is covered by the govulncheck security scanning on the Go version we are depending on and its vendored dependency.

[Maintenance/Owner]
- The owning team will be desktop-packages and I have their acknowledgement for that commitment
- The team desktop-packages is subscribed.
- The team desktop-packages is aware of the implications by a static build and commits to test no-change-rebuilds and to fix any issues found for the lifetime of the release (including ESM).
- The team desktop-packages is aware of the implications of vendored code and (as alerted by the security team) commits to provide updates to the security team for any affected vendored code for the lifetime of the release (including ESM).

[Background information]
- The Package description explains the package well.
- Upstream Name is wsl-pro-service.
- Link to upstream project https://github.com/canonical/ubuntu-pro-for-windows

Tags: sec-3829
Changed in wsl-pro-service (Ubuntu):
assignee: nobody → Lukas Märdian (slyon)
Revision history for this message
Lukas Märdian (slyon) wrote :
Download full text (5.7 KiB)

Review for Source Package: wsl-pro-service

The package is only available on Noble so far, so this review only applies to the Noble version. But I've created bug targets for Focal+ LTS releases as requested, to track future MIR process on the backports.

[Summary]
Wsl-pro-service serves as a bridge between the WSL agent running on Windows
and Ubuntu instances. It controls the Pro and Landscape status. The MIR was
very nicely prepared and the package is in an overall good shapre, but

MIR team ACK (with some recommended TODOs)

This does need a security review

List of specific binary packages to be promoted to main: wsl-pro-service
Specific binary packages built, but NOT to be promoted to main: <None>

Notes:
#0 This needs security review, due to statically built vendored dependencies,
   parsing JSON & gRPC data over a network socket and running a daemon as root.
#1 It depends on centralized "Ubuntu Pro" online accounts
#2 The upstream release process is a bit intransparent (no releases tagged
   on github) and it only saw 2 uploads into Ubuntu so far, so does not have
   a long track record.

Required TODOs:
- None

Recommended TODOs:
#3 Please investigate those lintian errors:
- E: wsl-pro-service source: missing-notice-file-for-apache-license [vendor/google.golang.org/grpc/
- E: wsl-pro-service source: missing-notice-file-for-apache-license [vendor/gopkg.in/yaml.v3/NOTICE]
#4 Please investigate this build-time warning:
- dpkg-gencontrol: warning: Built-Using field of package wsl-pro-service: substitution variable ${misc:Built-Using} used, but is not defined

[Rationale, Duplication and Ownership]
There is no other package in main providing the same functionality.
A team is committed to own long term maintenance of this package. (~desktop-packages)
The rationale given in the report seems valid and useful for Ubuntu (WSL)

[Dependencies]
OK:
- no other Dependencies to MIR due to this
  - SRCPKG checked with `check-mir`
  - all dependencies can be found in `seeded-in-ubuntu` (already in main)
  - none of the (potentially auto-generated) dependencies (Depends
    and Recommends) that are present after build are not in main
- no -dev/-debug/-doc packages that need exclusion
- No dependencies in main that are only superficially tested requiring
  more tests now.

Problems: None

[Embedded sources and static linking]
OK:
- Go Package that follows the Debian Go packaging guidelines
- vendoring is used, but the reasoning is sufficiently explained
- golang: static builds are used, the team confirmed their commitment
  to the additional responsibilities implied by static builds.
- not a rust package, no extra constraints to consider in that regard
- Includes vendored code, the package has documented how to refresh this
  code at: https://github.com/canonical/ubuntu-pro-for-wsl/blob/main/wsl-pro-service/debian/update-internal-dependencies

Problems:
- embedded source present
- static linking
- does have Built-Using entries

[Security]
OK:
- history of CVEs does not look concerning (but it's a very recent package)
- does not use webkit1,2
- does not use lib*v8 directly
- does not process arbitrary web content
- does not integrate arbitrary javascript...

Read more...

Changed in wsl-pro-service (Ubuntu Noble):
assignee: Lukas Märdian (slyon) → Ubuntu Security Team (ubuntu-security)
status: New → Confirmed
Mark Esler (eslerm)
tags: added: sec-3829
Revision history for this message
George-Andrei Iosif (iosifache) wrote :

Hi,

As multiple security concerns appeared when performing the security review of
this package, I had a discussion with Jean and Didier from the owning team. We
concluded that reporting these issues before offering the final MIR report
would be best. This is because no user is affected (as the package is still in
beta), and transparency will catalyse the fixes.

The concerns found are as follows:

1. Insecure gRPC communication: Because
[`insecure.NewCredentials()`](https://<email address hidden>/
credentials/insecure) is used in `internal/controlstream/session.go`, the
created gRPC connections are unencrypted and unauthenticated. A malicious
unprivileged user could make the agent connect the host to a rogue Landscape
server, leading to command execution. As discussed with Didier, encryption
seems unfeasible due to Windows Defender. A mitigation here will involve
authentication (possibly with certificates), ensuring that the communication of
the Ubuntu agent will occur only with the trusted Windows service.
2. Information leak in the temporary Landscape configuration file:
`/etc/landscape/client.conf.new` is a temporary file created by the Ubuntu
service in `internal/system/landscape.go` to store the Landscape configuration.
This file can also store sensitive information such as the account-wide
registration key, `registration_key`. This could lead to auto-registration of
any computer on the Landscape server. As a mitigation, the permission model
could be adjusted so that only the Landscape client can read it, not any user.
3. Command execution inside the Windows host: In `internal/system/system.go`,
all mounts are iterated and checked for communication with the 9P protocol
(which is standard for the second version of WSL). These drives are checked
with `s.findCmdExe()` to contain the `cmd.exe` executable. [As USB drives can
be made visible inside the WSL
instance](https://learn.microsoft.com/en-us/windows/wsl/connect-usb), it may be
possible for a rogue `cmd.exe` executable file from a USB drive to be executed.
As discussed with Jean and Didier, this assumption should be manually validated.
4. Crash when using IPv6 domain servers: When detecting the address of the
Windows host, the agent checks if the NAT mode is used. If so, then the
`/etc/resolv.conf` file is parsed in search of `nameserver` entries. If the
entry is an IPv6 entry, the address will be concatenated with the port using
the `Sprintf` function. The result of this concatenation is ambiguous because
it's not using the `[<ip>]:<port>` IPv6 notation, further connections may
crash. Please see [this](https://github.com/golang/go/issues/28308) proposed
Golang vet check.

Let me know if there is anything I can assist with in the meantime.

Many thanks!

Revision history for this message
George-Andrei Iosif (iosifache) wrote :

The fourth item's crash has already been patched in a GitHub PR
(https://github.com/canonical/ubuntu-pro-for-wsl/pull/622).

Revision history for this message
George-Andrei Iosif (iosifache) wrote :

Other patches were published in the meantime:
- For the second item above, in the `347e747` commit;
- Checking for a negative port number, in the `a6784f5` commit; and
- Avoiding logging configuration items, in the `518a85` commit.

Revision history for this message
George-Andrei Iosif (iosifache) wrote (last edit ):
Download full text (9.3 KiB)

I reviewed `wsl-pro-service` `0.1.1` as checked into Noble. This shouldn't be
considered a full audit but rather a quick gauge of maintainability. For the
sake of completeness, this review will also mention findings reported in
previous GitHub issues and Launchpad comments.

Ubuntu Pro for WSL (abbreviated UP4W) is a set of applications to manage Ubuntu
WSL instances, grant them Pro status, orchestrate instances from Landscape and
manage their lifecycle. It is mostly used in corporate environments.

A user can perform with the UP4W codebase the following steps:
1. Install the "Ubuntu Pro for WSL" from the Microsoft Store
2. Using the minimalist UI or the Windows Registry to attach an Ubuntu Pro token
3. Registering the WSL instances in Ubuntu Pro and Landscape
4. Verifying the status of the Ubuntu Pro token by using the `pro` client
inside the WSL instance, the Landscape client, or the Windows UP4W GUI.

Useful resources to understand the bigger picture are [the landing
page](https://ubuntu.com/desktop/wsl),
[repository](https://github.com/canonical/ubuntu-pro-for-wsl), [public
documentation](https://canonical-ubuntu-pro-for-wsl.readthedocs-hosted.com/en/la
test/#), and Canonical-specific specifications (WS0{25,27,28,31}).

The Windows agent can be installed on Windows via [the Microsoft
Store](https://apps.microsoft.com/detail/9pdxgncfsczv?rtc=1&hl=fr-ch&gl=CH). It
achieves the Windows-specific tasks of the UP4W infrastructure (such as getting
the subscription status from the Microsoft Store and setting the registries'
values), but will not be covered in this review. [Its
implementation](https://github.com/canonical/ubuntu-pro-for-wsl/tree/main/window
s-agent) can also be found on GitHub.

`wsl-pro-service` is a component of the UP4W Windows and Ubuntu infrastructure
owned by the Desktop team. It is meant to be a bridge between the `ubuntu-wsl`
API (interfacing the Windows host with the Ubuntu WSL instance). It is
implemented with a `systemd` service and a minimalistic CLI tool for Bash
completion and version retrieval.

The upstream codebase is in [the `wsl-pro-service` folder of the aforementioned
repository](https://github.com/canonical/ubuntu-pro-for-wsl/tree/main/wsl-pro-se
rvice).

- CVE History
 - As this is new software (still in testing), there is no CVE assigned to it.
- Build-Depends
 - The build process uses only the Debian toolchain, `debhelper` extensions for
Go and `apport` crash reporting, and the Go toolchain.
- Other dependencies
 - The relevant Debian dependencies used when operating the service are:
  - `ubuntu-advantage-tools`, which is required for its Ubuntu Pro CLI client;
and
  - An optional `landscape-client`.
 - The package vendors Go dependencies, which violate the Debian policy.
  - These are updated by the upstream using a GHA called
`update-workspace-dependencies`, which is integrated into the
`auto-updates.yaml` workflow.
  - In addition, the repository has GitHub's Dependabot set.
- pre/post inst/rm scripts
 - The scripts are standard, as generated by `dh_installsystemd`.
- init scripts
 - N/A
- systemd units
 - There is a `systemd` unit called `wsl-pro-service` that runs
`/usr/libexec...

Read more...

Changed in wsl-pro-service (Ubuntu Noble):
assignee: Ubuntu Security Team (ubuntu-security) → nobody
status: Confirmed → In Progress
Revision history for this message
Carlos Nihelton (cnihelton) wrote :
Download full text (3.9 KiB)

Specifically adressing @iosifache concern

> 3. Command execution inside the Windows host:

With USB/IP the WSL instance gets low level access to a USB device as if it was actually attached to the USB bus. I won't go into the details of how to get that done, but it suffices to say that:
1. It requires installation of components on both sides: WSL instance and Windows host
2. The daemon on the host side must be started with elevated permissions
3. Most importantly to this security concern: mounting such device won't result in a 9p filesystem, thus the device would be skipped in the search for cmd.exe

It's possible to mount a USB device as a drvfs 9p mount point, which could fool the current implementation of the `findCmdExe()` function. It requires:
1. The USB device partition to be attached to a WSL instance must be mounted in the Windows host (which requires it to be formatted in one of the filesystems that OS supports)
2. The attacker must be able to launch a command as root inside the WSL instance to mount that partition containing a rogue `cmd.exe` binary (easily done if they already have access to the host, not so easy if they only have access to the WSL instance as a Linux unpriviliged user account)

Yet, by the order which the mount points are processed, the USB device will always be mounted after the hard drive partitions, no matter which drive letters assigned to the partitions on the Windows side. So **the only way** the USB device partition would be picked up is in case the user has disabled automount drives via `/etc/wsl.conf`, as there would be no other candidate mount point to look into, resulting in the rogue binary being executed by wsl-pro-service as root inside the WSL instance. That means the rogue binary could do anything inside the WSL instance, **and anything the Windows user can do** on the Windows host (being root inside is the same as being the Windows user outside of the WSL instance).

While that sounds dangerous, remember that the attacker already had user level permissions to start that attack, so we are just back at where the attack started.

Here's a demonstration of such exploit:

- Assume I have a malicious USB stick formatted as exFAT mounted on Windows as "A:\" and containing a ransomware at path "A:\Windows\System32\cmd.exe";

```powershell
Get-PSDrive -PsProvider 'FileSystem'

Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
A 16.82 12.22 FileSystem A:\
C 362.05 33.18 FileSystem C:\
D 47.43 35.08 FileSystem D:\
```

- Somehow I managed to run the following command on the Windows host:

```powershell
wsl -u root -d Ubuntu bash -ec 'mkdir -p /mnt/a && mount -t drvfs "A:\\" /mnt/a'
```

- My mountpoints inside the Ubuntu WSL instance will look like:

```bash
 mount | grep drvfs
C:\ on /mnt/c type 9p (rw,noatime,dirsync,aname=drvfs;path=C:\;uid=1001;gid=1002;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=5,wfd=5)
D:\ on /mnt/d type 9p (rw,noatime,dirsync,aname=drvfs;path=D:\;uid=1001;gid=1002;symlinkroot=/mnt/,mmap,access=client,msize=65536,tran...

Read more...

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

The last security request (having per user certificate to secure the gRPC communication so that they can’t be hijacked cross-users) is now addressed with 0.1.4 with many other enhancements fixing some recommended TODOs.

I’m proceeding thus with the promotion.

Changed in wsl-pro-service (Ubuntu Noble):
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.