return 0;
}
-static char* random_name(void) {
- char *s = NULL;
+static char* hash_name(sd_varlink *link, const char *name) {
+ int r;
+
+ assert(link);
+ assert(name);
+
+ /* Make up a hashed name for this userns. We take the passed name, and hash it together with the
+ * connection cookie. This should make collisions unlikely but generation still deterministic (this
+ * matters because on polkit requests we might be called twice, and should generate the same string
+ * each time, to ensure the Polkit query looks the same) */
+
+ uint64_t cookie = 0;
+ r = socket_get_cookie(sd_varlink_get_fd(link), &cookie);
+ if (r < 0)
+ log_debug_errno(r, "Failed to determine connection cookie, ignoring: %m");
+
+ struct siphash h;
+ static sd_id128_t key = SD_ID128_MAKE(ed,3a,bb,01,3a,14,4b,b3,8a,63,a4,ad,ba,2d,c9,0a);
+ siphash24_init(&h, key.bytes);
+ siphash24_compress_typesafe(cookie, &h);
+ siphash24_compress_string(name, &h);
+
+ /* Make sure the hashed name fits into utmpx even if prefixed with "ns-", the peer's UID, "-", and
+ * suffixed by "-65535". */
- /* Make up a random name for this userns. Make sure the random name fits into utmpx even if prefixed
- * with "ns-", the peer's UID, "-", and suffixed by "-65535". */
assert_cc(STRLEN("ns-65535-") + 16 + STRLEN("-65535") < sizeof_field(struct utmpx, ut_user));
- if (asprintf(&s, "%016" PRIx64, random_u64()) < 0)
+ char *s = NULL;
+ if (asprintf(&s, "%016" PRIx64, siphash24_finalize(&h)) < 0)
return NULL;
return s;
if (!userns_name_is_valid(un)) {
free(un);
- /* if not, make up a random name */
- un = random_name();
+ /* if not, make up a hashed name */
+ un = hash_name(link, name);
if (!un)
return -ENOMEM;
}
free_and_replace(un, c);
else {
free(c);
- c = random_name();
+ c = hash_name(link, name);
if (!c)
return -ENOMEM;