From patchwork Wed Apr 30 09:13:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 751 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id C69C6360072 for ; Wed, 30 Apr 2014 02:12:44 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14307373) id 70A39414F2A40; Wed, 30 Apr 2014 02:12:44 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id 4CA03414FDC54 for ; Wed, 30 Apr 2014 02:12:44 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id :mime-version:content-type; q=dns; s=default; b=C58546A6tDPSe8QK rZnJ+1b8Z6zw6XExwRJYXWaIasXXxbqxP3cI1m8oEinwZ1adnMkooyJuyzC32Jcu lXRB3G6ccGUmOBnqZPmf/roluvkJ02zazf2N5DnuSbN7YL67fCVJjtYT2aGQZ8c1 ik+ukkD1KvjZ2nbOl89RKWJP4pE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:cc:subject:message-id :mime-version:content-type; s=default; bh=YFCBXiX+vy0DNVsXC2miEB pZAZ4=; b=xxtKhtMxaZg4UsYWye6M102lR0gudJvRIwS5SbvAscBuDMj9uaBg2x EVMNkombt27V1Oz0vLRp6sTI6jrTtEPr3H8uxAP0WOFTRjqzNeSm/5OwniLeZ58n pEntTiVr2CEE5kPugKI6AnKsWXEvQVCES9SgqoaNNga+wibK3S3lg= Received: (qmail 12815 invoked by alias); 30 Apr 2014 09:12:42 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 12797 invoked by uid 89); 30 Apr 2014 09:12:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Date: Wed, 30 Apr 2014 14:43:30 +0530 From: Siddhesh Poyarekar To: libc-alpha@sourceware.org Cc: m.weiser@science-computing.de Subject: [PATCH] Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878) Message-ID: <20140430091330.GV10922@spoyarek.pnq.redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.22.1-rc1 (2013-10-16) X-DH-Original-To: glibc@patchwork.siddhesh.in The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL (with errno as ERANGE) when the supplied buffer does not have sufficient space for the result. This is wrong, because the canonical way to indicate insufficient buffer is to set the errno to ERANGE and the status to NSS_STATUS_TRYAGAIN, as is used by all other modules. This fixes nscd behaviour when the nss_ldap module returns NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to fit into the supplied buffer. A reproducer is present on the bz #16878, which I used to verify that the problem is fixed. Many thanks to Michael Weiser for the reproducer and analysis. Siddhesh [BZ #16878] * nscd/netgroupcache.c (addgetnetgrentX): Look for NSS_STATUS_TRYAGAIN to indicate insufficient buffer space. * nscd/nss_files/files-netgrp.c (_nss_netgroup_parseline): Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer space. --- nscd/netgroupcache.c | 14 ++++++++------ nss/nss_files/files-netgrp.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c index b3d40e9..edab174 100644 --- a/nscd/netgroupcache.c +++ b/nscd/netgroupcache.c @@ -197,11 +197,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, int e; status = getfct.f (&data, buffer + buffilled, buflen - buffilled - req->key_len, &e); - if (status == NSS_STATUS_RETURN - || status == NSS_STATUS_NOTFOUND) - /* This was either the last one for this group or the - group was empty. Look at next group if available. */ - break; if (status == NSS_STATUS_SUCCESS) { if (data.type == triple_val) @@ -320,11 +315,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, } } } - else if (status == NSS_STATUS_UNAVAIL && e == ERANGE) + else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE) { buflen *= 2; buffer = xrealloc (buffer, buflen); } + else if (status == NSS_STATUS_RETURN + || status == NSS_STATUS_NOTFOUND + || status == NSS_STATUS_UNAVAIL) + /* This was either the last one for this group or the + group was empty or the NSS module had an internal + failure. Look at next group if available. */ + break; } enum nss_status (*endfct) (struct __netgrent *); diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c index 34eae4c..bc0b367 100644 --- a/nss/nss_files/files-netgrp.c +++ b/nss/nss_files/files-netgrp.c @@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result, if (cp - host > buflen) { *errnop = ERANGE; - status = NSS_STATUS_UNAVAIL; + status = NSS_STATUS_TRYAGAIN; } else {