[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#1063329: libselinux1t64: breaks system in upgrade from unstable



07.02.2024 11:06, Helmut Grohne :
..
pam seems difficult:
| extern time_t pam_misc_conv_warn_time; /* time that we should warn user */
| extern time_t pam_misc_conv_die_time;         /* cut-off time for input */

Attached is a sketch to make pam compatible.

I had a more complete and *tested* fix 2 days ago but I forgot
it was in /tmp and I rebooted the machine, so had to do it again
yesterday.

The idea is to have both die_time and die_time64, and keep them
in sync (using minimum between two values which is !=0).

This is a sketch using a #define, though better is to use symbol
versioning here and have time32 compat stuff for old programs
and 64bit time stuff for new, using redirection at the link time,
instead of the #defines which makes whole thing rather difficult
to read, - that's extra several lines of code, also to the .map
file.

What the whole thing needs is the criteria to use to enable the
trick.  Right now I used #ifdef NEED_TIME64_COMPAT which should
be defined somehow, - since I don't know the precise list of
architectures where this has to be done.  This is an externally-
controlled thing, there's no way to determine this directly from
the .c code (short of using architecture list in the .h file),
so it must be some symbol substituted at the package build time,
like Provides: t64:Compat (or whatever it is) is substituted in
d/control.

This is a less-intrusve-to-original-code version of the sketch,
ie, I tried to keep all changes outside of the original code as
possible, keeping all the original logic as it is.

/mjt
diff --git a/libpam_misc/include/security/pam_misc.h b/libpam_misc/include/security/pam_misc.h
index fca2422..922341c 100644
--- a/libpam_misc/include/security/pam_misc.h
+++ b/libpam_misc/include/security/pam_misc.h
@@ -21,6 +21,15 @@ extern int misc_conv(int num_msg, const struct pam_message **msgm,
 
 #include <time.h>
 
+#if NEED_TIME64_COMPAT
+
+extern time32_t pam_misc_conv_warn_time;
+extern time32_t pam_misc_conv_die_time;
+#define pam_misc_conv_warn_time pam_misc_conv_warn_time64
+#define pam_misc_conv_die_time pam_misc_conv_die_time64
+
+#endif
+
 extern time_t pam_misc_conv_warn_time; /* time that we should warn user */
 extern time_t pam_misc_conv_die_time;         /* cut-off time for input */
 extern const char *pam_misc_conv_warn_line;           /* warning notice */
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
index 908ee89..a02d491 100644
--- a/libpam_misc/misc_conv.c
+++ b/libpam_misc/misc_conv.c
@@ -30,6 +30,9 @@
 time_t pam_misc_conv_warn_time = 0;                  /* time when we warn */
 time_t pam_misc_conv_die_time  = 0;               /* time when we timeout */
 
+static void fixup_compat_time();
+static void reset_warn_time();
+
 const char *pam_misc_conv_warn_line = N_("...Time is running out...\n");
 const char *pam_misc_conv_die_line  = N_("...Sorry, your time is up!\n");
 
@@ -96,6 +99,8 @@ static int get_delay(void)
     expired = 0;                                        /* reset flag */
     (void) time(&now);
 
+    fixup_compat_time();
+
     /* has the quit time past? */
     if (pam_misc_conv_die_time && now >= pam_misc_conv_die_time) {
 	fprintf(stderr,"%s",pam_misc_conv_die_line);
@@ -107,7 +112,7 @@ static int get_delay(void)
     /* has the warning time past? */
     if (pam_misc_conv_warn_time && now >= pam_misc_conv_warn_time) {
 	fprintf(stderr, "%s", pam_misc_conv_warn_line);
-	pam_misc_conv_warn_time = 0;                    /* reset warn_time */
+	reset_warn_time();
 
 	/* indicate remaining delay - if any */
 
@@ -399,3 +404,36 @@ failed_conversation:
 
     return PAM_CONV_ERR;
 }
+
+#ifdef NEED_TIME64_COMPAT
+
+#undef pam_misc_conv_warn_time
+#undef pam_misc_conv_die_time
+
+int pam_misc_conv_warn_time, pam_misc_conv_die_time;
+
+    /* in compat 32/64 case, we have 2 values: time and time64.
+       We perform all operations with time64
+       But we try to keep them in sync, whiciever is smaller but !0 */
+#define fixup(t, t32) \
+    if (t32 && (!t || t > t32)) t = t32; /* if t32 fires sooner */ \
+    if (t < 0x7fffffff) t32 = t /* only if t can fit in t32 */
+
+static void fixup_compat_time() {
+    fixup(pam_misc_conv_warn_time64, pam_misc_conv_warn_time);
+    fixup(pam_misc_conv_die_time64,  pam_misc_conv_die_time);
+}
+static void reset_warn_time() {
+   pam_misc_conv_warn_time = 0;
+   pam_misc_conv_warn_time64 = 0;
+}
+
+#else
+
+static void fixup_compat_time() {
+}
+static void reset_warn_time() {
+   pam_misc_conv_warn_time = 0;
+}
+
+#endif

Reply to: