From patchwork Wed Jan 21 14:59:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos O'Donell X-Patchwork-Id: 431491 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 ozlabs.org (Postfix) with ESMTPS id 1F87A14017B for ; Thu, 22 Jan 2015 01:59:56 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; q=dns; s=default; b=jxs idwUVLSXdhleBkmNDg2TrmSHS2Yx90MphPA0odznNWf49eRdC71Nx8xjaA+Ko9l4 uaJ96WeYbLoYgG2g76KD84PfN2GTJM58PVH7fYb0h3EnJrkZM/VFk8GQSPDF7SSH jP+3nbj45ZbRAzflVB5T8+lYy3LS5fphczh90A4U= 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:message-id:date:from:mime-version:to:subject :content-type:content-transfer-encoding; s=default; bh=m1dPwLrxh d+c1zC664zj4Mu0J4I=; b=HoA4L0miDgTYMdathXval33ewBVdwgw3hS//yRT0h 8UGjIHrSNdX49SJsTm0FAOuGRX7yRuO3DrjoPiil1rTqvIP7bpmSUjtDr6Nia1e6 lC1QSh/Rxi/qWsenLqibj3LYd/uCCl/5s/ldQQiE1HlOQskKnx/8GcqjkQAsK0JC eA= Received: (qmail 1563 invoked by alias); 21 Jan 2015 14:59:50 -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 1542 invoked by uid 89); 21 Jan 2015 14:59:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Message-ID: <54BFBEDF.5020103@redhat.com> Date: Wed, 21 Jan 2015 09:59:43 -0500 From: "Carlos O'Donell" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: GNU C Library Subject: [COMMITTED] tst-getpw.c: Rewrite. The tst-getpw test iterates over 2000 UIDs to look for one valid one, and one invalid one to test the getpw function. The test should stop immediately after it finds one of each of the testable conditions and terminate with an appropriate exit code. On one of my test boxes the local configuration for NSS is slow enough (sssd over the network) that the test times out sporadically. With the rewrite we now test for: - EINVAL as expected for invalid input. - One UID that maps. - One UID that doesn't map. - Check for other errno values that we don't expect. This should make the test faster and more stable since there is bound to be a files-based UID that isn't used and can be used for the test (rather than going into the high-numbered UIDs). In the event the system is totally broken we only iterate over the range of 16-bit UIDs. Tested on x86_64. Cheers, Carlos. 2015-01-21 Carlos O'Donell * pwd/tst-getpw.c: Rewrite. diff --git a/pwd/tst-getpw.c b/pwd/tst-getpw.c index 059c9e0..e3e101b 100644 --- a/pwd/tst-getpw.c +++ b/pwd/tst-getpw.c @@ -15,28 +15,99 @@ License along with the GNU C Library; if not, see . */ +#include #include +#include +#include + +/* We want to test getpw by calling it with a uid that does + exist and one that doesn't exist. We track if we've met those + conditions and exit. We also track if we've failed due to lack + of memory. That constitutes all of the standard failure cases. */ +bool seen_hit; +bool seen_miss; +bool seen_oom; + +/* How many errors we've had while running the test. */ +int errors; static void check (uid_t uid) { + int ret; char buf[1024]; - (void) getpw (uid, buf); + ret = getpw (uid, buf); + + /* Successfully read a password line. */ + if (ret == 0 && !seen_hit) + { + printf ("PASS: Read a password line given a uid.\n"); + seen_hit = true; + } + + /* Failed to read a password line. Why? */ + if (ret == -1) + { + /* No entry? Technically the errno could be any number + of values including ESRCH, EBADP or EPERM depending + on the quality of the nss module that implements the + underlying lookup. It should be 0 for getpw.*/ + if (errno == 0 && !seen_miss) + { + printf ("PASS: Found an invalid uid.\n"); + seen_miss = true; + return; + } + + /* Out of memory? */ + if (errno == ENOMEM && !seen_oom) + { + printf ("FAIL: Failed with ENOMEM.\n"); + seen_oom = true; + errors++; + } + + /* We don't expect any other values for errno. */ + if (errno != ENOMEM && errno != 0) + errors++; + } } static int do_test (void) { + int ret; uid_t uid; - /* Just call it a different number of times the range should be - large enough to find some existing and some non existing uids. */ + /* Should return -1 and set errnot to EINVAL. */ + ret = getpw (0, NULL); + if (ret == -1 && errno == EINVAL) + { + printf ("PASS: NULL buffer returns -1 and sets errno to EINVAL.\n"); + } + else + { + printf ("FAIL: NULL buffer did not return -1 or set errno to EINVAL.\n"); + errors++; + } + + /* Look for one matching uid, one non-found uid and then stop. + Set an upper limit at the 16-bit UID mark; no need to go farther. */ + for (uid = 0; uid < ((uid_t) 65535); ++uid) + { + check (uid); + if (seen_miss && seen_hit) + break; + } + + if (!seen_hit) + printf ("FAIL: Did not read even one password line given a uid.\n"); - for (uid = 0; uid < 2000; ++uid) - check (uid); + if (!seen_miss) + printf ("FAIL: Did not find even one invalid uid.\n"); - return 0; + return errors; } #define TEST_FUNCTION do_test ()