From patchwork Thu Jan 21 18:44:36 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: 1430016 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 4DMBCH3zLFz9rx8 for ; Fri, 22 Jan 2021 05:44:59 +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=jn92tgjb; 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 4DMBCF73D7zDrRX for ; Fri, 22 Jan 2021 05:44:57 +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=jn92tgjb; 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 4DMBC33zsLzDqhn for ; Fri, 22 Jan 2021 05:44:46 +1100 (AEDT) Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 10LIfDAw102046; Thu, 21 Jan 2021 13:44:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id; s=pp1; bh=oOG7piT7bPm4mQRhINkfNdvTtIft3KHY4s1rguYw0bM=; b=jn92tgjbKoJohCAqbdNL9la653rOUvGZLe/aZOIkp+c65yyPsvvKbMoHMTATO9y28lTG mcB8SBRiZdpvA/XM94+X+bUATU29sFJPhlaAbSny+E7VteeOtMA2Ne5FEVAAcfh5/RS/ vs+tywUNrWWDlOn/6OIZ9MwoDrK9skgeMOORckfJU5wDnWVrq+PvtbzekeT29UABudE9 oBeHGYz2wrsbpJAnk7qGrdvoZxIhPl+8wr3LVVsEwBat7xLoBhfKmdYpGkskNdQiuQ8b 5HD6H0cg5BNRM+lxfIPzG2s2vzXoh+GUEX+3TMofcjtbdvX0MT/1rFVw7GI+fbB4o6Rv Fg== Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0b-001b2d01.pphosted.com with ESMTP id 367f3x02qp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 Jan 2021 13:44:43 -0500 Received: from pps.filterd (ppma05wdc.us.ibm.com [127.0.0.1]) by ppma05wdc.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 10LIibgC001233; Thu, 21 Jan 2021 18:44:43 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma05wdc.us.ibm.com with ESMTP id 3668nwe6wb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 21 Jan 2021 18:44:43 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 10LIigZv25493908 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 21 Jan 2021 18:44:42 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7D122BE053; Thu, 21 Jan 2021 18:44:42 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 85809BE04F; Thu, 21 Jan 2021 18:44:41 +0000 (GMT) Received: from klaus-virtual-ubuntu.aus.stglabs.ibm.com (unknown [9.80.239.98]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Thu, 21 Jan 2021 18:44:41 +0000 (GMT) From: Klaus Heinrich Kiwi To: petitboot@lists.ozlabs.org Subject: [PATCH v4 1/2] discover: Allow for empty paths Date: Thu, 21 Jan 2021 15:44:36 -0300 Message-Id: <20210121184437.5613-1-klaus@linux.vnet.ibm.com> X-Mailer: git-send-email 2.17.1 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343, 18.0.737 definitions=2021-01-21_09:2021-01-21, 2021-01-21 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 malwarescore=0 phishscore=0 spamscore=0 bulkscore=0 clxscore=1015 impostorscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101210093 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. Also add / modify a few more tests for this scenario. Signed-off-by: Klaus Heinrich Kiwi --- discover/grub2/builtins.c | 9 +++++---- discover/grub2/grub2.c | 17 ++++++++++++---- discover/paths.c | 16 ++++++++++----- discover/paths.h | 6 +++--- test/parser/test-grub2-devpath.c | 28 +++++++++++++++++--------- test/parser/test-grub2-test-file-ops.c | 19 +++++++++++++++++ test/parser/utils.c | 2 +- 7 files changed, 71 insertions(+), 26 deletions(-) diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index ab1407a..f32e8e5 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,8 @@ 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..9be94eb 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); @@ -135,19 +136,27 @@ struct grub2_file *grub2_parse_file(struct grub2_script *script, 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); } + /* 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/test-grub2-test-file-ops.c b/test/parser/test-grub2-test-file-ops.c index b614fc1..38214a1 100644 --- a/test/parser/test-grub2-test-file-ops.c +++ b/test/parser/test-grub2-test-file-ops.c @@ -13,6 +13,12 @@ fi if [ ! -f /empty_file -a $status = success ] then status=fail_f_3 fi +if [ -f "" -a $status = success ] +then status=fail_f_4 +fi +if [ -f / -a $status = success ] +then status=fail_f_5 +fi if [ -s /file_that_does_not_exist -a $status = success ] then status=fail_s_1 @@ -26,6 +32,12 @@ fi if [ ! -s /non_empty_file -a $status = success ] then status=fail_s_4 fi +if [ -s "" -a $status = success ] +then status=fail_s_5 +fi +if [ ! -s / -a $status = success ] +then status=fail_s_6 +fi if [ -d /file_that_does_not_exist -a $status = success ] then status=fail_d_1 @@ -36,6 +48,12 @@ fi if [ -d /empty_file -a $status = success ] then status=fail_d_3 fi +if [ -d "" -a $status = success ] +then status=fail_d_4 +fi +if [ ! -d / -a $status = success ] +then status=fail_d_5 +fi menuentry $status { linux /vmlinux @@ -50,6 +68,7 @@ void run_test(struct parser_test *test) ctx = test->ctx; test_read_conf_embedded(test, "/grub2/grub.cfg"); + test_add_dir(test, ctx->device, "/"); test_add_file_data(test, ctx->device, "/empty_file", "", 0); test_add_file_data(test, ctx->device, "/non_empty_file", "1", 1); test_add_dir(test, ctx->device, "/dir"); 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;