diff mbox series

[RFC,v9,01/10] cpe-info: new make target

Message ID 20200616170341.45098-1-matthew.weber@rockwellcollins.com
State RFC
Headers show
Series [RFC,v9,01/10] cpe-info: new make target | expand

Commit Message

Matt Weber June 16, 2020, 5:03 p.m. UTC
Similar to make legal-info, produce a csv delimited file containing
all selected packages CPE identification.

By default, support the pkg infra defining a set of CPE_ID_* defaults
using the package name for the vendor and name as most CPE IDs seem
to align with that assumption. Plus initially, use the pkg version as
the CPE ID's version field.

Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
---
Changes

v9
 - Rebase

v8
 - Removed CVE patched list as this isn't implmented.

v4 -> v7
 - No change

v3
[Thomas P
 - Merged infra define CPE_ID_*  into this patch
 - Report all packages vs restricting to just allowing based on if
   the VENDOR was set (v2). This now represents Thomas P's original
   idea to report everything.  At first I felt I should restrict
   the reporting to those CPE IDs we had made sure were correct.
   Turns out we should have actually let the script handle fixing
   the CPEs and just make a complete design of this up front.

[Matt
 - Moved to using the _project on all vendors instead of just name

v2
[Thomas P
 - Moved comment on conditionals back to this patchset where
   the conditional is created vs later
---
 Makefile               | 17 ++++++++++++++++-
 package/pkg-generic.mk | 13 +++++++++++++
 package/pkg-utils.mk   |  8 ++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

Comments

Yann E. MORIN June 21, 2020, 8:45 a.m. UTC | #1
On 2020-06-16 12:03 -0500, Matt Weber spake thusly:
> Similar to make legal-info, produce a csv delimited file containing
> all selected packages CPE identification.
> 
> By default, support the pkg infra defining a set of CPE_ID_* defaults
> using the package name for the vendor and name as most CPE IDs seem
> to align with that assumption. Plus initially, use the pkg version as
> the CPE ID's version field.

So, as I understand it, the CPE info for host packages will also be
stored in the generated file, but it will be a partial list.

For example, if a host package has a Config.in option (e.g. aespipe,
with BR2_PACKAGE_HOST_AESPIPE=y), then it will be listed in PACKAGES,
and so will be present in the CPE manifest.

But on the other hand, a host package that has no Config.in option but
is oart of the dependency chain of a package (e.g. host-pkgconf) will
not be listed in PACKAGES, and thus will not appear in the manifest.

This is a bit awkward I think.

As far as I understand it, the CPE info is (mostly|only) usefull to
then query the CVE list applicable to that CPE.

As such, this is (mostly|only) relevant to the target packages, I would
think, no? Thus, host pakcages should be filtered out.

If we are however interested by the CPE info for host packages, probably
that should go to a separate manifest, like for the legal-info, no?

Also, see an issue, below...

> Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> ---
[--SNIP--]
> @@ -864,6 +865,19 @@ legal-info: legal-info-clean legal-info-prepare $(foreach p,$(PACKAGES),$(p)-all
>  		mv .legal-info.sha256 legal-info.sha256)
>  	@echo "Legal info produced in $(LEGAL_INFO_DIR)"
>  
> +.PHONY: cpe-info-clean
> +cpe-info-clean:
> +	@rm -f $(CPE_MANIFEST_CSV)

This must also be removed on 'make clean'.

> +.PHONY: cpe-info-prepare
> +cpe-info-prepare:
> +	@$(call MESSAGE,"Gathering CPE info")
> +	@$(call cpe-manifest,CPE ID,CVE PATCHED,PACKAGE,VERSION,SOURCE SITE)
> +
> +.PHONY: cpe-info
> +cpe-info: cpe-info-clean cpe-info-prepare $(foreach p,$(PACKAGES),$(p)-cpe-info)

I think this depednecy is incorrect. Indeed, you reallt want that
cpe-info-clean be run before cpe-info-prepare, so I think you'll need
these dependencies:

    cpe-info-prepare: cpe-info-clean
    cpe-info: cpe-info-prepare
    cpe-info: $(foreach p,$(filter-out host-%,$(PACKAGES)),$(p)-cpe-info)

(Yes, I see you modeled your dependencies on the legal-info ones, but I
think they are broken.)

[--SNIP--]
> diff --git a/package/pkg-utils.mk b/package/pkg-utils.mk
> index d88a14ab0f..9818eda12d 100644
> --- a/package/pkg-utils.mk
> +++ b/package/pkg-utils.mk
> @@ -223,3 +223,11 @@ legal-deps = \
>          $(filter-out $(if $(1:host-%=),host-%),\
>              $(call non-virtual-deps,\
>                  $($(call UPPERCASE,$(1))_FINAL_RECURSIVE_DEPENDENCIES))),$(p) [$($(call UPPERCASE,$(p))_LICENSE)])
> +
> +#
> +# cpe-info helper functions
> +#
> +
> +define cpe-manifest # cpe, pkg name, version, url
> +	echo '"$(1)","$(2)","$(3)","$(4)"' >>$(CPE_MANIFEST_CSV)
> +endef

If (and *if*) we need the CPE info for host packages, then we could
change this helper to redirect to the appropriate manifest, a bit like
is done for legal-info.

But I'm not sure we want it (at least not now).

Regards,
Yann E. MORIN.

> -- 
> 2.17.1
> 
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Matt Weber June 22, 2020, 11:44 a.m. UTC | #2
Yann,

On Sun, Jun 21, 2020 at 3:46 AM Yann E. MORIN <yann.morin.1998@free.fr> wrote:
>
> On 2020-06-16 12:03 -0500, Matt Weber spake thusly:
> > Similar to make legal-info, produce a csv delimited file containing
> > all selected packages CPE identification.
> >
> > By default, support the pkg infra defining a set of CPE_ID_* defaults
> > using the package name for the vendor and name as most CPE IDs seem
> > to align with that assumption. Plus initially, use the pkg version as
> > the CPE ID's version field.
>
> So, as I understand it, the CPE info for host packages will also be
> stored in the generated file, but it will be a partial list.
>
> For example, if a host package has a Config.in option (e.g. aespipe,
> with BR2_PACKAGE_HOST_AESPIPE=y), then it will be listed in PACKAGES,
> and so will be present in the CPE manifest.
>
> But on the other hand, a host package that has no Config.in option but
> is oart of the dependency chain of a package (e.g. host-pkgconf) will
> not be listed in PACKAGES, and thus will not appear in the manifest.
>
> This is a bit awkward I think.
>
> As far as I understand it, the CPE info is (mostly|only) usefull to
> then query the CVE list applicable to that CPE.
>
> As such, this is (mostly|only) relevant to the target packages, I would
> think, no? Thus, host pakcages should be filtered out.

Correct only target packages are really useful but I could see a host
package list also being something that long term would be a good
datapoint.  There are cases where those host packages could inflict
behavior on the target that could need a CVE tagged against them.
(Note, I saw the conclusion you had in "cpe-info: only report target
pkgs" . )

>
> If we are however interested by the CPE info for host packages, probably
> that should go to a separate manifest, like for the legal-info, no?
>

Agree.

> Also, see an issue, below...
>
> > Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>
> > ---
> [--SNIP--]
> > @@ -864,6 +865,19 @@ legal-info: legal-info-clean legal-info-prepare $(foreach p,$(PACKAGES),$(p)-all
> >               mv .legal-info.sha256 legal-info.sha256)
> >       @echo "Legal info produced in $(LEGAL_INFO_DIR)"
> >
> > +.PHONY: cpe-info-clean
> > +cpe-info-clean:
> > +     @rm -f $(CPE_MANIFEST_CSV)
>
> This must also be removed on 'make clean'.

Sure

>
> > +.PHONY: cpe-info-prepare
> > +cpe-info-prepare:
> > +     @$(call MESSAGE,"Gathering CPE info")
> > +     @$(call cpe-manifest,CPE ID,CVE PATCHED,PACKAGE,VERSION,SOURCE SITE)
> > +
> > +.PHONY: cpe-info
> > +cpe-info: cpe-info-clean cpe-info-prepare $(foreach p,$(PACKAGES),$(p)-cpe-info)
>
> I think this depednecy is incorrect. Indeed, you reallt want that
> cpe-info-clean be run before cpe-info-prepare, so I think you'll need
> these dependencies:
>
>     cpe-info-prepare: cpe-info-clean
>     cpe-info: cpe-info-prepare
>     cpe-info: $(foreach p,$(filter-out host-%,$(PACKAGES)),$(p)-cpe-info)
>
> (Yes, I see you modeled your dependencies on the legal-info ones, but I
> think they are broken.)
>

:-)  ah ok.

Thanks for the review!

Best regards,
Matt
Frank Hunleth June 22, 2020, 8:55 p.m. UTC | #3
Matt,

> > On 2020-06-16 12:03 -0500, Matt Weber spake thusly:
> > > Similar to make legal-info, produce a csv delimited file containing
> > > all selected packages CPE identification.
> > >
> > > By default, support the pkg infra defining a set of CPE_ID_* defaults
> > > using the package name for the vendor and name as most CPE IDs seem
> > > to align with that assumption. Plus initially, use the pkg version as
> > > the CPE ID's version field.

Sorry for the late comments. I only now saw your CPE patches. This is
really valuable work. One of my projects is being updated to provide
CycloneDX files (XML or JSON). At a high level, CycloneDX combines
information from legal-info, show-info, and cpe-info into one JSON or
XML-formatted file. https://cyclonedx.org/ has more information.

I am not an expert on this, so let me share comments that I received
when forwarding your patches to the people working on CycloneDX
integration:

> Having buildroot output to CycloneDX directly would be ideal. CycloneDX is being adopted by tool makers already so this is in alignment to what others are doing.
>
> CPE, SWID, and PURL are different formats in which software can be identified. CPE is deprecated by the NVD but will likely still be around for another few years. SWID contains a tagId which is used for identity, and the format provides elementary SBOM capabilities as well. PURL also performs identity but also includes location information so that packages can be resolved, which plays into provenance a bit.
>
> All three are valuable. Only CPE and SWID are supported by the NVD. However, every member in the OSS Coalition has, or will be adopting  PURL - so basically the entire development ecosystem is about to support it in a major way. Some SCA vendors already support it.
>
> Because all three can be used for identity, all three are valuable in the ‘known vulnerability’ use case as described here: https://cyclonedx.org/use-cases/#known-vulnerabilities

I am very thankful that you've started this work. Certainly having
accurate CPEs is a step in the right direction, IMHO.

Thanks,
Frank
Thomas Petazzoni June 25, 2020, 11 a.m. UTC | #4
Hello Matt,

On Tue, 16 Jun 2020 12:03:32 -0500
Matt Weber <matthew.weber@rockwellcollins.com> wrote:

> Similar to make legal-info, produce a csv delimited file containing
> all selected packages CPE identification.
> 
> By default, support the pkg infra defining a set of CPE_ID_* defaults
> using the package name for the vendor and name as most CPE IDs seem
> to align with that assumption. Plus initially, use the pkg version as
> the CPE ID's version field.
> 
> Signed-off-by: Matthew Weber <matthew.weber@rockwellcollins.com>

This patch really does two things:

 - Add some CPE_* variables into the package infrastructure

 - Add a cpe-info make target

These are two separate things, should be two separate patches. However,
see below.

> +.PHONY: cpe-info-clean
> +cpe-info-clean:
> +	@rm -f $(CPE_MANIFEST_CSV)
> +
> +.PHONY: cpe-info-prepare
> +cpe-info-prepare:
> +	@$(call MESSAGE,"Gathering CPE info")
> +	@$(call cpe-manifest,CPE ID,CVE PATCHED,PACKAGE,VERSION,SOURCE SITE)
> +
> +.PHONY: cpe-info
> +cpe-info: cpe-info-clean cpe-info-prepare $(foreach p,$(PACKAGES),$(p)-cpe-info)
> +	@echo "CPE info produced in $(CPE_MANIFEST_CSV)"

I don't think we need/want an additional make target. We have "make
show-info" already, it outputs a JSON blurb, which we can extend with
additional information from the packages.

> +$(2)_CPE_ID_VENDOR ?= $$($(2)_NAME)_project
> +$(2)_CPE_ID_NAME ?= $$($(2)_NAME)
> +$(2)_CPE_ID_VERSION ?= $$($(2)_VERSION)
> +$(2)_CPE_ID ?= $$($(2)_CPE_ID_VENDOR):$$($(2)_CPE_ID_NAME):$$($(2)_CPE_ID_VERSION)

These variables should be documented in the Buildroot manual.

I see you set some default values for those CPE_ID values, but I am
wondering if that's how we want to do this. Indeed a big question,
which was discussed in a thread earlier this year between Michael
Walle, Akshay Bhat and me is that how do we then distinguish packages
for which the CPE information in Buildroot has been verified and is
known to be correct, from packages that have the CPE information not
verified, and even further from packages that don't have any CPE
information because this specific package is not known in the NVD
database.

So I'd like to see a proposal that clarifies how we are going to handle
this. One way is to *not* have any default value for those CPE
variables, and add them to packages progressively, so that we know that
when the CPE information is there, it _has_ been verified.

It's not great because it means adding gazillions of CPE_ID information
in packages. But is there any other option ?

Best regards,

Thomas
Gregory CLEMENT July 1, 2020, 7:43 a.m. UTC | #5
Hello,

>> +$(2)_CPE_ID_VENDOR ?= $$($(2)_NAME)_project
>> +$(2)_CPE_ID_NAME ?= $$($(2)_NAME)
>> +$(2)_CPE_ID_VERSION ?= $$($(2)_VERSION)
>> +$(2)_CPE_ID ?= $$($(2)_CPE_ID_VENDOR):$$($(2)_CPE_ID_NAME):$$($(2)_CPE_ID_VERSION)
>
> These variables should be documented in the Buildroot manual.
>
> I see you set some default values for those CPE_ID values, but I am
> wondering if that's how we want to do this. Indeed a big question,
> which was discussed in a thread earlier this year between Michael
> Walle, Akshay Bhat and me is that how do we then distinguish packages
> for which the CPE information in Buildroot has been verified and is
> known to be correct, from packages that have the CPE information not
> verified, and even further from packages that don't have any CPE
> information because this specific package is not known in the NVD
> database.
>
> So I'd like to see a proposal that clarifies how we are going to handle
> this. One way is to *not* have any default value for those CPE
> variables, and add them to packages progressively, so that we know that
> when the CPE information is there, it _has_ been verified.
>
> It's not great because it means adding gazillions of CPE_ID information
> in packages. But is there any other option ?

I am working on a adding a tool allowing to check the cve status of a
given configuration. I am about to submit it. For now I base my check on
the buildroot package name as it is done in pkg-stat, but as you know
there are some mismatch. At a point there will be the need to use the
CPE information, so I have already had to think on how to manage it.

I already have to deal with failure when checking if a version was
affected by a CVE. And for this situation I choose to report that
failure instead of considering the package being affected or not by
default. The idea is to, later, be able to fix the failure but in the
meantime being aware of it.

For package name I would use a similar approach: if there is no CPE_ID
provided then try to use the package name but in this case report that
it has to be checked manually, while if there is a CPE_ID then use it as
a reliable name. So I am clearly in favor on the second option proposed
by Thomas. The ultimate goal is to have a CPE_ID information in each
package but in the meantime there is a path to achieve this.

Gregory

>
> Best regards,
>
> Thomas
> -- 
> Thomas Petazzoni, CTO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Thomas Petazzoni July 1, 2020, 11:57 a.m. UTC | #6
Hello,

On Wed, 01 Jul 2020 09:43:10 +0200
Gregory CLEMENT <gregory.clement@bootlin.com> wrote:

> > It's not great because it means adding gazillions of CPE_ID information
> > in packages. But is there any other option ?  
> 
> I am working on a adding a tool allowing to check the cve status of a
> given configuration. I am about to submit it. For now I base my check on
> the buildroot package name as it is done in pkg-stat, but as you know
> there are some mismatch. At a point there will be the need to use the
> CPE information, so I have already had to think on how to manage it.
> 
> I already have to deal with failure when checking if a version was
> affected by a CVE. And for this situation I choose to report that
> failure instead of considering the package being affected or not by
> default. The idea is to, later, be able to fix the failure but in the
> meantime being aware of it.
> 
> For package name I would use a similar approach: if there is no CPE_ID
> provided then try to use the package name but in this case report that
> it has to be checked manually, while if there is a CPE_ID then use it as
> a reliable name. So I am clearly in favor on the second option proposed
> by Thomas. The ultimate goal is to have a CPE_ID information in each
> package but in the meantime there is a path to achieve this.

This all looks sensible to me, so please go ahead and submit the
initial work you have, even without CPE ID support for now.

Thanks!

Thomas
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index ce1c08a6f6..3dcc47efa8 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@  nobuild_targets := source %-source \
 	clean distclean help show-targets graph-depends \
 	%-graph-depends %-show-depends %-show-version \
 	graph-build graph-size list-defconfigs \
-	savedefconfig update-defconfig printvars
+	savedefconfig update-defconfig printvars cpe-info %-cpe-info
 ifeq ($(MAKECMDGOALS),)
 BR_BUILDING = y
 else ifneq ($(filter-out $(nobuild_targets),$(MAKECMDGOALS)),)
@@ -222,6 +222,7 @@  LEGAL_MANIFEST_CSV_TARGET = $(LEGAL_INFO_DIR)/manifest.csv
 LEGAL_MANIFEST_CSV_HOST = $(LEGAL_INFO_DIR)/host-manifest.csv
 LEGAL_WARNINGS = $(LEGAL_INFO_DIR)/.warnings
 LEGAL_REPORT = $(LEGAL_INFO_DIR)/README
+CPE_MANIFEST_CSV = $(BASE_DIR)/cpe-manifest.csv
 
 BR2_CONFIG = $(CONFIG_DIR)/.config
 
@@ -864,6 +865,19 @@  legal-info: legal-info-clean legal-info-prepare $(foreach p,$(PACKAGES),$(p)-all
 		mv .legal-info.sha256 legal-info.sha256)
 	@echo "Legal info produced in $(LEGAL_INFO_DIR)"
 
+.PHONY: cpe-info-clean
+cpe-info-clean:
+	@rm -f $(CPE_MANIFEST_CSV)
+
+.PHONY: cpe-info-prepare
+cpe-info-prepare:
+	@$(call MESSAGE,"Gathering CPE info")
+	@$(call cpe-manifest,CPE ID,CVE PATCHED,PACKAGE,VERSION,SOURCE SITE)
+
+.PHONY: cpe-info
+cpe-info: cpe-info-clean cpe-info-prepare $(foreach p,$(PACKAGES),$(p)-cpe-info)
+	@echo "CPE info produced in $(CPE_MANIFEST_CSV)"
+
 .PHONY: show-targets
 show-targets:
 	@echo $(sort $(PACKAGES)) $(sort $(TARGETS_ROOTFS))
@@ -1145,6 +1159,7 @@  help:
 	@echo '  legal-info             - generate info about license compliance'
 	@echo '  show-info              - generate info about packages, as a JSON blurb'
 	@echo '  printvars              - dump internal variables selected with VARS=...'
+	@echo '  cpe-info               - generate info about security CPE identification'
 	@echo
 	@echo '  make V=0|1             - 0 => quiet build (default), 1 => verbose build'
 	@echo '  make O=dir             - Locate all output files in "dir", including .config'
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index f9385177ac..1408845613 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -971,6 +971,18 @@  else
 $(2)_KCONFIG_VAR = BR2_PACKAGE_$(2)
 endif
 
+$(2)_CPE_ID_VENDOR ?= $$($(2)_NAME)_project
+$(2)_CPE_ID_NAME ?= $$($(2)_NAME)
+$(2)_CPE_ID_VERSION ?= $$($(2)_VERSION)
+$(2)_CPE_ID ?= $$($(2)_CPE_ID_VENDOR):$$($(2)_CPE_ID_NAME):$$($(2)_CPE_ID_VERSION)
+
+$(1)-cpe-info: PKG=$(2)
+$(1)-cpe-info:
+ifneq ($$(call qstrip,$$($(2)_SOURCE)),)
+	@$$(call MESSAGE,"Collecting cpe info")
+	$(Q)$$(call cpe-manifest,$$($(2)_CPE_ID),$$($(2)_RAWNAME),$$($(2)_VERSION),$$($(2)_ACTUAL_SOURCE_SITE))
+endif # ifneq ($$(call qstrip,$$($(2)_SOURCE)),)
+
 # legal-info: declare dependencies and set values used later for the manifest
 ifneq ($$($(2)_LICENSE_FILES),)
 $(2)_MANIFEST_LICENSE_FILES = $$($(2)_LICENSE_FILES)
@@ -1116,6 +1128,7 @@  DL_TOOLS_DEPENDENCIES += $$(call extractor-system-dependency,$$($(2)_SOURCE))
 	$(1)-clean-for-reconfigure \
 	$(1)-clean-for-reinstall \
 	$(1)-configure \
+	$(1)-cpe-info \
 	$(1)-depends \
 	$(1)-dirclean \
 	$(1)-external-deps \
diff --git a/package/pkg-utils.mk b/package/pkg-utils.mk
index d88a14ab0f..9818eda12d 100644
--- a/package/pkg-utils.mk
+++ b/package/pkg-utils.mk
@@ -223,3 +223,11 @@  legal-deps = \
         $(filter-out $(if $(1:host-%=),host-%),\
             $(call non-virtual-deps,\
                 $($(call UPPERCASE,$(1))_FINAL_RECURSIVE_DEPENDENCIES))),$(p) [$($(call UPPERCASE,$(p))_LICENSE)])
+
+#
+# cpe-info helper functions
+#
+
+define cpe-manifest # cpe, pkg name, version, url
+	echo '"$(1)","$(2)","$(3)","$(4)"' >>$(CPE_MANIFEST_CSV)
+endef