public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ansible-collection-ansible-posix] epel9: Mitigates CVE-2026-11837 (rhbz#2487432)
@ 2026-07-08  1:19 Maxwell G
  0 siblings, 0 replies; only message in thread
From: Maxwell G @ 2026-07-08  1:19 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/ansible-collection-ansible-posix
Branch : epel9
Commit : 25437b607d13e3fbe62cbbe48b6400f34469ae27
Author : Maxwell G <maxwell@gtmx.me>
Date   : 2026-07-07T20:11:02-05:00
Stats  : +227/-0 in 2 file(s)
URL    : https://src.fedoraproject.org/rpms/ansible-collection-ansible-posix/c/25437b607d13e3fbe62cbbe48b6400f34469ae27?branch=epel9

Log:
Mitigates CVE-2026-11837 (rhbz#2487432)

---
diff --git a/0001-Fixes-the-symlink-handling-issue-in-the-authorized_k.patch b/0001-Fixes-the-symlink-handling-issue-in-the-authorized_k.patch
new file mode 100644
index 0000000..f8ba577
--- /dev/null
+++ b/0001-Fixes-the-symlink-handling-issue-in-the-authorized_k.patch
@@ -0,0 +1,223 @@
+From 8f680842f0ab00217657849df03e71629cf94157 Mon Sep 17 00:00:00 2001
+From: Hideki Saito <saito@fgrep.org>
+Date: Tue, 30 Jun 2026 08:45:30 +0900
+Subject: [PATCH] Fixes the symlink handling issue in the authorized_key module
+ (#760)
+
+- Addresses CVE-2026-11837
+- Fixes #759
+
+Signed-off-by: Hideki Saito <saito@fgrep.org>
+(cherry picked from commit 18f2f69c53ffe8014a3047ac8c523ae6671be63e)
+---
+ changelogs/fragments/759_cve_2026_11837.yml   |  2 +
+ plugins/modules/authorized_key.py             | 29 ++++++++++----
+ .../authorized_key/tasks/check_symlink.yml    | 22 +++++++++++
+ .../tasks/check_symlink_cleanup.yml           | 12 ++++++
+ .../tasks/check_symlink_setup.yml             | 38 +++++++++++++++++++
+ .../targets/authorized_key/tasks/main.yml     | 11 +++++-
+ 6 files changed, 105 insertions(+), 9 deletions(-)
+ create mode 100644 changelogs/fragments/759_cve_2026_11837.yml
+ create mode 100644 tests/integration/targets/authorized_key/tasks/check_symlink.yml
+ create mode 100644 tests/integration/targets/authorized_key/tasks/check_symlink_cleanup.yml
+ create mode 100644 tests/integration/targets/authorized_key/tasks/check_symlink_setup.yml
+
+diff --git a/changelogs/fragments/759_cve_2026_11837.yml b/changelogs/fragments/759_cve_2026_11837.yml
+new file mode 100644
+index 0000000..8ae96f1
+--- /dev/null
++++ b/changelogs/fragments/759_cve_2026_11837.yml
+@@ -0,0 +1,2 @@
++security_fixes:
++  - authorized_key - fix local privilege escalation via symlink-following when running as root (https://github.com/ansible-collections/ansible.posix/issues/759).
+diff --git a/plugins/modules/authorized_key.py b/plugins/modules/authorized_key.py
+index 9fbc610..0b62d84 100644
+--- a/plugins/modules/authorized_key.py
++++ b/plugins/modules/authorized_key.py
+@@ -290,6 +290,17 @@ class keydict(dict):
+         return [item[1] for item in self.items()]
+ 
+ 
++def _safe_open_write(module, path, follow):
++    flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
++    if not follow and hasattr(os, 'O_NOFOLLOW'):
++        flags |= os.O_NOFOLLOW
++    try:
++        fd = os.open(path, flags, int('0600', 8))
++    except OSError as e:
++        module.fail_json(msg="File open failed %s : %s" % (path, to_native(e)))
++    return fd
++
++
+ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False):
+     """
+     Calculate name of authorized keys file, optionally creating the
+@@ -342,7 +353,7 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
+                 module.fail_json(msg="Failed to create directory %s : %s" % (sshdir, to_native(e)))
+             if module.selinux_enabled():
+                 module.set_default_selinux_context(sshdir, False)
+-        os.chown(sshdir, uid, gid)
++        os.chown(sshdir, uid, gid, follow_symlinks=follow)
+         os.chmod(sshdir, int('0700', 8))
+ 
+     if not os.path.exists(keysfile):
+@@ -350,16 +361,13 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
+         if not os.path.exists(basedir):
+             os.makedirs(basedir)
+ 
+-        f = None
+-        try:
+-            f = open(keysfile, "w")  # touches file so we can set ownership and perms
+-        finally:
+-            f.close()
++        fd = _safe_open_write(module, keysfile, follow)
++        os.close(fd)
+         if module.selinux_enabled():
+             module.set_default_selinux_context(keysfile, False)
+ 
+     try:
+-        os.chown(keysfile, uid, gid)
++        os.chown(keysfile, uid, gid, follow_symlinks=follow)
+         os.chmod(keysfile, int('0600', 8))
+     except OSError:
+         pass
+@@ -575,7 +583,7 @@ def enforce_state(module, params):
+ 
+     # check current state -- just get the filename, don't create file
+     do_write = False
+-    params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
++    params["keyfile"] = keyfile(module, user, do_write, path, manage_dir, follow)
+     existing_content = readfile(params["keyfile"])
+     existing_keys = parsekeys(module, existing_content)
+ 
+@@ -664,6 +672,11 @@ def enforce_state(module, params):
+ 
+         if not module.check_mode:
+             writefile(module, filename, new_content)
++            user_entry = pwd.getpwnam(user)
++            uid = user_entry.pw_uid
++            gid = user_entry.pw_gid
++            os.chown(filename, uid, gid, follow_symlinks=follow)
++            os.chmod(filename, int('0600', 8))
+         params['changed'] = True
+ 
+     return params
+diff --git a/tests/integration/targets/authorized_key/tasks/check_symlink.yml b/tests/integration/targets/authorized_key/tasks/check_symlink.yml
+new file mode 100644
+index 0000000..7572fbd
+--- /dev/null
++++ b/tests/integration/targets/authorized_key/tasks/check_symlink.yml
+@@ -0,0 +1,22 @@
++---
++#
++# Check: keysfile is symlink and follow=false
++#
++- name: Try to add key with keysfile as symlink
++  ansible.posix.authorized_key:
++    user: testuser
++    key: "{{ rsa_key_basic }}"
++    state: present
++    manage_dir: false
++    follow: false
++
++- name: Assert target file ownership unchanged
++  ansible.builtin.stat:
++    path: /tmp/symlink_test_target/target_file
++  register: target_file_stat
++
++- name: Verify target file is still owned by root
++  ansible.builtin.assert:
++    that:
++      - target_file_stat.stat.uid == 0
++...
+diff --git a/tests/integration/targets/authorized_key/tasks/check_symlink_cleanup.yml b/tests/integration/targets/authorized_key/tasks/check_symlink_cleanup.yml
+new file mode 100644
+index 0000000..37b64d4
+--- /dev/null
++++ b/tests/integration/targets/authorized_key/tasks/check_symlink_cleanup.yml
+@@ -0,0 +1,12 @@
++---
++- name: Remove testuser
++  ansible.builtin.user:
++    name: testuser
++    state: absent
++    remove: true
++
++- name: Remove symlink target directory
++  ansible.builtin.file:
++    path: /tmp/symlink_test_target
++    state: absent
++...
+diff --git a/tests/integration/targets/authorized_key/tasks/check_symlink_setup.yml b/tests/integration/targets/authorized_key/tasks/check_symlink_setup.yml
+new file mode 100644
+index 0000000..3c21ea4
+--- /dev/null
++++ b/tests/integration/targets/authorized_key/tasks/check_symlink_setup.yml
+@@ -0,0 +1,38 @@
++---
++- name: Create testuser for symlink tests
++  ansible.builtin.user:
++    name: testuser
++    create_home: true
++  register: testuser_result
++
++- name: Create symlink target directory
++  ansible.builtin.file:
++    path: /tmp/symlink_test_target
++    state: directory
++    owner: root
++    mode: '0700'
++
++- name: Create a target file owned by root
++  ansible.builtin.copy:
++    dest: /tmp/symlink_test_target/target_file
++    content: "sensitive data"
++    owner: root
++    mode: '0600'
++
++- name: Remove .ssh directory if exists
++  ansible.builtin.file:
++    path: "{{ testuser_result.home }}/.ssh"
++    state: absent
++
++- name: Create .ssh directory
++  ansible.builtin.file:
++    path: "{{ testuser_result.home }}/.ssh"
++    state: directory
++    mode: '0700'
++
++- name: Create symlink from authorized_keys to target file
++  ansible.builtin.file:
++    src: /tmp/symlink_test_target/target_file
++    dest: "{{ testuser_result.home }}/.ssh/authorized_keys"
++    state: link
++...
+diff --git a/tests/integration/targets/authorized_key/tasks/main.yml b/tests/integration/targets/authorized_key/tasks/main.yml
+index 6a22838..a4257e1 100644
+--- a/tests/integration/targets/authorized_key/tasks/main.yml
++++ b/tests/integration/targets/authorized_key/tasks/main.yml
+@@ -17,7 +17,7 @@
+ # You should have received a copy of the GNU General Public License
+ # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
+ 
+-- name: Setup testing environment
++- name: Setup for testing environment
+   ansible.builtin.import_tasks: setup_steps.yml
+ 
+ - name: Test for multiple keys handling
+@@ -31,3 +31,12 @@
+ 
+ - name: Test for the management of comments with key
+   ansible.builtin.import_tasks: comments.yml
++
++- name: CVE-2026-11837 Setup for symlink tests
++  ansible.builtin.import_tasks: check_symlink_setup.yml
++
++- name: CVE-2026-11837 Test for symlink tests
++  ansible.builtin.import_tasks: check_symlink.yml
++
++- name: CVE-2026-11837 Cleanup symlink test
++  ansible.builtin.import_tasks: check_symlink_cleanup.yml
+-- 
+2.54.0
+

diff --git a/ansible-collection-ansible-posix.spec b/ansible-collection-ansible-posix.spec
index b33dbbc..fd95605 100644
--- a/ansible-collection-ansible-posix.spec
+++ b/ansible-collection-ansible-posix.spec
@@ -17,6 +17,9 @@ Source:         https://github.com/ansible-collections/ansible.posix/archive/%{v
 # collection. This is a downstream only patch. Upstreams include these files
 # for reasons that are irrelevant to Fedora.
 Patch0:         0001-Exclude-unnecessary-files-from-built-collection.patch
+# Mitigates CVE-2026-11837
+# Backport of github.com/ansible-collections/ansible.posix/commit/18f2f69c53ffe8014a3047ac8c523ae6671be63e
+Patch1:         0001-Fixes-the-symlink-handling-issue-in-the-authorized_k.patch
 BuildRequires:  ansible-packaging
 %if %{with tests}
 BuildRequires:  ansible-packaging-tests
@@ -56,6 +59,7 @@ find -type f ! -executable -name '*.py' -print -exec sed -i -e '1{\@^#!.*@d}' '{
 %changelog
 * Wed Jul 08 2026 Maxwell G <maxwell@gtmx.me> - 1.6.2-1
 - Update to 1.6.2.
+- Mitigates CVE-2026-11837 (rhbz#2487432)
 
 * Fri May 19 2023 Maxwell G <maxwell@gtmx.me> - 1.5.4-1
 - Update to 1.5.4. Fixes rhbz#2207695.

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-08  1:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-08  1:19 [rpms/ansible-collection-ansible-posix] epel9: Mitigates CVE-2026-11837 (rhbz#2487432) Maxwell G

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox