From patchwork Wed Jan 20 19:26:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Heinrich Kiwi X-Patchwork-Id: 1429404 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DLbBl0KYWz9sCq for ; Thu, 21 Jan 2021 06:27:27 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=lFiVhcQc; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4DLbBk1xqNzDqbc for ; Thu, 21 Jan 2021 06:27:26 +1100 (AEDT) X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=linux.vnet.ibm.com (client-ip=148.163.158.5; helo=mx0a-001b2d01.pphosted.com; envelope-from=klaus@linux.vnet.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=lFiVhcQc; dkim-atps=neutral Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4DLbBY3Fz7zDqCY for ; Thu, 21 Jan 2021 06:27:17 +1100 (AEDT) Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 10KJ2Tu6125682; Wed, 20 Jan 2021 14:27:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : in-reply-to : references; s=pp1; bh=SevNgf649lMVuaND84oBUcfgtXnC7NFF32dDZfg48zA=; b=lFiVhcQcWTnQTh9dHXHaW9hLTHa1P5fFhzeXy3X3ZcXJhP3mD8zEmqybMAZeeNlYmdLP 2pmwU6wlFD8FgCD7L9Q8mdD73xBdZifB55oGv0JIVO1yRkgWTfV2S/Sj4PXq/gBngObE 5p1cgWeUt+JZDrvCQROxC+nbiGhM4+xSRGzgydWN7pzwRpUXI2XBaJjC8J5PxrR2fFXg 0OFpoz3xNDyENje6TFCzEY2E4ALg/gIM2XS2uXbtr/yWcLd5ib6HRfVlWrdS2X387onI tIMMgIpkAEoL6jp1eSYogOLQ3f/fVkmaUNpFKGSl1MaFVblHi7Sc3EOyNBv2DySyeMf8 OQ== Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0b-001b2d01.pphosted.com with ESMTP id 366t1rh5ms-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 Jan 2021 14:27:14 -0500 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 10KJR62m031048; Wed, 20 Jan 2021 19:27:13 GMT Received: from b01cxnp22035.gho.pok.ibm.com (b01cxnp22035.gho.pok.ibm.com [9.57.198.25]) by ppma02wdc.us.ibm.com with ESMTP id 3668rv6jxv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 Jan 2021 19:27:12 +0000 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp22035.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 10KJRCGD30343426 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 20 Jan 2021 19:27:12 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EC982112062; Wed, 20 Jan 2021 19:27:11 +0000 (GMT) Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3401F112061; Wed, 20 Jan 2021 19:27:07 +0000 (GMT) Received: from klaus-virtual-ubuntu.aus.stglabs.ibm.com (unknown [9.80.220.85]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP; Wed, 20 Jan 2021 19:27:06 +0000 (GMT) From: Klaus Heinrich Kiwi To: petitboot@lists.ozlabs.org Subject: [PATCH v3 1/2] discover: Allow for empty paths Date: Wed, 20 Jan 2021 16:26:57 -0300 Message-Id: <20210120192658.27930-1-klaus@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <35917519-878b-56d3-c995-c97e01f15d3a@linux.vnet.ibm.com> References: <35917519-878b-56d3-c995-c97e01f15d3a@linux.vnet.ibm.com> In-Reply-To: References: X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343, 18.0.737 definitions=2021-01-20_10:2021-01-20, 2021-01-20 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 adultscore=0 priorityscore=1501 lowpriorityscore=0 mlxlogscore=999 spamscore=0 impostorscore=0 malwarescore=0 clxscore=1015 suspectscore=0 phishscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101200108 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Some grub tests involve a (device)/path structure, where it is actually legal to have an empty path. Adjust join_path() and dependant functions to allow for empty pathnames. Signed-off-by: Klaus Heinrich Kiwi --- discover/grub2/builtins.c | 10 ++++++---- discover/grub2/grub2.c | 29 +++++++++++++++++++---------- discover/paths.c | 16 +++++++++++----- discover/paths.h | 6 +++--- test/parser/test-grub2-devpath.c | 28 +++++++++++++++++++--------- test/parser/utils.c | 2 +- 6 files changed, 59 insertions(+), 32 deletions(-) diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index ab1407a..4b94f99 100644 --- a/discover/grub2/builtins.c +++ b/discover/grub2/builtins.c @@ -247,13 +247,13 @@ static bool builtin_test_op_file(struct grub2_script *script, char op, switch (op) { case 's': /* -s: return true if file exists and has non-zero size */ - result = statbuf.st_size > 0; + result = !path ? false : statbuf.st_size > 0; break; case 'f': /* -f: return true if file exists and is not a directory. This is * different than the behavior of "test", but is what GRUB does * (though note as above that we follow symlinks unlike GRUB). */ - result = !S_ISDIR(statbuf.st_mode); + result = !path ? false : !S_ISDIR(statbuf.st_mode); break; default: result = false; @@ -284,7 +284,7 @@ static bool builtin_test_op_dir(struct grub2_script *script, char op, if (rc) return false; - return S_ISDIR(statbuf.st_mode); + return !path ? false : S_ISDIR(statbuf.st_mode); } static bool builtin_test_op(struct grub2_script *script, @@ -419,7 +419,9 @@ static int builtin_source(struct grub2_script *script, return false; rc = parse_to_device_path(script, argv[1], &dev, &path); - if (rc) + + /* We need to have a valid (non-empty) path for sources */ + if (rc || !path) return false; rc = parser_request_file(script->ctx, dev, path, &buf, &len); diff --git a/discover/grub2/grub2.c b/discover/grub2/grub2.c index b176ce2..7fb6f62 100644 --- a/discover/grub2/grub2.c +++ b/discover/grub2/grub2.c @@ -70,7 +70,8 @@ struct resource *create_grub2_resource(struct grub2_script *script, } file = grub2_parse_file(script, path); - if (!file) + /* We need a non-empty path for resources */ + if (!file || !file->path) return NULL; res = talloc(opt, struct resource); @@ -118,7 +119,6 @@ struct grub2_file *grub2_parse_file(struct grub2_script *script, const char *str) { struct grub2_file *file; - size_t dev_len; char *pos; if (!str) @@ -130,24 +130,33 @@ struct grub2_file *grub2_parse_file(struct grub2_script *script, /* just a path - no device, return path as-is */ file->path = talloc_strdup(file, str); - } else { + } + else { /* device plus path - split into components */ - pos = strchr(str, ')'); - /* no closing bracket, or zero-length path? */ - if (!pos || *(pos+1) == '\0') { + /* no closing bracket is not legal */ + if (!pos) { talloc_free(file); return NULL; } - file->path = talloc_strdup(file, pos + 1); + /* path is non-empty - copy it (otherwise keep it + * NULL as it should be legal) */ + if ( *(pos+1) != '\0' ) + file->path = talloc_strdup(file, pos + 1); - dev_len = pos - str - 1; - if (dev_len) - file->dev = talloc_strndup(file, str + 1, dev_len); + /* same as above for device string */ + if ( pos > (str+1) ) + file->dev = talloc_strndup(file, str + 1, + (size_t) (pos - str - 1)); } + /* if both dev and path are empty, this is probably an error */ + if (!file->dev && !file->path) { + talloc_free(file); + return NULL; + } return file; } diff --git a/discover/paths.c b/discover/paths.c index 16fdd59..3c43bf6 100644 --- a/discover/paths.c +++ b/discover/paths.c @@ -51,13 +51,19 @@ const char *mount_base(void) char *join_paths(void *alloc_ctx, const char *a, const char *b) { char *full_path; + size_t a_len = a ? strlen(a) : 0; + size_t b_len = b ? strlen(b) : 0; - full_path = talloc_array(alloc_ctx, char, strlen(a) + strlen(b) + 2); + full_path = talloc_zero_array(alloc_ctx, char, a_len + b_len + 2); - strcpy(full_path, a); - if (b[0] != '/' && a[strlen(a) - 1] != '/') - strcat(full_path, "/"); - strcat(full_path, b); + if (a_len) + strcpy(full_path, a); + + if (b_len) { + if (a_len && a[a_len - 1] != '/' && b[0] != '/') + strcat(full_path, "/"); + strcat(full_path, b); + } return full_path; } diff --git a/discover/paths.h b/discover/paths.h index 67fe8a3..6694877 100644 --- a/discover/paths.h +++ b/discover/paths.h @@ -6,10 +6,10 @@ #include /** - * Utility function for joining two paths. Adds a / between a and b if - * required. + * Utility function for joining two paths. Allows either or + * both paths to be NULL. Adds a / between a and b if required. * - * Returns a newly-allocated string. + * Returns a newly-allocated string (empty if both paths NULL) */ char *join_paths(void *alloc_ctx, const char *a, const char *b); diff --git a/test/parser/test-grub2-devpath.c b/test/parser/test-grub2-devpath.c index d1d00f1..2571078 100644 --- a/test/parser/test-grub2-devpath.c +++ b/test/parser/test-grub2-devpath.c @@ -9,35 +9,40 @@ menuentry a { linux /vmlinux } +# local, with an empty device-string +menuentry b { + linux ()/vmlinux +} + # local, specified by root env var root=00000000-0000-0000-0000-000000000001 -menuentry b { +menuentry c { linux /vmlinux } # remote, specified by root env var root=00000000-0000-0000-0000-000000000002 -menuentry c { +menuentry d { linux /vmlinux } # local, full dev+path spec -menuentry d { +menuentry e { linux (00000000-0000-0000-0000-000000000001)/vmlinux } # remote, full dev+path spec -menuentry e { +menuentry f { linux (00000000-0000-0000-0000-000000000002)/vmlinux } # invalid: incomplete dev+path spec -menuentry f { +menuentry g { linux (00000000-0000-0000-0000-000000000001 } # invalid: no path -menuentry g { +menuentry h { linux (00000000-0000-0000-0000-000000000001) } @@ -64,7 +69,7 @@ void run_test(struct parser_test *test) test_run_parser(test, "grub2"); - check_boot_option_count(ctx, 5); + check_boot_option_count(ctx, 6); opt = get_boot_option(ctx, 0); check_name(opt, "a"); @@ -76,13 +81,18 @@ void run_test(struct parser_test *test) opt = get_boot_option(ctx, 2); check_name(opt, "c"); - check_resolved_local_resource(opt->boot_image, dev2, "/vmlinux"); + check_resolved_local_resource(opt->boot_image, dev1, "/vmlinux"); opt = get_boot_option(ctx, 3); check_name(opt, "d"); - check_resolved_local_resource(opt->boot_image, dev1, "/vmlinux"); + check_resolved_local_resource(opt->boot_image, dev2, "/vmlinux"); opt = get_boot_option(ctx, 4); check_name(opt, "e"); + check_resolved_local_resource(opt->boot_image, dev1, "/vmlinux"); + + opt = get_boot_option(ctx, 5); + check_name(opt, "f"); check_resolved_local_resource(opt->boot_image, dev2, "/vmlinux"); + } diff --git a/test/parser/utils.c b/test/parser/utils.c index d8499a4..2705b9a 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -257,7 +257,7 @@ int parser_stat_path(struct discover_context *ctx, list_for_each_entry(&test->files, file, list) { if (file->dev != dev) continue; - if (strcmp(file->name, path)) + if (path && strcmp(file->name, path)) continue; statbuf->st_size = (off_t)file->size;