From nobody Mon Aug 4 19:46:38 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bwnB72Sgdz63RJ7; Mon, 04 Aug 2025 19:46:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bwnB62DJ3z4KGQ; Mon, 04 Aug 2025 19:46:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754336798; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7T7uPJuHSlKAsrn3aaGKJ5+24RV5aIocRY6UCSiWQ+E=; b=lKR5hop53djBj/WM+eFuxT44fziZBdl9nGGAPppPZwUhaMCC4g0+wtS2AcR4mRVw4bLw8S MxXquylp9z4cweO88FEvAMLPLTybPZII1wPghF5uHxnX2Jw4XnCckn/KyN+tfJpcyoh1aa HgUpNliXdRwEV8EvbYFqn6ZNjCU7Xfs6eyVebsKeAcbye2z5Qhv35CmEpimGUQO7Fol/0W iosBDEvcR8grYT9/c2fld9HREHC+z+dayRL8wh+LxG8CeWiT0owKjGOk0sYtabwrgPROXu RLVGUAcMwm5uvjeLSxlFR+uqMT6b7qTYLNb3UxrxsS7xAhrSUBIdp+VMMZ1/YA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754336798; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7T7uPJuHSlKAsrn3aaGKJ5+24RV5aIocRY6UCSiWQ+E=; b=Yt0b6iozre+fiK02JQVZuEp6WuD3RpYFOt7JQAm30HchcyGMnQdEGTSu+NISi3epSa89D4 x5P7LnkpPGP8T7G1WLoJkMc1V/1Pyu7KiNWlYDRV+wn5/IlLXRJL1JNFBzSdy0W3o/5xuC 9z/kRxPmUjGcvSe91csjQljjMWIMMv2yuIMuGNY2UlpSspUiqjtg6dXD+AyRXk3OBEwhku 1k3SXZnzGHYNEY9o35hB+mhHRDLOik2oSG953Mmo6S3y5lZDcY1pqX6w98Yz3U+iovt4l/ iIrpJNT7Ukub9rVJxI3elEAzbvEVwTFL/e7Wh1t6T9HfNvGfq26R4LPkKa9lUQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1754336798; a=rsa-sha256; cv=none; b=jEhvN2EDnUfn0w1XhheeiA+eD/dbknx1+bfKSKGQTU08RFCxtH5+anNkbSyDT42zqDMjZ9 ZFDyPIRlAIDJ5vU+gOQ7x3FAbESVs/smvexjKlbwmcCmEA2zimiRoCPJ0KBtWF4cRuchB8 RERIlETk2hUPONyv+h7Q5X5IOsmTw4019uKB+8TZod/A9K2yoQcwpU2VB6T9JAZfBURag8 XRhqk3Rhb7nX0d866/Gw7rZiTneMUQEgwjFiC+eHXbNMIn8oGdr3mLOOIc8+jJt5260cRn iPaeKl+KVSKwsqDE2RxU9Ak+iBH/0flXuySEfuhIR0v1J0UhrBAkXhWLf02y0A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bwnB61kM5z12lg; Mon, 04 Aug 2025 19:46:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 574JkctI098752; Mon, 4 Aug 2025 19:46:38 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 574Jkc3Q098749; Mon, 4 Aug 2025 19:46:38 GMT (envelope-from git) Date: Mon, 4 Aug 2025 19:46:38 GMT Message-Id: <202508041946.574Jkc3Q098749@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: e01fe14c9aac - main - ctld: Make config file parsing exception safe List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e01fe14c9aac95b1daec877af1729545b6d1b147 Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=e01fe14c9aac95b1daec877af1729545b6d1b147 commit e01fe14c9aac95b1daec877af1729545b6d1b147 Author: John Baldwin AuthorDate: 2025-08-04 19:38:06 +0000 Commit: John Baldwin CommitDate: 2025-08-04 19:38:06 +0000 ctld: Make config file parsing exception safe Split parse_conf in half keeping yyparse_conf as C-only function in parse.y. parse_conf uses freebsd::FILE_up to ensure that the config file is always closed. Both parse_conf and uclparse_conf catch any exceptions thrown during parsing. This is in preparation for using C++ objects allocated with new for various data structures. Note that this treats memory allocation failures from new as parsing errors rather than ctld exiting entirely as it currently does if malloc or calloc fail. Sponsored by: Chelsio Communications Pull Request: https://github.com/freebsd/freebsd-src/pull/1794 --- usr.sbin/ctld/Makefile | 1 + usr.sbin/ctld/conf.cc | 25 +++++++++++++++++++++++++ usr.sbin/ctld/conf.h | 2 +- usr.sbin/ctld/ctld.hh | 1 + usr.sbin/ctld/parse.y | 10 ++-------- usr.sbin/ctld/uclparse.cc | 12 +++++++++++- 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile index 314554a99b56..67f89dca2757 100644 --- a/usr.sbin/ctld/Makefile +++ b/usr.sbin/ctld/Makefile @@ -12,6 +12,7 @@ CFLAGS+= -I${SRCTOP}/sys CFLAGS+= -I${SRCTOP}/sys/cam/ctl CFLAGS+= -I${SRCTOP}/sys/dev/iscsi CFLAGS+= -I${SRCTOP}/lib/libiscsiutil +CFLAGS+= -I${SRCTOP}/lib/libutil++ #CFLAGS+= -DICL_KERNEL_PROXY NO_WCAST_ALIGN= CXXWARNFLAGS.gcc= -Wno-shadow diff --git a/usr.sbin/ctld/conf.cc b/usr.sbin/ctld/conf.cc index 1750f7ab96c6..c9e1a2fb9968 100644 --- a/usr.sbin/ctld/conf.cc +++ b/usr.sbin/ctld/conf.cc @@ -39,6 +39,8 @@ #include #include +#include + #include "conf.h" #include "ctld.hh" @@ -757,3 +759,26 @@ target_start_lun(u_int id) lun = new_lun; return (true); } + +bool +parse_conf(const char *path) +{ + freebsd::FILE_up fp(fopen(path, "r")); + if (fp == nullptr) { + log_warn("unable to open configuration file %s", path); + return (false); + } + + bool parsed; + try { + parsed = yyparse_conf(fp.get()); + } catch (std::bad_alloc) { + log_warnx("failed to allocate memory parsing %s", path); + return (false); + } catch (...) { + log_warnx("unknown exception parsing %s", path); + return (false); + } + + return (parsed); +} diff --git a/usr.sbin/ctld/conf.h b/usr.sbin/ctld/conf.h index 6e287ce70436..b13fd80e9fe5 100644 --- a/usr.sbin/ctld/conf.h +++ b/usr.sbin/ctld/conf.h @@ -97,7 +97,7 @@ bool lun_set_path(const char *value); bool lun_set_serial(const char *value); bool lun_set_size(uint64_t value); -bool parse_conf(const char *path); +bool yyparse_conf(FILE *fp); __END_DECLS diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh index b1757f98ac81..61e453d8dc23 100644 --- a/usr.sbin/ctld/ctld.hh +++ b/usr.sbin/ctld/ctld.hh @@ -247,6 +247,7 @@ struct ctld_connection { extern int ctl_fd; +bool parse_conf(const char *path); bool uclparse_conf(const char *path); struct conf *conf_new(void); diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index c0146262e895..432183ed794c 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -890,20 +890,14 @@ yyerror(const char *str) } bool -parse_conf(const char *path) +yyparse_conf(FILE *fp) { int error; - yyin = fopen(path, "r"); - if (yyin == NULL) { - log_warn("unable to open configuration file %s", path); - return (false); - } - + yyin = fp; lineno = 1; yyrestart(yyin); error = yyparse(); - fclose(yyin); return (error == 0); } diff --git a/usr.sbin/ctld/uclparse.cc b/usr.sbin/ctld/uclparse.cc index 8788e1cbb981..4c7bbb43d75d 100644 --- a/usr.sbin/ctld/uclparse.cc +++ b/usr.sbin/ctld/uclparse.cc @@ -41,6 +41,8 @@ #include #include +#include + #include "conf.h" #include "ctld.hh" @@ -1113,7 +1115,15 @@ uclparse_conf(const char *path) } top = ucl_parser_get_object(parser); - parsed = uclparse_toplevel(top); + try { + parsed = uclparse_toplevel(top); + } catch (std::bad_alloc) { + log_warnx("failed to allocate memory parsing %s", path); + parsed = false; + } catch (...) { + log_warnx("unknown exception parsing %s", path); + parsed = false; + } ucl_object_unref(top); ucl_parser_free(parser);