Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJler-00084n-ML for pgsql-hackers@arkaria.postgresql.org; Sun, 13 Oct 2019 21:44:09 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iJlb5-00056K-94 for pgsql-hackers@arkaria.postgresql.org; Sun, 13 Oct 2019 21:40:15 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJlZ9-000555-0M for pgsql-hackers@lists.postgresql.org; Sun, 13 Oct 2019 21:38:15 +0000 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iJlZ5-00017w-TB for pgsql-hackers@postgresql.org; Sun, 13 Oct 2019 21:38:14 +0000 Received: by mail-wr1-x442.google.com with SMTP id r3so17395141wrj.6 for ; Sun, 13 Oct 2019 14:38:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=cOz4zXWbqJNcSl7BWR+RwdiEx9APWMRvbLQhWQMGr8A=; b=W1HvsDZhMPBZJC+MC/nYlshUPQQd89AvOg8v/qM+UNOdrSszmuI5qBRE1pJ/gXjrTh biyd333+sfUxAsDh8EC8rv8qD7WSxYb2J6akAsks9KQV5CaUQHF2aL8bZ7Vol5s14d90 4LzmUzFDtZ1t2C5nkC4Ai7tss1KLy1QUFyRyevi7ORJq8wlZT8UHCMbUET2A6akUKisg A/dwfBF6fHMCdXONRwNwgB+JmMw38wGcGMVLScONcwG8zgig68rct9alxoa83Gk5HT1P cJWSEMl5J+Ml4E+xtS9NhbEWwHhMC+n96Yc2AC0On7mDJSqb4bzkuE1oNNa0wTSU0R1w 0uUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=cOz4zXWbqJNcSl7BWR+RwdiEx9APWMRvbLQhWQMGr8A=; b=JiVJVYGQsTe07dYPJ9Ma/cFwUjFaSpa4vPlpN+frBLD3SayZpxmYANmSBOwZf5eoty EtZmwqtA/Ks6QuNR7xeAlYBXUH9zLdTCQG2OQ6hG3UGl8IjvzinGSGjOSvI0SqA5ZENq EuzB17Y/wpwHSysh1TmtT4xYePtCTiNvOxTNv0pIp1C1F6GHnCxxTilT060vtCZdstf7 vL5sma1fYkutX0JSQhr+5mn8bvKenJatm1DJnIWhs+pdM7evaZJzHKdWikpcXv9VEDIX hNQ7E9AWd6eJ5/abE0xNrp/o1BpHLjfyQEWvaBbBXPkBCKA5EvgCsK45wwWLWG2tz3YF pw5A== X-Gm-Message-State: APjAAAXXfYSEYaax4E4SSeVOOrEGMyM4s05STvcRa6GNM3DtdxNSpzwP k1TTBmPFLIUAtUa460fQiIrQOvD8IeWyFyJpk/5Tostgxes5qLNrsf9ySmcGsTZ2Q2gTl6xBMqo ClBSoCljfTRwWwILMNVst2cLdnworNZtmEmmEDv5VAJKMdEt/YQ6h1KhZnRjpfYfGmebhGpdhWo rB2z+tQAl2wY0= X-Google-Smtp-Source: APXvYqyw+AhiXO46bi9Opad3FYNq0Y3Cmsfw9jfwY6AAaPeQhBODW5tSlR0ugo67JI9G0jYsMnUEWw== X-Received: by 2002:adf:ba07:: with SMTP id o7mr24118560wrg.50.1571002690337; Sun, 13 Oct 2019 14:38:10 -0700 (PDT) Received: from localhost (ip-86-49-253-183.net.upcbroadband.cz. [86.49.253.183]) by smtp.gmail.com with ESMTPSA id 3sm17034276wmo.22.2019.10.13.14.38.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Oct 2019 14:38:09 -0700 (PDT) Date: Sun, 13 Oct 2019 23:38:08 +0200 From: Tomas Vondra To: pgsql-hackers@postgresql.org Cc: Teodor Sigaev Subject: Re: CREATE TEXT SEARCH DICTIONARY segfaulting on 9.6+ Message-ID: <20191013213808.wfhtvkqcvlvbdkmz@development> References: <20191013012610.2p2fp3zzpoav7jzf@development> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <20191013012610.2p2fp3zzpoav7jzf@development> User-Agent: NeoMutt/20180716 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk I spent a bit of time investigating this, and it seems the new code is somewhat too trusting when it comes to data from the affix/dict files. In this particular case, it boils down to this code in NISortDictionary: if (Conf->useFlagAliases) { for (i = 0; i < Conf->nspell; i++) { char *end; if (*Conf->Spell[i]->p.flag != '\0') { curaffix = strtol(Conf->Spell[i]->p.flag, &end, 10); if (Conf->Spell[i]->p.flag == end || errno == ERANGE) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid affix alias \"%s\"", Conf->Spell[i]->p.flag))); } ... Conf->Spell[i]->p.d.affix = curaffix; ... } ... } So it simply grabs whatever it finds in the dict file, parses it and then (later) we use it as index to access the AffixData array, even if the value is way out of bounds. For example in the example, hunspell_sample_long.affix contains about 10 affixes, but then we parse the hunspell_sample_num.dict file, and we stumble upon book/302,301,202,303 and we parse the flags as integers, and interpret them as indexes in the AffixData array. Clearly, 303 is waaaay out of bounds, triggering the segfault crash. So I think we need some sort of cross-check here. We certainly need to make NISortDictionary() check the affix value is within AffixData bounds, and error out when the index is non-sensical (maybe negative and/or exceeding nAffixData). Maybe there's a simple way to check if the affix/dict files match. The failing affix has FLAG num while with FLAG long it works just fine. But I'm not sure that's actually possible, because I don't see anything in hunspell_sample_num.dict that would allow us to decide that it expects "FLAG num" and not "FLAG long". Furthermore, we certainly can't rely on this - we still need to check the range. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services