]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
creds: reject empty validity intervals 43040/head
authordongshengyuan <545258830@qq.com>
Thu, 16 Jul 2026 06:44:08 +0000 (14:44 +0800)
committerdongshengyuan <545258830@qq.com>
Sat, 18 Jul 2026 07:53:00 +0000 (15:53 +0800)
Reject credentials whose not-after timestamp is equal to the timestamp
at each encryption entry point.

Reproducer: systemd-creds --timestamp=TS --not-after=TS encrypt in out

Before: encryption succeeded, but decrypt refused the credential as not
in order.

Follow-up: 21bc0b6fa1de44b520353b935bf14160f9f70591

src/creds/creds.c
src/shared/creds-util.c
test/units/TEST-54-CREDS.sh

index 765185dbe75bc98213e67f7682c87561c6c64708..d863ed83868db0cada24a30e95e6c020e6ffa0c4 100644 (file)
@@ -599,8 +599,8 @@ static int verb_encrypt(int argc, char *argv[], uintptr_t _data, void *userdata)
 
         timestamp = arg_timestamp != USEC_INFINITY ? arg_timestamp : now(CLOCK_REALTIME);
 
-        if (arg_not_after != USEC_INFINITY && arg_not_after < timestamp)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential is invalidated before it is valid.");
+        if (arg_not_after != USEC_INFINITY && arg_not_after <= timestamp)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential is invalidated before or when it becomes valid.");
 
         if (geteuid() != 0 && !sd_id128_equal(arg_with_key, CRED_AES256_GCM_BY_NULL)) {
                 (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
@@ -1257,7 +1257,7 @@ static int vl_method_encrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
                 timestamp_fresh = true;
         } else
                 timestamp_fresh = timestamp_is_fresh(p.timestamp);
-        if (p.not_after != UINT64_MAX && p.not_after < p.timestamp)
+        if (p.not_after != UINT64_MAX && p.not_after <= p.timestamp)
                 return sd_varlink_error_invalid_parameter_name(link, "notAfter");
 
         r = settle_scope(link, &p.scope, &p.uid, &cflags, /* any_scope_after_polkit= */ NULL);
index 09bbf6bca89ba9f00306d2161b2089ab65f3f915..bbba1c3eae66d511ac21e207ff0744687d85d799 100644 (file)
@@ -900,8 +900,8 @@ int encrypt_credential_and_warn(
         if (name && !credential_name_valid(name))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid credential name: %s", name);
 
-        if (not_after != USEC_INFINITY && timestamp != USEC_INFINITY && not_after < timestamp)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential is invalidated before it is valid (" USEC_FMT " < " USEC_FMT ").", not_after, timestamp);
+        if (not_after != USEC_INFINITY && timestamp != USEC_INFINITY && not_after <= timestamp)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential is invalidated before or when it becomes valid (" USEC_FMT " <= " USEC_FMT ").", not_after, timestamp);
 
         if (DEBUG_LOGGING) {
                 char buf[FORMAT_TIMESTAMP_MAX];
index 7c2774fa103296550ef6e90e146039bb6669a228..75d1c41253dc2c2a190bacb8f17b7604b6fdf463 100755 (executable)
@@ -167,6 +167,8 @@ systemd-creds --not-after="+1d" encrypt /tmp/cred.orig /tmp/cred.enc
 systemd-creds decrypt /tmp/cred.enc /tmp/cred.dec
 diff /tmp/cred.orig /tmp/cred.dec
 rm -f /tmp/cred.{enc,dec}
+ts="$(date -u '+%Y-%m-%d %H:%M:%S UTC')"
+(! systemd-creds --with-key=null --timestamp="$ts" --not-after="$ts" encrypt /tmp/cred.orig /tmp/cred.enc)
 
 # Null-key credentials and the systemd.credentials_boot_policy= setting.
 #