Your message dated Fri, 05 Apr 2024 17:27:47 +0000
with message-id <[email protected]>
and subject line Bug#1068262: Removed package(s) from unstable
has caused the Debian Bug report #1013955,
regarding libapache2-mod-auth-kerb: memory leak plus incorrect handling of 
keytabs
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1013955: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1013955
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: libapache2-mod-auth-kerb
Version: 5.4-2.5
Severity: normal
Tags: patch upstream
X-Debbugs-Cc: [email protected]

Dear Maintainer,

I think there are two problems with the code:

In authenticate_user_gss the keytab path (configured by the Krb5Keytab conf 
directive) is in the process environment using a putenv call.

First, there is an obvious memory leak because the string put into the 
environment is malloc'ed. It is never freed. Moreover, this malloc and putenv 
happens at every request.

Second, not only that putenv is not thread-safe but it may lead to functional 
bugs. Let us assume that we have two different directories, each with its own 
Krb5Keytab conf directive, each pointing to a different keytab file. When two 
requests are handled by two threads in parallel, each will putenv 
KRB5_KTNAME=/path/to/keytab. It is possible that the calls to the GSSAPI/Krb5 
functions of one thread use the value of the environment variable KRB5_KTNAME 
set by the other thread.

I've written a patch to correct these two problems. The patch works in my setup 
but I have to tested it exhaustively. Please have a look.

Thank you and best regards,
Sorin

-- System Information:
Debian Release: bookworm/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.17.0-1-amd64 (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=C, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libapache2-mod-auth-kerb depends on:
ii  apache2-bin [apache2-api-20120211]  2.4.54-1
ii  krb5-config                         2.6+nmu1
ii  libc6                               2.33-7
ii  libcom-err2                         1.46.5-2
ii  libgssapi-krb5-2                    1.19.2-2+b2
ii  libkrb5-3                           1.19.2-2+b2

libapache2-mod-auth-kerb recommends no packages.

libapache2-mod-auth-kerb suggests no packages.

-- no debconf information
Index: mod_auth_kerb-5.4/src/mod_auth_kerb.c
===================================================================
--- mod_auth_kerb-5.4.orig/src/mod_auth_kerb.c
+++ mod_auth_kerb-5.4/src/mod_auth_kerb.c
@@ -228,7 +228,8 @@ static const char *
 cmd_delegationlock(cmd_parms *cmd, void *dconf, const char *a1);
 
 static int
-obtain_server_credentials(request_rec *r, const char *service_name);
+obtain_server_credentials(request_rec *r, const char *service_name,
+                         const char *kt_name);
 
 #ifdef STANDARD20_MODULE_STUFF
 #define command(name, func, var, type, usage)           \
@@ -1245,14 +1246,12 @@ end:
 }
 
 static int
