diff options
| -rw-r--r-- | meta/recipes-extended/pam/libpam/CVE-2024-10963.patch | 265 | ||||
| -rw-r--r-- | meta/recipes-extended/pam/libpam_1.5.3.bb | 1 |
2 files changed, 266 insertions, 0 deletions
diff --git a/meta/recipes-extended/pam/libpam/CVE-2024-10963.patch b/meta/recipes-extended/pam/libpam/CVE-2024-10963.patch new file mode 100644 index 0000000000..b79831f0e5 --- /dev/null +++ b/meta/recipes-extended/pam/libpam/CVE-2024-10963.patch | |||
| @@ -0,0 +1,265 @@ | |||
| 1 | From f9ccee5c4c6cb0d4197b08ebeb36c1dceffe82e8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Thorsten Kukuk <kukuk@suse.com> | ||
| 3 | Date: Thu, 14 Nov 2024 10:27:28 +0100 | ||
| 4 | Subject: [PATCH] pam_access: rework resolving of tokens as hostname | ||
| 5 | |||
| 6 | * modules/pam_access/pam_access.c: separate resolving of IP addresses | ||
| 7 | from hostnames. Don't resolve TTYs or display variables as hostname | ||
| 8 | (#834). | ||
| 9 | Add "nodns" option to disallow resolving of tokens as hostname. | ||
| 10 | * modules/pam_access/pam_access.8.xml: document nodns option | ||
| 11 | * modules/pam_access/access.conf.5.xml: document that hostnames should | ||
| 12 | be written as FQHN. | ||
| 13 | |||
| 14 | Upstream-Status: Backport [https://github.com/linux-pam/linux-pam/commit/940747f88c16e029b69a74e80a2e94f65cb3e628] | ||
| 15 | CVE: CVE-2024-10963 | ||
| 16 | Signed-off-by: Stanislav Vovk <stanislav.vovk@est.tech> | ||
| 17 | --- | ||
| 18 | modules/pam_access/access.conf.5.xml | 4 ++ | ||
| 19 | modules/pam_access/pam_access.8.xml | 46 ++++++++++++------ | ||
| 20 | modules/pam_access/pam_access.c | 72 +++++++++++++++++++++++++++- | ||
| 21 | 3 files changed, 105 insertions(+), 17 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml | ||
| 24 | index ff1cb223..158fc7df 100644 | ||
| 25 | --- a/modules/pam_access/access.conf.5.xml | ||
| 26 | +++ b/modules/pam_access/access.conf.5.xml | ||
| 27 | @@ -220,10 +220,14 @@ | ||
| 28 | the fields they are ignored. However if the list separator is changed with the | ||
| 29 | <emphasis>listsep</emphasis> option, the spaces will become part of the actual | ||
| 30 | item and the line will be most probably ignored. For this reason, it is not | ||
| 31 | recommended to put spaces around the ':' characters. | ||
| 32 | </para> | ||
| 33 | + <para> | ||
| 34 | + Hostnames should be written as Fully-Qualified Host Name (FQHN) to avoid | ||
| 35 | + confusion with device names or PAM service names. | ||
| 36 | + </para> | ||
| 37 | </refsect1> | ||
| 38 | |||
| 39 | <refsect1 xml:id="access.conf-see_also"> | ||
| 40 | <title>SEE ALSO</title> | ||
| 41 | <para> | ||
| 42 | diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml | ||
| 43 | index 010e749e..1182c907 100644 | ||
| 44 | --- a/modules/pam_access/pam_access.8.xml | ||
| 45 | +++ b/modules/pam_access/pam_access.8.xml | ||
| 46 | @@ -20,15 +20,18 @@ | ||
| 47 | <cmdsynopsis xml:id="pam_access-cmdsynopsis" sepchar=" "> | ||
| 48 | <command>pam_access.so</command> | ||
| 49 | <arg choice="opt" rep="norepeat"> | ||
| 50 | debug | ||
| 51 | </arg> | ||
| 52 | + <arg choice="opt" rep="norepeat"> | ||
| 53 | + noaudit | ||
| 54 | + </arg> | ||
| 55 | <arg choice="opt" rep="norepeat"> | ||
| 56 | nodefgroup | ||
| 57 | </arg> | ||
| 58 | <arg choice="opt" rep="norepeat"> | ||
| 59 | - noaudit | ||
| 60 | + nodns | ||
| 61 | </arg> | ||
| 62 | <arg choice="opt" rep="norepeat"> | ||
| 63 | accessfile=<replaceable>file</replaceable> | ||
| 64 | </arg> | ||
| 65 | <arg choice="opt" rep="norepeat"> | ||
| 66 | @@ -127,10 +130,37 @@ | ||
| 67 | Do not report logins from disallowed hosts and ttys to the audit subsystem. | ||
| 68 | </para> | ||
| 69 | </listitem> | ||
| 70 | </varlistentry> | ||
| 71 | |||
| 72 | + <varlistentry> | ||
| 73 | + <term> | ||
| 74 | + nodefgroup | ||
| 75 | + </term> | ||
| 76 | + <listitem> | ||
| 77 | + <para> | ||
| 78 | + User tokens which are not enclosed in parentheses will not be | ||
| 79 | + matched against the group database. The backwards compatible default is | ||
| 80 | + to try the group database match even for tokens not enclosed | ||
| 81 | + in parentheses. | ||
| 82 | + </para> | ||
| 83 | + </listitem> | ||
| 84 | + </varlistentry> | ||
| 85 | + | ||
| 86 | + <varlistentry> | ||
| 87 | + <term> | ||
| 88 | + nodns | ||
| 89 | + </term> | ||
| 90 | + <listitem> | ||
| 91 | + <para> | ||
| 92 | + Do not try to resolve tokens as hostnames, only IPv4 and IPv6 | ||
| 93 | + addresses will be resolved. Which means to allow login from a | ||
| 94 | + remote host, the IP addresses need to be specified in <filename>access.conf</filename>. | ||
| 95 | + </para> | ||
| 96 | + </listitem> | ||
| 97 | + </varlistentry> | ||
| 98 | + | ||
| 99 | <varlistentry> | ||
| 100 | <term> | ||
| 101 | fieldsep=separators | ||
| 102 | </term> | ||
| 103 | <listitem> | ||
| 104 | @@ -168,24 +198,10 @@ | ||
| 105 | "Domain Admins" contain a space. | ||
| 106 | </para> | ||
| 107 | </listitem> | ||
| 108 | </varlistentry> | ||
| 109 | |||
| 110 | - <varlistentry> | ||
| 111 | - <term> | ||
| 112 | - nodefgroup | ||
| 113 | - </term> | ||
| 114 | - <listitem> | ||
| 115 | - <para> | ||
| 116 | - User tokens which are not enclosed in parentheses will not be | ||
| 117 | - matched against the group database. The backwards compatible default is | ||
| 118 | - to try the group database match even for tokens not enclosed | ||
| 119 | - in parentheses. | ||
| 120 | - </para> | ||
| 121 | - </listitem> | ||
| 122 | - </varlistentry> | ||
| 123 | - | ||
| 124 | </variablelist> | ||
| 125 | </refsect1> | ||
| 126 | |||
| 127 | <refsect1 xml:id="pam_access-types"> | ||
| 128 | <title>MODULE TYPES PROVIDED</title> | ||
| 129 | diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c | ||
| 130 | index f70b7e49..d06496c3 100644 | ||
| 131 | --- a/modules/pam_access/pam_access.c | ||
| 132 | +++ b/modules/pam_access/pam_access.c | ||
| 133 | @@ -97,10 +97,11 @@ struct login_info { | ||
| 134 | const char *config_file; | ||
| 135 | const char *hostname; | ||
| 136 | int debug; /* Print debugging messages. */ | ||
| 137 | int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */ | ||
| 138 | int noaudit; /* Do not audit denials */ | ||
| 139 | + int nodns; /* Do not try to resolve tokens as hostnames */ | ||
| 140 | const char *fs; /* field separator */ | ||
| 141 | const char *sep; /* list-element separator */ | ||
| 142 | int from_remote_host; /* If PAM_RHOST was used for from */ | ||
| 143 | struct addrinfo *res; /* Cached DNS resolution of from */ | ||
| 144 | int gai_rv; /* Cached retval of getaddrinfo */ | ||
| 145 | @@ -148,10 +149,12 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo, | ||
| 146 | loginfo->debug = YES; | ||
| 147 | } else if (strcmp (argv[i], "nodefgroup") == 0) { | ||
| 148 | loginfo->only_new_group_syntax = YES; | ||
| 149 | } else if (strcmp (argv[i], "noaudit") == 0) { | ||
| 150 | loginfo->noaudit = YES; | ||
| 151 | + } else if (strcmp (argv[i], "nodns") == 0) { | ||
| 152 | + loginfo->nodns = YES; | ||
| 153 | } else { | ||
| 154 | pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]); | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | @@ -730,11 +733,11 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item) | ||
| 159 | |||
| 160 | if (tok[0] == '.') { /* domain: match last fields */ | ||
| 161 | if ((str_len = strlen(string)) > tok_len | ||
| 162 | && strcasecmp(tok, string + str_len - tok_len) == 0) | ||
| 163 | return YES; | ||
| 164 | - } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */ | ||
| 165 | + } else if (tok[tok_len - 1] == '.') { /* internet network numbers/subnet (end with ".") */ | ||
| 166 | struct addrinfo hint; | ||
| 167 | |||
| 168 | memset (&hint, '\0', sizeof (hint)); | ||
| 169 | hint.ai_flags = AI_CANONNAME; | ||
| 170 | hint.ai_family = AF_INET; | ||
| 171 | @@ -805,10 +808,43 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, | ||
| 172 | } | ||
| 173 | return (NO); | ||
| 174 | } | ||
| 175 | |||
| 176 | |||
| 177 | +static int | ||
| 178 | +is_device (pam_handle_t *pamh, const char *tok) | ||
| 179 | +{ | ||
| 180 | + struct stat st; | ||
| 181 | + const char *dev = "/dev/"; | ||
| 182 | + char *devname; | ||
| 183 | + | ||
| 184 | + devname = malloc (strlen(dev) + strlen (tok) + 1); | ||
| 185 | + if (devname == NULL) { | ||
| 186 | + pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for device name: %m"); | ||
| 187 | + /* | ||
| 188 | + * We should return an error and abort, but pam_access has no good | ||
| 189 | + * error handling. | ||
| 190 | + */ | ||
| 191 | + return NO; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + char *cp = stpcpy (devname, dev); | ||
| 195 | + strcpy (cp, tok); | ||
| 196 | + | ||
| 197 | + if (lstat(devname, &st) != 0) | ||
| 198 | + { | ||
| 199 | + free (devname); | ||
| 200 | + return NO; | ||
| 201 | + } | ||
| 202 | + free (devname); | ||
| 203 | + | ||
| 204 | + if (S_ISCHR(st.st_mode)) | ||
| 205 | + return YES; | ||
| 206 | + | ||
| 207 | + return NO; | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | /* network_netmask_match - match a string against one token | ||
| 211 | * where string is a hostname or ip (v4,v6) address and tok | ||
| 212 | * represents either a hostname, a single ip (v4,v6) address | ||
| 213 | * or a network/netmask | ||
| 214 | */ | ||
| 215 | @@ -866,14 +902,46 @@ network_netmask_match (pam_handle_t *pamh, | ||
| 216 | if (getaddrinfo (tok, NULL, NULL, &ai) != 0) | ||
| 217 | { | ||
| 218 | return NO; | ||
| 219 | } | ||
| 220 | } | ||
| 221 | + else if (isipaddr(tok, NULL, NULL) == YES) | ||
| 222 | + { | ||
| 223 | + if (getaddrinfo (tok, NULL, NULL, &ai) != 0) | ||
| 224 | + { | ||
| 225 | + if (item->debug) | ||
| 226 | + pam_syslog(pamh, LOG_DEBUG, "cannot resolve IP address \"%s\"", tok); | ||
| 227 | + | ||
| 228 | + return NO; | ||
| 229 | + } | ||
| 230 | + netmask_ptr = NULL; | ||
| 231 | + } | ||
| 232 | + else if (item->nodns) | ||
| 233 | + { | ||
| 234 | + /* Only hostnames are left, which we would need to resolve via DNS */ | ||
| 235 | + return NO; | ||
| 236 | + } | ||
| 237 | else | ||
| 238 | { | ||
| 239 | + /* Bail out on X11 Display entries and ttys. */ | ||
| 240 | + if (tok[0] == ':') | ||
| 241 | + { | ||
| 242 | + if (item->debug) | ||
| 243 | + pam_syslog (pamh, LOG_DEBUG, | ||
| 244 | + "network_netmask_match: tok=%s is X11 display", tok); | ||
| 245 | + return NO; | ||
| 246 | + } | ||
| 247 | + if (is_device (pamh, tok)) | ||
| 248 | + { | ||
| 249 | + if (item->debug) | ||
| 250 | + pam_syslog (pamh, LOG_DEBUG, | ||
| 251 | + "network_netmask_match: tok=%s is a TTY", tok); | ||
| 252 | + return NO; | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | /* | ||
| 256 | - * It is either an IP address or a hostname. | ||
| 257 | + * It is most likely a hostname. | ||
| 258 | * Let getaddrinfo sort everything out | ||
| 259 | */ | ||
| 260 | if (getaddrinfo (tok, NULL, NULL, &ai) != 0) | ||
| 261 | { | ||
| 262 | pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok); | ||
| 263 | -- | ||
| 264 | 2.43.5 | ||
| 265 | |||
diff --git a/meta/recipes-extended/pam/libpam_1.5.3.bb b/meta/recipes-extended/pam/libpam_1.5.3.bb index 815085cc82..4c27767ab1 100644 --- a/meta/recipes-extended/pam/libpam_1.5.3.bb +++ b/meta/recipes-extended/pam/libpam_1.5.3.bb | |||
| @@ -34,6 +34,7 @@ SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/Linux-PAM-${PV}.tar.xz \ | |||
| 34 | file://CVE-2025-6020-01.patch \ | 34 | file://CVE-2025-6020-01.patch \ |
| 35 | file://CVE-2025-6020-02.patch \ | 35 | file://CVE-2025-6020-02.patch \ |
| 36 | file://CVE-2025-6020-03.patch \ | 36 | file://CVE-2025-6020-03.patch \ |
| 37 | file://CVE-2024-10963.patch \ | ||
| 37 | " | 38 | " |
| 38 | 39 | ||
| 39 | SRC_URI[sha256sum] = "7ac4b50feee004a9fa88f1dfd2d2fa738a82896763050cd773b3c54b0a818283" | 40 | SRC_URI[sha256sum] = "7ac4b50feee004a9fa88f1dfd2d2fa738a82896763050cd773b3c54b0a818283" |
