Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uNUDh-0032Yv-5S for pgsql-bugs@arkaria.postgresql.org; Fri, 06 Jun 2025 10:22:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uNUDd-007i2l-N9 for pgsql-bugs@arkaria.postgresql.org; Fri, 06 Jun 2025 10:22:38 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uNUDd-007i2d-D8 for pgsql-bugs@lists.postgresql.org; Fri, 06 Jun 2025 10:22:38 +0000 Received: from udcm-wwu1.uni-muenster.de ([128.176.118.7]) by magus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uNUDb-000Wpg-2p for pgsql-bugs@lists.postgresql.org; Fri, 06 Jun 2025 10:22:37 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=uni-muenster.de; i=@uni-muenster.de; q=dns/txt; s=uniout; t=1749205356; x=1780741356; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=kzGi+xD+8aGuy8XvfzIcCYWKgJXLWHvQSUYJN5/QSHQ=; b=HZWf0ztDUNEYshZhtqO2J39+rUQs8jT0pc6tOhGtzIEoMwomsy8op6dp ZFXpcG4ZfyNhaGCTiUMr2NXu7RC81Dnruvrw5R6+l7tooxz18Ri0shyXD gIpM7PDpeYkEcU8ojyehlJQXfv1Zmt4/lKXbMloaRt52gnIKcX6we6xtY zh225K9D219nxd2cxRAwr6v2NCsdiz25HrNMP6ZdNdmTWdpJ9uoPLVZFX Aj9i8WysIm/b2Ta5Twh+nyfNmtYE1QCuLIM6z84gcZzeeHyFEHvdpb201 6UUHz/VA4Wfp5nEJH7wHQIwMi8Wvy5731nNjRzao9/QgJmyMrvvrwmki5 w==; X-CSE-ConnectionGUID: VAhQ+RHOTpqWLZroF512dg== X-CSE-MsgGUID: r7v9GXJhRNybFpjL747yFg== X-IronPort-AV: E=Sophos;i="6.16,214,1744063200"; d="scan'208";a="368556161" Received: from secmail.uni-muenster.de ([128.176.118.4]) by UDCM-RELAY1.UNI-MUENSTER.DE with ESMTP; 06 Jun 2025 12:22:35 +0200 Received: from [192.168.178.27] (dynamic-002-243-022-207.2.243.pool.telefonica.de [2.243.22.207]) by SECMAIL.UNI-MUENSTER.DE (Postfix) with ESMTPSA id 72A5820ADF02; Fri, 6 Jun 2025 12:22:32 +0200 (CEST) Message-ID: <31f3480e-cd7d-4021-b392-87922572cc37@uni-muenster.de> Date: Fri, 6 Jun 2025 12:22:30 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: BUG #18943: Return value of a function 'xmlBufferCreate' is dereferenced at xpath.c:177 without checking for NUL To: Michael Paquier Cc: Tom Lane , pgsql-bugs@lists.postgresql.org, maralist86@mail.ru References: <18943-2f2a04ab03904598@postgresql.org> <861593.1748970933@sss.pgh.pa.us> Content-Language: en-US, de-DE From: Jim Jones In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 06.06.25 07:54, Michael Paquier wrote: > On Thu, Jun 05, 2025 at 04:15:19PM +0200, Jim Jones wrote: >> On 05.06.25 11:47, Jim Jones wrote: >>> Taking a further look at xml.c I am wondering if other functions might >>> also need some attention in this regard: >>> >>> * xmlTextWriterStartElement [3] >>> * xmlTextWriterWriteAttribute [4] >>> * xmlTextWriterWriteRaw [5] >>> * xmlTextWriterEndAttribute [6] > > It seems to me that you mean xmlTextWriterEndElement() and not > xmlTextWriterEndAttribute() for the last one. +1 The return value of the xmlTextWriter* functions are now properly evaluated. > - xmlBufferWriteChar, which could fail on OOM if they need to grow > memory, but let's leave these as they are; I suspect that > xmlBufferCreate() would fail anyway. > I also think we're safe in this case. xmlBufferAdd() can return XML_ERR_ARGUMENT if the xmlBuffer* or the xmlChar* are NULL, which cannot happen in this part of the code. XML_ERR_NO_MEMORY is also unlikely to happen, since xmlBufferWriteChar() and xmlBufferWriteCHAR() call xmlBufferAdd() with a -1 length. >>> We're assuming they never fail. Perhaps something like this? >>>  ... >>>  nbytes = xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name); >>>  if (nbytes == -1 || xmlerrcxt->err_occurred) >>>     xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, >>>                         "could not allocate xmlTextWriterStartElement"); > > Oh. These can return XML_ERR_NO_MEMORY as well, with more error > patterns.. +1 > >> There is also a further xmlXPathCastNodeToString() call in xml.c at >> xml_xmlnodetoxmltype() - it calls xmlNodeGetContent() and it can return >> NULL. > > And it's documented as a routine that returns an allocated string, so > yes, we would miss allocation failures but we should not. I think > that we should move the call of xmlXPathCastNodeToString() inside the > PG_TRY block and rely on the xmlerrcxt given by the caller to log an > error if an allocation fails, marking xmlChar *str as volatile to free > it in the finally block if required. +1 > >> The function pgxmlNodeSetToText() also calls xmlXPathCastNodeToString(), >> but apparently xmlBufferAdd() can handle NULL values.[1] > > Yeah, the patch I have posted upthread gets that done better. > > What do you think? Going through xml.c once again, I stumbled upon xmlAddChildList(), which returns the last child or NULL in case of error. [1] ... xmlAddChildList(root, content_nodes); So, perhaps this? if (xmlAddChildList(root, content_nodes) == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not add content nodes to root element"); -- Jim 1- https://github.com/GNOME/libxml2/blob/c6206c93872fc91d98fbc61215c5618b629bf915/tree.c#L2976