summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2023-12-14 12:33:35 +0100
committerAlejandro Colomar <alx@kernel.org>2024-02-14 04:07:55 +0100
commit541d4dde23e8cfaee8291d5a9289aa9de7fb80d2 (patch)
treeff50e07feb39dd38868611f9752f18298d3c18c9
parent55f9635ecf1f637abb86f77ec456f7e69e9e9ebc (diff)
src/chage.c: Unify long overflow checks in print_day_as_date()
The conversion from day to seconds can be done in print_date (renamed to print_day_as_date for clarification). This has the nice benefit that DAY multiplication and long to time_t conversion are done at just one place. Co-developed-by: Tobias Stoeckmann <tobias@stoeckmann.org> Co-developed-by: Alejandro Colomar <alx@kernel.org> Signed-off-by: Alejandro Colomar <alx@kernel.org> Cherry-picked-from: 20100e4b22c3 ("src/chage.c: Unify long overflow checks in print_day_as_date()") Cc: "Serge E. Hallyn" <serge@hallyn.com> Link: <https://github.com/shadow-maint/shadow/pull/876> [alx: This is a pre-requisite for 674409e2265e ("lib/: Saturate addition to avoid overflow")] Signed-off-by: Alejandro Colomar <alx@kernel.org>
-rw-r--r--src/chage.c52
1 files changed, 27 insertions, 25 deletions
diff --git a/src/chage.c b/src/chage.c
index 8a6d3584..ecbf8738 100644
--- a/src/chage.c
+++ b/src/chage.c
@@ -72,7 +72,7 @@ static long expdate;
/* local function prototypes */
NORETURN static void usage (int status);
static int new_fields (void);
-static void print_date (time_t date);
+static void print_day_as_date (long day);
static void list_fields (void);
static void process_flags (int argc, char **argv);
static void check_flags (int argc, int opt_index);
@@ -227,10 +227,22 @@ static int new_fields (void)
return 1;
}
-static void print_date (time_t date)
+
+static void
+print_day_as_date(long day)
{
- struct tm *tp;
- char buf[80];
+ char buf[80];
+ time_t date;
+ struct tm *tp;
+
+ if (day < 0) {
+ puts(_("never"));
+ return;
+ }
+ if (__builtin_mul_overflow(day, DAY, &date)) {
+ puts(_("future"));
+ return;
+ }
tp = gmtime (&date);
if (NULL == tp) {
@@ -241,6 +253,7 @@ static void print_date (time_t date)
}
}
+
/*
* list_fields - display the current values of the expiration fields
*
@@ -250,21 +263,15 @@ static void print_date (time_t date)
*/
static void list_fields (void)
{
- long changed = 0;
- long expires;
-
/*
* The "last change" date is either "never" or the date the password
* was last modified. The date is the number of days since 1/1/1970.
*/
(void) fputs (_("Last password change\t\t\t\t\t: "), stdout);
- if (lstchgdate < 0 || lstchgdate > LONG_MAX / DAY) {
- (void) puts (_("never"));
- } else if (lstchgdate == 0) {
+ if (lstchgdate == 0) {
(void) puts (_("password must be changed"));
} else {
- changed = lstchgdate * DAY;
- print_date (changed);
+ print_day_as_date(lstchgdate);
}
/*
@@ -277,11 +284,11 @@ static void list_fields (void)
} else if ( (lstchgdate < 0)
|| (maxdays >= 10000)
|| (maxdays < 0)
- || ((LONG_MAX - changed) / DAY < maxdays)) {
+ || (LONG_MAX - lstchgdate < maxdays))
+ {
(void) puts (_("never"));
} else {
- expires = changed + maxdays * DAY;
- print_date (expires);
+ print_day_as_date(lstchgdate + maxdays);
}
/*
@@ -297,12 +304,12 @@ static void list_fields (void)
|| (inactdays < 0)
|| (maxdays >= 10000)
|| (maxdays < 0)
- || (maxdays > LONG_MAX - inactdays)
- || ((LONG_MAX - changed) / DAY < maxdays + inactdays)) {
+ || (LONG_MAX - inactdays < maxdays)
+ || (LONG_MAX - lstchgdate < maxdays + inactdays))
+ {
(void) puts (_("never"));
} else {
- expires = changed + (maxdays + inactdays) * DAY;
- print_date (expires);
+ print_day_as_date(lstchgdate + maxdays + inactdays);
}
/*
@@ -310,12 +317,7 @@ static void list_fields (void)
* password expiring or not.
*/
(void) fputs (_("Account expires\t\t\t\t\t\t: "), stdout);
- if (expdate < 0 || LONG_MAX / DAY < expdate) {
- (void) puts (_("never"));
- } else {
- expires = expdate * DAY;
- print_date (expires);
- }
+ print_day_as_date(expdate);
/*
* Start with the easy numbers - the number of days before the