From e7c5eab712e0f70ecbc6d225d4766e0fe0f3f884 Mon Sep 17 00:00:00 2001
From: Carlos Goncalves <cgoncalves@redhat.com>
Date: Mon, 13 May 2019 13:37:12 +0200
Subject: [PATCH] [CVE-2019-3895] Set image owner id

This patch ensures [controller_worker]/amp_image_owner_id is set. This
configuration option restricts Glance image selection to a specific
owner ID. This is a recommended security setting.

Closes-Bug: #1830607

Change-Id: I14b69b9fb5234cf79a4d7e85de5f16df5ef7f7a2
---
 playbooks/octavia-files.yaml                  |  1 +
 .../tasks/octavia.yml                         | 12 +++++
 .../octavia-undercloud/tasks/image_mgmt.yml   | 45 ++++++++++++++++---
 ...a-set-image-owner-id-adb197d5daae54f1.yaml | 10 +++++
 4 files changed, 62 insertions(+), 6 deletions(-)
 create mode 100644 releasenotes/notes/octavia-set-image-owner-id-adb197d5daae54f1.yaml

diff --git a/playbooks/octavia-files.yaml b/playbooks/octavia-files.yaml
index 2b464edf3..9b744c2b8 100644
--- a/playbooks/octavia-files.yaml
+++ b/playbooks/octavia-files.yaml
@@ -69,6 +69,7 @@
     ca_private_key_path: "{{ ca_private_key_path }}"
     ca_passphrase: "{{ ca_passphrase }}"
     client_cert_path: "{{ client_cert_path }}"
+    auth_project_name: "{{ auth_project_name }}"
   environment:
     OS_USERNAME: "{{ os_username }}"
     OS_USER_DOMAIN_NAME: "Default"
diff --git a/playbooks/roles/octavia-controller-config/tasks/octavia.yml b/playbooks/roles/octavia-controller-config/tasks/octavia.yml
index 632d08443..dd510654c 100644
--- a/playbooks/roles/octavia-controller-config/tasks/octavia.yml
+++ b/playbooks/roles/octavia-controller-config/tasks/octavia.yml
@@ -41,3 +41,15 @@
       src: "manager-post-deploy.conf.j2"
       selevel: s0
       setype: svirt_sandbox_file_t
+  - name: gather facts about the service project
+    shell: |
+      openstack project show "{{ auth_project_name }}" -c id -f value
+    register: project_id_result
+  - name: setting [controller_worker]/amp_image_owner_id
+    become: true
+    become_user: root
+    ini_file:
+      path: "{{ octavia_confd_prefix }}/etc/octavia/conf.d/common/post-deploy.conf"
+      section: controller_worker
+      option: amp_image_owner_id
+      value: "{{ project_id_result.stdout }}"
diff --git a/playbooks/roles/octavia-undercloud/tasks/image_mgmt.yml b/playbooks/roles/octavia-undercloud/tasks/image_mgmt.yml
index 769940618..a30d56992 100644
--- a/playbooks/roles/octavia-undercloud/tasks/image_mgmt.yml
+++ b/playbooks/roles/octavia-undercloud/tasks/image_mgmt.yml
@@ -19,13 +19,38 @@
       amphora_image: "{{ (image_file_result.stat.path | basename | splitext)[0] }}"
     when: amphora_image is not defined and image_file_result.stat.exists and not symlnk_check.stat.islnk
 
-  - name: check there an image in glance already
+  - name: gather facts about the service project
     shell: |
-      openstack image show {{ amphora_image }} -c checksum -f value
+      openstack project show "{{ auth_project_name }}" -c id -f value
+    register: project_id_result
+
+  - name: check there's an image in glance already
+    shell: |
+      openstack image list --property owner={{ project_id_result.stdout }} --private --name {{ amphora_image }} -c ID -f value
+    environment:
+      OS_USERNAME: "{{ auth_username }}"
+      OS_PASSWORD: "{{ auth_password }}"
+      OS_PROJECT_NAME: "{{ auth_project_name }}"
+    register: glance_id_result
+    ignore_errors: true
+
+  - name: set image id fact
+    set_fact:
+      image_id: "{{ glance_id_result.stdout }}"
+    when: glance_id_result.rc == 0
+
+  - name: get checksum if there's an image in glance already
+    shell: |
+      openstack image show {{ glance_id_result.stdout }} -c checksum -f value
+    environment:
+      OS_USERNAME: "{{ auth_username }}"
+      OS_PASSWORD: "{{ auth_password }}"
+      OS_PROJECT_NAME: "{{ auth_project_name }}"
+    when: image_id is defined
     register: glance_results
     ignore_errors: true
 
-  - name: get md5 from glance if image already exists there
+  - name: set current_md5 fact from glance if image already exists there
     set_fact:
       current_md5: "{{ glance_results.stdout }}"
     when: glance_results.rc == 0
@@ -37,10 +62,14 @@
 
   - name: move existing image if the names match and the md5s are not the same
     shell: |
-      ts=`openstack image show {{ amphora_image }} -f value -c created_at`
+      ts=`openstack image show {{ image_id }} -f value -c created_at`
       ts=${ts//:/}
       ts=${ts//-/}
-      openstack image set {{ amphora_image }} --name "{{ amphora_image }}_$ts"
+      openstack image set {{ image_id }} --name "{{ amphora_image }}_$ts"
+    environment:
+      OS_USERNAME: "{{ auth_username }}"
+      OS_PASSWORD: "{{ auth_password }}"
+      OS_PROJECT_NAME: "{{ auth_project_name }}"
     when: replace_image is defined and replace_image
 
   - name: decide whether to upload new image
@@ -73,7 +102,11 @@
         --container-format bare --tag {{ amp_image_tag }} \
         --file {{ raw_filename|default(image_filename) }} \
         --property hw_architecture={{ amp_hw_arch }} \
-        {{ amphora_image }}
+        --private {{ amphora_image }}
+    environment:
+      OS_USERNAME: "{{ auth_username }}"
+      OS_PASSWORD: "{{ auth_password }}"
+      OS_PROJECT_NAME: "{{ auth_project_name }}"
     register: image_result
     changed_when: "image_result.stdout != ''"
     when: image_file_result.stat.exists and upload_image is defined
diff --git a/releasenotes/notes/octavia-set-image-owner-id-adb197d5daae54f1.yaml b/releasenotes/notes/octavia-set-image-owner-id-adb197d5daae54f1.yaml
new file mode 100644
index 000000000..f8c82419d
--- /dev/null
+++ b/releasenotes/notes/octavia-set-image-owner-id-adb197d5daae54f1.yaml
@@ -0,0 +1,10 @@
+---
+security:
+  - |
+    Fixed a vulnerability where an attacker may cause new Octavia amphorae to
+    run based on any arbitrary image (CVE-2019-3895).
+fixes:
+  - |
+    Ensure [controller_worker]/amp_image_owner_id is set. This configuration
+    option restricts Glance image selection to a specific owner ID. This is a
+    recommended security setting.