-get_gss_creds(request_rec *r,
-              kerb_auth_config *conf,
-             gss_cred_id_t *server_creds)
+get_server_name(request_rec *r,
+               kerb_auth_config *conf,
+               gss_name_t *server_name)
 {
    gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
-   OM_uint32 major_status, minor_status, minor_status2;
-   gss_name_t server_name = GSS_C_NO_NAME;
-   gss_cred_usage_t usage = GSS_C_ACCEPT;
+   OM_uint32 major_status, minor_status;
    char buf[1024];
    int have_server_princ;
 
@@ -1260,8 +1259,8 @@ get_gss_creds(request_rec *r,
    have_server_princ = conf->krb_service_name && 
strchr(conf->krb_service_name, '/') != NULL;
    if (have_server_princ)
       strncpy(buf, conf->krb_service_name, sizeof(buf));
-   else if (conf->krb_service_name && strcmp(conf->krb_service_name,"Any") == 
0) {      
-      *server_creds = GSS_C_NO_CREDENTIAL;
+   else if (conf->krb_service_name && strcmp(conf->krb_service_name,"Any") == 
0) {
+      *server_name = GSS_C_NO_NAME;
       return 0;
    }
    else
@@ -1274,7 +1273,7 @@ get_gss_creds(request_rec *r,
 
    major_status = gss_import_name(&minor_status, &token,
                                  (have_server_princ) ? (gss_OID) 
GSS_KRB5_NT_PRINCIPAL_NAME : (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
-                                 &server_name);
+                                 server_name);
    memset(&token, 0, sizeof(token));
    if (GSS_ERROR(major_status)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
@@ -1283,7 +1282,7 @@ get_gss_creds(request_rec *r,
       return HTTP_INTERNAL_SERVER_ERROR;
    }
 
-   major_status = gss_display_name(&minor_status, server_name, &token, NULL);
+   major_status = gss_display_name(&minor_status, *server_name, &token, NULL);
    if (GSS_ERROR(major_status)) {
       /* Perhaps we could just ignore this error but it's safer to give up now,
          I think */
@@ -1295,15 +1294,46 @@ get_gss_creds(request_rec *r,
 
    log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Acquiring creds for %s",
              token.value);
+   gss_release_buffer(&minor_status, &token);
+
+   return 0;
+}
+
+static int
+get_gss_creds(request_rec *r,
+              kerb_auth_config *conf,
+             gss_cred_id_t *server_creds)
+{
+   OM_uint32 major_status, minor_status, minor_status2;
+   gss_name_t server_name = GSS_C_NO_NAME;
+   gss_cred_usage_t usage = GSS_C_ACCEPT;
+   gss_key_value_element_desc e[1];
+   gss_key_value_set_desc kv = {0, &e[0]};
+
+   int rc = get_server_name(r, conf, &server_name);
+   if (rc)
+          return rc;
+
    if (conf->krb5_s4u2proxy) {
        usage = GSS_C_BOTH;
-       obtain_server_credentials(r, conf->krb_service_name);
+       obtain_server_credentials(r, conf->krb_service_name, 
conf->krb_5_keytab);
    }
-   gss_release_buffer(&minor_status, &token);
-   
-   major_status = gss_acquire_cred(&minor_status, server_name, 
GSS_C_INDEFINITE,
-                                  GSS_C_NO_OID_SET, usage,
-                                  server_creds, NULL, NULL);
+
+   if (conf->krb_5_keytab) {
+          e[kv.count].value = apr_pstrcat(r->pool, "FILE:", conf->krb_5_keytab,
+                                          NULL);
+          if (!e[kv.count].value) {
+                  log_rerror(APLOG_MARK, APLOG_ERR, APR_ENOMEM, r,
+                             "Out of memory");
+                  return HTTP_INTERNAL_SERVER_ERROR;
+          }
+          e[kv.count].key = "keytab";
+          ++kv.count;
+   }
+
+   major_status = gss_acquire_cred_from(
+          &minor_status, server_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET,
+          usage, &kv, server_creds, NULL, NULL);
    gss_release_name(&minor_status2, &server_name);
    if (GSS_ERROR(major_status)) {
       log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
@@ -1447,8 +1477,8 @@ cleanup:
 }
 
 static int
-obtain_server_credentials(request_rec *r,
-                          const char *service_name)
+obtain_server_credentials(request_rec *r, const char *service_name,
+                         const char *kt_name)
 {
     krb5_context kcontext = NULL;
     krb5_keytab keytab = NULL;
@@ -1555,7 +1585,9 @@ obtain_server_credentials(request_rec *r
         }
     }
 
-    if ((kerr = krb5_kt_default(kcontext, &keytab))) {
+    if ((kerr = (kt_name ?
+                krb5_kt_resolve(kcontext, kt_name, &keytab) :
+                krb5_kt_default(kcontext, &keytab)))) {
         log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "Unable to get default keytab: %s (%d)",
                    error_message(kerr), kerr);
@@ -1667,25 +1699,6 @@ authenticate_user_gss(request_rec *r, ke
   spnego_oid.length = 6;
   spnego_oid.elements = (void *)"\x2b\x06\x01\x05\x05\x02";
 
-  if (conf->krb_5_keytab) {
-     char *ktname;
-     /* we don't use the ap_* calls here, since the string passed to putenv()
-      * will become part of the enviroment and shouldn't be free()ed by apache
-      */
-     ktname = malloc(strlen("KRB5_KTNAME=") + strlen(conf->krb_5_keytab) + 1);
-     if (ktname == NULL) {
-       log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "malloc() failed: not enough 
memory");
-       ret = HTTP_INTERNAL_SERVER_ERROR;
-       goto end;
-     }
-     sprintf(ktname, "KRB5_KTNAME=%s", conf->krb_5_keytab);
-     putenv(ktname);
-#ifdef HEIMDAL
-     /* Seems to be also supported by latest MIT */
-     gsskrb5_register_acceptor_identity(conf->krb_5_keytab);
-#endif
-  }
-
   ret = get_gss_creds(r, conf, &server_creds);
   if (ret)
      goto end;

--- End Message ---
--- Begin Message ---
Version: 5.4-3+rm

Dear submitter,

as the package libapache-mod-auth-kerb has just been removed from the Debian 
archive
unstable we hereby close the associated bug reports.  We are sorry
that we couldn't deal with your issue properly.

For details on the removal, please see https://bugs.debian.org/1068262

The version of this package that was in Debian prior to this removal
can still be found using https://snapshot.debian.org/.

Please note that the changes have been done on the master archive and
will not propagate to any mirrors until the next dinstall run at the
earliest.

This message was generated automatically; if you believe that there is
a problem with it please contact the archive administrators by mailing
[email protected].

Debian distribution maintenance software
pp.
Thorsten Alteholz (the ftpmaster behind the curtain)

--- End Message ---

Reply via email to