sd-id128: do not allow null 'app_id' param

If it is null, we get the 'base' param unchanged:
$ build/systemd-id128 show 00000000000000000000000000000001 \
  --app-specific=00000000000000000000000000000000
00000000000000000000000000000001

This is not good, because it breaks our promise that the base (usually either
machine-id or boot-id) cannot be derived from the result. Some application
using the library could use a null app id, inadvertently exposing the machine
or boot id. (This could happen because of forgotten initialization, or maybe
because the app id is configurable, and the user configures it wrongly.)

Note: the other way the secret is not exposed:
$ build/systemd-id128 show 00000000000000000000000000000000 \
  --app-specific=00000000000000000000000000000002
4f63080959264900b0d88d999dae2d3a

Normally systemd would not allow a null machine-id or boot-id, but we can let
the user do the calculation that if they want to.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2023-08-26 14:03:14 +02:00
parent b37e8184a5
commit fa96afb4c4
4 changed files with 12 additions and 2 deletions

View file

@ -198,7 +198,10 @@
<term><constant>-ENXIO</constant></term>
<listitem><para>Returned by <function>sd_id128_get_invocation()</function> if no invocation ID is
set.</para>
set. Also returned by <function>sd_id128_get_app_specific()</function>,
<function>sd_id128_get_machine_app_specific()</function>, and
<function>sd_id128_get_boot_app_specific()</function> when the <parameter>app_id</parameter>
parameter is all zeros.</para>
<xi:include href="version-info.xml" xpointer="v242"/></listitem>
</varlistentry>

View file

@ -235,7 +235,9 @@ static int parse_argv(int argc, char *argv[]) {
break;
case 'a':
r = sd_id128_from_string(optarg, &arg_app);
r = id128_from_string_nonzero(optarg, &arg_app);
if (r == -ENXIO)
return log_error_errno(r, "Application ID cannot be all zeros.");
if (r < 0)
return log_error_errno(r, "Failed to parse \"%s\" as application-ID: %m", optarg);
break;

View file

@ -346,6 +346,7 @@ _public_ int sd_id128_get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id
} buf;
assert_return(ret, -EINVAL);
assert_return(!sd_id128_is_null(app_id), -ENXIO);
hmac_sha256(&base, sizeof(base), &app_id, sizeof(app_id), buf.hmac);

View file

@ -192,6 +192,10 @@ TEST(id128) {
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
assert_se(!sd_id128_equal(id, id2));
}
/* Check return values */
assert_se(sd_id128_get_app_specific(SD_ID128_ALLF, SD_ID128_NULL, &id) == -ENXIO);
assert_se(sd_id128_get_app_specific(SD_ID128_NULL, SD_ID128_ALLF, &id) == 0);
}
TEST(sd_id128_get_invocation) {