From nobody Mon Feb 9 16:18:43 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1690196865; cv=none; d=zohomail.com; s=zohoarc; b=Nujj/F5CTJv1nLRPRmMIGo/DyQLAhNCtaeRrvYalmO2wj1teUM67I+9Oaz5yCn6KqwHK1WuacvJbl2doQnDqiVy/7cyghMPV11N3OUS8/2XHh+t8jam1bmcyxcNcsOu2ijZBphTFGAmsveXJZ9feGe5heTWMt9oVVTv//FpojCs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1690196865; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9aPawA5ESo5CRMIgOFiPZjmhXxpcDENIO0dImei+Tbo=; b=LWuzqtqAexbcKPK3RYZ82hlT5N9W3XTHN7TAyYr/xz19qwCoVgxuSbDmwtUecvGRtolLnBRyxZ/hjMfr4t5QX8TORKClkMkzC9wIZBetf0iZz2Zl/qocXMwmcgtvAARQNMWIOpDyEFNOhRDJBYuVfkK5+140ccIYJzPD4TcmCdo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1690196865349410.35305529237235; Mon, 24 Jul 2023 04:07:45 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.568753.888678 (Exim 4.92) (envelope-from ) id 1qNtPU-0006z8-2m; Mon, 24 Jul 2023 11:07:28 +0000 Received: by outflank-mailman (output) from mailman id 568753.888678; Mon, 24 Jul 2023 11:07:28 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qNtPT-0006yt-UR; Mon, 24 Jul 2023 11:07:27 +0000 Received: by outflank-mailman (input) for mailman id 568753; Mon, 24 Jul 2023 11:07:26 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qNtN7-0008WC-O3 for xen-devel@lists.xenproject.org; Mon, 24 Jul 2023 11:05:01 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ee780650-2a11-11ee-8612-37d641c3527e; Mon, 24 Jul 2023 13:05:00 +0200 (CEST) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id C40F01FDF0; Mon, 24 Jul 2023 11:04:59 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 973BA13476; Mon, 24 Jul 2023 11:04:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id lvtGI9tavmR+YgAAMHmgww (envelope-from ); Mon, 24 Jul 2023 11:04:59 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ee780650-2a11-11ee-8612-37d641c3527e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1690196699; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9aPawA5ESo5CRMIgOFiPZjmhXxpcDENIO0dImei+Tbo=; b=MOWePWqF3Qw+uHN0dIhCwibDKqjlcE2Xt2ucz5KA96XZstUbGtqdSW04vakXkOhyBwirwB /tiVphEvE9PeTZyDLm0TF3HKMIPK8GzHWakj8DFL41y7h4M2ruQ/C6Dc8dTTWlU1ZN+rOH R4xM3ZTgbox+vNfJwveEgxDSvh32HkY= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH v3 23/25] tools/xenstore: merge is_valid_nodename() into canonicalize() Date: Mon, 24 Jul 2023 13:02:45 +0200 Message-Id: <20230724110247.10520-24-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230724110247.10520-1-jgross@suse.com> References: <20230724110247.10520-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1690196867749100001 Content-Type: text/plain; charset="utf-8" Today is_valid_nodename() is always called directly after calling canonicalize(), with the exception of do_unwatch(), where the call is missing (which is not correct, but results just in a wrong error reason being returned). Merge is_valid_nodename() into canonicalize(). While at it merge valid_chars() into it, too. Signed-off-by: Juergen Gross --- V3: - new patch --- tools/xenstore/xenstored_core.c | 89 ++++++++++++++------------------ tools/xenstore/xenstored_core.h | 6 +-- tools/xenstore/xenstored_watch.c | 16 ++---- 3 files changed, 45 insertions(+), 66 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_cor= e.c index ea5a1a9cce..ec20bc042d 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1210,42 +1210,6 @@ void send_ack(struct connection *conn, enum xsd_sock= msg_type type) send_reply(conn, type, "OK", sizeof("OK")); } =20 -static bool valid_chars(const char *node) -{ - /* Nodes can have lots of crap. */ - return (strspn(node,=20 - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-/_@") =3D=3D strlen(node)); -} - -bool is_valid_nodename(const struct connection *conn, const char *node, - bool allow_special) -{ - int local_off =3D 0; - unsigned int domid; - - /* Must start in / or - if special nodes are allowed - in @. */ - if (!strstarts(node, "/") && (!allow_special || !strstarts(node, "@"))) - return false; - - /* Cannot end in / (unless it's just "/"). */ - if (strends(node, "/") && !streq(node, "/")) - return false; - - /* No double //. */ - if (strstr(node, "//")) - return false; - - if (sscanf(node, "/local/domain/%5u/%n", &domid, &local_off) !=3D 1) - local_off =3D 0; - - if (domain_max_chk(conn, ACC_PATHLEN, strlen(node) - local_off)) - return false; - - return valid_chars(node); -} - /* We expect one arg in the input: return NULL otherwise. * The payload must contain exactly one nul, at the end. */ @@ -1279,16 +1243,46 @@ static char *perms_to_strings(const void *ctx, cons= t struct node_perms *perms, } =20 const char *canonicalize(struct connection *conn, const void *ctx, - const char *node) + const char *node, bool allow_special) { - const char *prefix; + char *name; + int local_off =3D 0; + unsigned int domid; =20 - if (!node || (node[0] =3D=3D '/') || (node[0] =3D=3D '@')) - return node; - prefix =3D get_implicit_path(conn); - if (prefix) - return talloc_asprintf(ctx, "%s/%s", prefix, node); - return node; + errno =3D EINVAL; + if (!node) + return NULL; + + if (strspn(node, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-/_@") !=3D strlen(node)) + return NULL; + + if (node[0] =3D=3D '@' && !allow_special) + return NULL; + + if (node[0] !=3D '/' && node[0] !=3D '@') { + name =3D talloc_asprintf(ctx, "%s/%s", get_implicit_path(conn), + node); + if (!name) + return NULL; + } else + name =3D (char *)node; + + /* Cannot end in / (unless it's just "/"). */ + if (strends(name, "/") && !streq(name, "/")) + return NULL; + + /* No double //. */ + if (strstr(name, "//")) + return NULL; + + if (sscanf(name, "/local/domain/%5u/%n", &domid, &local_off) !=3D 1) + local_off =3D 0; + + if (domain_max_chk(conn, ACC_PATHLEN, strlen(name) - local_off)) + return NULL; + + return name; } =20 static struct node *get_node_canonicalized(struct connection *conn, @@ -1302,13 +1296,10 @@ static struct node *get_node_canonicalized(struct c= onnection *conn, =20 if (!canonical_name) canonical_name =3D &tmp_name; - *canonical_name =3D canonicalize(conn, ctx, name); + *canonical_name =3D canonicalize(conn, ctx, name, allow_special); if (!*canonical_name) return NULL; - if (!is_valid_nodename(conn, *canonical_name, allow_special)) { - errno =3D EINVAL; - return NULL; - } + return get_node(conn, ctx, *canonical_name, perm); } =20 diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_cor= e.h index f3a83efce8..ec1d6aac27 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -241,7 +241,7 @@ void send_ack(struct connection *conn, enum xsd_sockmsg= _type type); =20 /* Canonicalize this path if possible. */ const char *canonicalize(struct connection *conn, const void *ctx, - const char *node); + const char *node, bool allow_special); =20 /* Get access permissions. */ unsigned int perm_for_conn(struct connection *conn, @@ -294,10 +294,6 @@ struct connection *get_connection_by_id(unsigned int c= onn_id); void check_store(void); void corrupt(struct connection *conn, const char *fmt, ...); =20 -/* Is this a valid node name? */ -bool is_valid_nodename(const struct connection *conn, const char *node, - bool allow_special); - /* Get name of parent node. */ char *get_parent(const void *ctx, const char *node); =20 diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_wa= tch.c index 2662a3fa49..247d37e80f 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -167,17 +167,9 @@ static int check_watch_path(struct connection *conn, c= onst void *ctx, const char **path, bool *relative) { *relative =3D !strstarts(*path, "/") && !strstarts(*path, "@"); - *path =3D canonicalize(conn, ctx, *path); - if (!*path) - return errno; - if (!is_valid_nodename(conn, *path, true)) - goto inval; - - return 0; + *path =3D canonicalize(conn, ctx, *path, true); =20 - inval: - errno =3D EINVAL; - return errno; + return *path ? 0 : errno; } =20 static struct watch *add_watch(struct connection *conn, const char *path, @@ -261,9 +253,9 @@ int do_unwatch(const void *ctx, struct connection *conn, if (get_strings(in, vec, ARRAY_SIZE(vec)) !=3D ARRAY_SIZE(vec)) return EINVAL; =20 - node =3D canonicalize(conn, ctx, vec[0]); + node =3D canonicalize(conn, ctx, vec[0], true); if (!node) - return ENOMEM; + return errno; list_for_each_entry(watch, &conn->watches, list) { if (streq(watch->node, node) && streq(watch->token, vec[1])) { list_del(&watch->list); --=20 2.35.3