Package: keyutils Version: 1.6.1-3 Severity: normal Tags: patch User: ubuntu-de...@lists.ubuntu.com Usertags: origin-ubuntu kinetic ubuntu-patch
Dear Maintainer, * What led up to the situation? Connect to a file share server hosted in the cloud using cifs. At some point the SMB server moves to a different cluster (with a set of IP addresses) and its DNS records are updated accordingly. * What was the outcome of this action? The kernel tries to reconnect to the old IP that was cached for unlimited time. * What outcome did you expect instead? After _some_ delay, the kernel should perform DNS resolution again and pick-up the new IP ; so it can reconnect to the server successfully. *** /tmp/tmprouv6pz2/bug_body In Ubuntu, the attached patch was applied to achieve the following: * Apply upstream patch that applies a configurable default TTL for DNS records. Thanks for considering the patch. -- System Information: Debian Release: bookworm/sid APT prefers jammy-updates APT policy: (500, 'jammy-updates'), (500, 'jammy-security'), (500, 'jammy'), (100, 'jammy-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 5.15.0-35-generic (SMP w/4 CPU threads) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
diff -Nru keyutils-1.6.1/debian/patches/apply-default-ttl-to-records.patch keyutils-1.6.1/debian/patches/apply-default-ttl-to-records.patch --- keyutils-1.6.1/debian/patches/apply-default-ttl-to-records.patch 1970-01-01 01:00:00.000000000 +0100 +++ keyutils-1.6.1/debian/patches/apply-default-ttl-to-records.patch 2022-02-28 10:43:38.000000000 +0100 @@ -0,0 +1,522 @@ +From 75e7568dc516db698093b33ea273e1b4a30b70be Mon Sep 17 00:00:00 2001 +From: David Howells <dhowe...@redhat.com> +Date: Tue, 14 Apr 2020 16:07:26 +0100 +Subject: dns: Apply a default TTL to records obtained from getaddrinfo() + Address records obtained from getaddrinfo() don't come with any TTL + information, even if they're obtained from the DNS, with the result that + key.dns_resolver upcall program doesn't set an expiry time on dns_resolver + records unless they include a component obtained directly from the DNS, + such as an SRV or AFSDB record. + . + Fix this to apply a default TTL of 10mins in the event that we haven't got + one. This can be configured in /etc/keyutils/key.dns_resolver.conf by + adding the line: + . + default_ttl = <number-of-seconds> + . + to the file. + . + Signed-off-by: David Howells <dhowe...@redhat.com> + Reviewed-by: Ben Boeckel <m...@benboeckel.net> + Reviewed-by: Jeff Layton <jlay...@kernel.org> +Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git/commit/?id=75e7568dc516db698093b33ea273e1b4a30b70be +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/keyutils/+bug/1962453 +Last-Updated: 2022-02-28 + +--- + Makefile | 1 + + dns.afsdb.c | 16 ++-- + key.dns.h | 4 + + key.dns_resolver.c | 208 +++++++++++++++++++++++++++++++++++++++++--- + man/key.dns_resolver.8 | 25 ++++-- + man/key.dns_resolver.conf.5 | 48 ++++++++++ + 6 files changed, 277 insertions(+), 25 deletions(-) + create mode 100644 man/key.dns_resolver.conf.5 + +--- a/Makefile ++++ b/Makefile +@@ -204,6 +204,7 @@ + $(INSTALL) -D key.dns_resolver $(DESTDIR)$(SBINDIR)/key.dns_resolver + $(INSTALL) -D -m 0644 request-key.conf $(DESTDIR)$(ETCDIR)/request-key.conf + mkdir -p $(DESTDIR)$(ETCDIR)/request-key.d ++ mkdir -p $(DESTDIR)$(ETCDIR)/keyutils + mkdir -p $(DESTDIR)$(MAN1) + $(INSTALL) -m 0644 $(wildcard man/*.1) $(DESTDIR)$(MAN1) + mkdir -p $(DESTDIR)$(MAN3) +--- a/dns.afsdb.c ++++ b/dns.afsdb.c +@@ -37,8 +37,6 @@ + */ + #include "key.dns.h" + +-static unsigned long afs_ttl = ULONG_MAX; +- + /* + * + */ +@@ -114,8 +112,8 @@ + } + } + +- afs_ttl = ttl; +- info("ttl: %u", ttl); ++ key_expiry = ttl; ++ info("ttl: %u", key_expiry); + } + + /* +@@ -203,8 +201,8 @@ + } + } + +- afs_ttl = ttl; +- info("ttl: %u", ttl); ++ key_expiry = ttl; ++ info("ttl: %u", key_expiry); + } + + /* +@@ -240,7 +238,7 @@ + /* look up the hostnames we've obtained to get the actual addresses */ + afsdb_hosts_to_addrs(handle, ns_s_an); + +- info("DNS query AFSDB RR results:%u ttl:%lu", payload_index, afs_ttl); ++ info("DNS query AFSDB RR results:%u ttl:%u", payload_index, key_expiry); + return 0; + } + +@@ -279,7 +277,7 @@ + /* look up the hostnames we've obtained to get the actual addresses */ + srv_hosts_to_addrs(handle, ns_s_an); + +- info("DNS query VL SRV RR results:%u ttl:%lu", payload_index, afs_ttl); ++ info("DNS query VL SRV RR results:%u ttl:%u", payload_index, key_expiry); + return 0; + } + +@@ -293,7 +291,7 @@ + + /* set the key's expiry time from the minimum TTL encountered */ + if (!debug_mode) { +- ret = keyctl_set_timeout(key, afs_ttl); ++ ret = keyctl_set_timeout(key, key_expiry); + if (ret == -1) + error("%s: keyctl_set_timeout: %m", __func__); + } +--- a/key.dns.h ++++ b/key.dns.h +@@ -29,6 +29,7 @@ + #include <stdlib.h> + #include <unistd.h> + #include <time.h> ++#include <ctype.h> + + #define MAX_VLS 15 /* Max Volume Location Servers Per-Cell */ + #define INET_IP4_ONLY 0x1 +@@ -42,6 +43,7 @@ + extern key_serial_t key; + extern int debug_mode; + extern unsigned mask; ++extern unsigned int key_expiry; + + #define N_PAYLOAD 256 + extern struct iovec payload[N_PAYLOAD]; +@@ -52,6 +54,8 @@ + extern __attribute__((format(printf, 1, 2))) + void _error(const char *fmt, ...); + extern __attribute__((format(printf, 1, 2))) ++void warning(const char *fmt, ...); ++extern __attribute__((format(printf, 1, 2))) + void info(const char *fmt, ...); + extern __attribute__((noreturn)) + void nsError(int err, const char *domain); +--- a/key.dns_resolver.c ++++ b/key.dns_resolver.c +@@ -46,10 +46,13 @@ + static const char a_query_type[] = "a"; + static const char aaaa_query_type[] = "aaaa"; + static const char afsdb_query_type[] = "afsdb"; ++static const char *config_file = "/etc/keyutils/key.dns_resolver.conf"; ++static bool config_specified = false; + key_serial_t key; + static int verbose; + int debug_mode; + unsigned mask = INET_ALL; ++unsigned int key_expiry = 5; + + + /* +@@ -106,6 +109,23 @@ + } + + /* ++ * Print a warning to stderr or the syslog ++ */ ++void warning(const char *fmt, ...) ++{ ++ va_list va; ++ ++ va_start(va, fmt); ++ if (isatty(2)) { ++ vfprintf(stderr, fmt, va); ++ fputc('\n', stderr); ++ } else { ++ vsyslog(LOG_WARNING, fmt, va); ++ } ++ va_end(va); ++} ++ ++/* + * Print status information + */ + void info(const char *fmt, ...) +@@ -272,6 +292,7 @@ + } + + info("The key instantiation data is '%s'", buf); ++ info("The expiry time is %us", key_expiry); + free(buf); + } + +@@ -412,6 +433,9 @@ + + /* load the key with data key */ + if (!debug_mode) { ++ ret = keyctl_set_timeout(key, key_expiry); ++ if (ret == -1) ++ error("%s: keyctl_set_timeout: %m", __func__); + ret = keyctl_instantiate_iov(key, payload, payload_index, 0); + if (ret == -1) + error("%s: keyctl_instantiate: %m", __func__); +@@ -421,6 +445,157 @@ + } + + /* ++ * Read the config file. ++ */ ++static void read_config(void) ++{ ++ FILE *f; ++ char buf[4096], *b, *p, *k, *v; ++ unsigned int line = 0, u; ++ int n; ++ ++ info("READ CONFIG %s", config_file); ++ ++ f = fopen(config_file, "r"); ++ if (!f) { ++ if (errno == ENOENT && !config_specified) { ++ debug("%s: %m", config_file); ++ return; ++ } ++ error("%s: %m", config_file); ++ } ++ ++ while (fgets(buf, sizeof(buf) - 1, f)) { ++ line++; ++ ++ /* Trim off leading and trailing spaces and discard whole-line ++ * comments. ++ */ ++ b = buf; ++ while (isspace(*b)) ++ b++; ++ if (!*b || *b == '#') ++ continue; ++ p = strchr(b, '\n'); ++ if (!p) ++ error("%s:%u: line missing newline or too long", config_file, line); ++ while (p > buf && isspace(p[-1])) ++ p--; ++ *p = 0; ++ ++ /* Split into key[=value] pairs and trim spaces. */ ++ k = b; ++ v = NULL; ++ b = strchr(b, '='); ++ if (b) { ++ char quote = 0; ++ bool esc = false; ++ ++ if (b == k) ++ error("%s:%u: Unspecified key", ++ config_file, line); ++ ++ /* NUL-terminate the key. */ ++ for (p = b - 1; isspace(*p); p--) ++ ; ++ p[1] = 0; ++ ++ /* Strip leading spaces */ ++ b++; ++ while (isspace(*b)) ++ b++; ++ if (!*b) ++ goto missing_value; ++ ++ if (*b == '"' || *b == '\'') { ++ quote = *b; ++ b++; ++ } ++ v = p = b; ++ while (*b) { ++ if (esc) { ++ switch (*b) { ++ case ' ': ++ case '\t': ++ case '"': ++ case '\'': ++ case '\\': ++ break; ++ default: ++ goto invalid_escape_char; ++ } ++ esc = false; ++ *p++ = *b++; ++ continue; ++ } ++ if (*b == '\\') { ++ esc = true; ++ b++; ++ continue; ++ } ++ if (*b == quote) { ++ b++; ++ if (*b) ++ goto post_quote_data; ++ quote = 0; ++ break; ++ } ++ if (!quote && *b == '#') ++ break; /* Terminal comment */ ++ *p++ = *b++; ++ } ++ ++ if (esc) ++ error("%s:%u: Incomplete escape", config_file, line); ++ if (quote) ++ error("%s:%u: Unclosed quotes", config_file, line); ++ *p = 0; ++ } ++ ++ if (strcmp(k, "default_ttl") == 0) { ++ if (!v) ++ goto missing_value; ++ if (sscanf(v, "%u%n", &u, &n) != 1) ++ goto bad_value; ++ if (v[n]) ++ goto extra_data; ++ if (u < 1 || u > INT_MAX) ++ goto out_of_range; ++ key_expiry = u; ++ } else { ++ warning("%s:%u: Unknown option '%s'", config_file, line, k); ++ } ++ } ++ ++ if (ferror(f) || fclose(f) == EOF) ++ error("%s: %m", config_file); ++ return; ++ ++missing_value: ++ error("%s:%u: %s: Missing value", config_file, line, k); ++invalid_escape_char: ++ error("%s:%u: %s: Invalid char in escape", config_file, line, k); ++post_quote_data: ++ error("%s:%u: %s: Data after closing quote", config_file, line, k); ++bad_value: ++ error("%s:%u: %s: Bad value", config_file, line, k); ++extra_data: ++ error("%s:%u: %s: Extra data supplied", config_file, line, k); ++out_of_range: ++ error("%s:%u: %s: Value out of range", config_file, line, k); ++} ++ ++/* ++ * Dump the configuration after parsing the config file. ++ */ ++static __attribute__((noreturn)) ++void config_dumper(void) ++{ ++ printf("default_ttl = %u\n", key_expiry); ++ exit(0); ++} ++ ++/* + * Print usage details, + */ + static __attribute__((noreturn)) +@@ -428,22 +603,24 @@ + { + if (isatty(2)) { + fprintf(stderr, +- "Usage: %s [-vv] key_serial\n", ++ "Usage: %s [-vv] [-c config] key_serial\n", + prog); + fprintf(stderr, +- "Usage: %s -D [-vv] <desc> <calloutinfo>\n", ++ "Usage: %s -D [-vv] [-c config] <desc> <calloutinfo>\n", + prog); + } else { +- info("Usage: %s [-vv] key_serial", prog); ++ info("Usage: %s [-vv] [-c config] key_serial", prog); + } + exit(2); + } + +-const struct option long_options[] = { +- { "debug", 0, NULL, 'D' }, +- { "verbose", 0, NULL, 'v' }, +- { "version", 0, NULL, 'V' }, +- { NULL, 0, NULL, 0 } ++static const struct option long_options[] = { ++ { "config", 0, NULL, 'c' }, ++ { "debug", 0, NULL, 'D' }, ++ { "dump-config", 0, NULL, 2 }, ++ { "verbose", 0, NULL, 'v' }, ++ { "version", 0, NULL, 'V' }, ++ { NULL, 0, NULL, 0 } + }; + + /* +@@ -455,11 +632,19 @@ + char *keyend, *p; + char *callout_info = NULL; + char *buf = NULL, *name; ++ bool dump_config = false; + + openlog(prog, 0, LOG_DAEMON); + +- while ((ret = getopt_long(argc, argv, "vDV", long_options, NULL)) != -1) { ++ while ((ret = getopt_long(argc, argv, "c:vDV", long_options, NULL)) != -1) { + switch (ret) { ++ case 'c': ++ config_file = optarg; ++ config_specified = true; ++ continue; ++ case 2: ++ dump_config = true; ++ continue; + case 'D': + debug_mode = 1; + continue; +@@ -481,6 +666,9 @@ + + argc -= optind; + argv += optind; ++ read_config(); ++ if (dump_config) ++ config_dumper(); + + if (!debug_mode) { + if (argc != 1) +@@ -542,7 +730,7 @@ + name++; + + info("Query type: '%*.*s'", qtlen, qtlen, keyend); +- ++ + if ((qtlen == sizeof(a_query_type) - 1 && + memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) || + (qtlen == sizeof(aaaa_query_type) - 1 && +--- a/man/key.dns_resolver.8 ++++ b/man/key.dns_resolver.8 +@@ -7,28 +7,41 @@ + .\" as published by the Free Software Foundation; either version + .\" 2 of the License, or (at your option) any later version. + .\" +-.TH KEY.DNS_RESOLVER 8 "04 Mar 2011" Linux "Linux Key Management Utilities" ++.TH KEY.DNS_RESOLVER 8 "18 May 2020" Linux "Linux Key Management Utilities" + .SH NAME + key.dns_resolver \- upcall for request\-key to handle dns_resolver keys + .SH SYNOPSIS + \fB/sbin/key.dns_resolver \fR<key> + .br +-\fB/sbin/key.dns_resolver \fR\-D [\-v] [\-v] <keydesc> <calloutinfo> ++\fB/sbin/key.dns_resolver \fR--dump-config [\-c <configfile>] ++.br ++\fB/sbin/key.dns_resolver \fR\-D [\-v] [\-v] [\-c <configfile>] <desc> ++.br ++<calloutinfo> + .SH DESCRIPTION + This program is invoked by request\-key on behalf of the kernel when kernel + services (such as NFS, CIFS and AFS) want to perform a hostname lookup and the + kernel does not have the key cached. It is not ordinarily intended to be + called directly. + .P +-It can be called in debugging mode to test its functionality by passing a +-\fB\-D\fR flag on the command line. For this to work, the key description and +-the callout information must be supplied. Verbosity can be increased by +-supplying one or more \fB\-v\fR flags. ++There program has internal parameters that can be changed with a configuration ++file (see key.dns_resolver.conf(5) for more information). The default ++configuration file is in /etc, but this can be overridden with the \fB-c\fR ++flag. ++.P ++The program can be called in debugging mode to test its functionality by ++passing a \fB\-D\fR or \fB\--debug\fR flag on the command line. For this to ++work, the key description and the callout information must be supplied. ++Verbosity can be increased by supplying one or more \fB\-v\fR flags. ++.P ++The program may also be called with \fB--dump-config\fR to show the values that ++configurable parameters will have after parsing the config file. + .SH ERRORS + All errors will be logged to the syslog. + .SH SEE ALSO + .ad l + .nh ++.BR key.dns_resolver.conf (5), + .BR request\-key.conf (5), + .BR keyrings (7), + .BR request\-key (8) +--- /dev/null ++++ b/man/key.dns_resolver.conf.5 +@@ -0,0 +1,48 @@ ++.\" -*- nroff -*- ++.\" Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. ++.\" Written by David Howells (dhowe...@redhat.com) ++.\" ++.\" This program is free software; you can redistribute it and/or ++.\" modify it under the terms of the GNU General Public License ++.\" as published by the Free Software Foundation; either version ++.\" 2 of the License, or (at your option) any later version. ++.\" ++.TH KEY.DNS_RESOLVER.CONF 5 "18 May 2020" Linux "Linux Key Management Utilities" ++.SH NAME ++key.dns_resolver.conf \- Kernel DNS resolver config ++.SH DESCRIPTION ++This file is used by the key.dns_resolver(5) program to set parameters. ++Unless otherwise overridden with the \fB\-c\fR flag, the program reads: ++.IP ++/etc/key.dns_resolver.conf ++.P ++Configuration options are given in \fBkey[=value]\fR form, where \fBvalue\fR is ++optional. If present, the value may be surrounded by a pair of single ('') or ++double quotes ("") which will be stripped off. The special characters in the ++value may be escaped with a backslash to turn them into ordinary characters. ++.P ++Lines beginning with a '#' are considered comments and ignored. A '#' symbol ++anywhere after the '=' makes the rest of the line into a comment unless the '#' ++is inside a quoted section or is escaped. ++.P ++Leading and trailing spaces and spaces around the '=' symbol will be stripped ++off. ++.P ++Available options include: ++.TP ++.B default_ttl=<number> ++The number of seconds to set as the expiration on a cached record. This will ++be overridden if the program manages to retrieve TTL information along with ++the addresses (if, for example, it accesses the DNS directly). The default is ++5 seconds. The value must be in the range 1 to INT_MAX. ++.P ++The file can also include comments beginning with a '#' character unless ++otherwise suppressed by being inside a quoted value or being escaped with a ++backslash. ++ ++.SH FILES ++.ul ++/etc/key.dns_resolver.conf ++.ul 0 ++.SH SEE ALSO ++\fBkey.dns_resolver\fR(8) diff -Nru keyutils-1.6.1/debian/patches/series keyutils-1.6.1/debian/patches/series --- keyutils-1.6.1/debian/patches/series 2022-03-04 11:13:34.000000000 +0100 +++ keyutils-1.6.1/debian/patches/series 2022-06-08 17:00:59.000000000 +0200 @@ -6,3 +6,4 @@ pkg-config-install-tweaks.patch man-page-fixes.patch Tests-for-KEYCTL_MOVE-require-kernel-5.3-or-above.patch +apply-default-ttl-to-records.patch