Accepting request 699853 from Base:System

kmod 26

OBS-URL: https://build.opensuse.org/request/show/699853
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kmod?expand=0&rev=53
This commit is contained in:
Dominique Leuenberger 2019-05-06 11:19:09 +00:00 committed by Git OBS Bridge
commit 5c59f9e8b4
21 changed files with 157 additions and 1517 deletions

View File

@ -1,7 +1,7 @@
From ae166d55534d92e12e4892431075539474c59918 Mon Sep 17 00:00:00 2001
From bbeef7f559bd9c6b1aad11bcd65e56428f290bd8 Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Wed, 26 Feb 2014 13:48:55 +0100
Subject: [PATCH 1/5] modprobe: Recognize --allow-unsupported-modules on
Subject: [PATCH 1/6] modprobe: Recognize --allow-unsupported-modules on
commandline
The option does not do anything yet, but it does not return error
@ -14,10 +14,10 @@ Patch-mainline: never
1 file changed, 5 insertions(+)
diff --git a/tools/modprobe.c b/tools/modprobe.c
index 6b34658..589cc07 100644
index a9e2331..3be2989 100644
--- a/tools/modprobe.c
+++ b/tools/modprobe.c
@@ -83,6 +83,8 @@ static const struct option cmdopts[] = {
@@ -85,6 +85,8 @@ static const struct option cmdopts[] = {
{"dirname", required_argument, 0, 'd'},
{"set-version", required_argument, 0, 'S'},
@ -26,7 +26,7 @@ index 6b34658..589cc07 100644
{"syslog", no_argument, 0, 's'},
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
@@ -835,6 +837,9 @@ static int do_modprobe(int argc, char **orig_argv)
@@ -843,6 +845,9 @@ static int do_modprobe(int argc, char **orig_argv)
case 'S':
kversion = optarg;
break;
@ -37,5 +37,5 @@ index 6b34658..589cc07 100644
env_modprobe_options_append("-s");
use_syslog = 1;
--
1.8.4.5
2.20.1

View File

@ -1,7 +1,7 @@
From d607994c7b086afae09a8cded8bf6c5e8682541e Mon Sep 17 00:00:00 2001
From ede3e6010e5a132286c3a1ee815ec88bdef847b8 Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Wed, 26 Feb 2014 13:53:38 +0100
Subject: [PATCH 2/5] libkmod-config: Recognize allow_unsupported_modules in
Subject: [PATCH 2/6] libkmod-config: Recognize allow_unsupported_modules in
the configuration
References: fate#316971
@ -11,10 +11,10 @@ Patch-mainline: never
1 file changed, 3 insertions(+)
diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c
index 0953924..79bfb9b 100644
index aaac0a1..1b24536 100644
--- a/libkmod/libkmod-config.c
+++ b/libkmod/libkmod-config.c
@@ -667,6 +667,9 @@ static int kmod_config_parse(struct kmod_config *config, int fd,
@@ -650,6 +650,9 @@ static int kmod_config_parse(struct kmod_config *config, int fd,
|| streq(cmd, "config")) {
ERR(ctx, "%s: command %s is deprecated and not parsed anymore\n",
filename, cmd);
@ -25,5 +25,5 @@ index 0953924..79bfb9b 100644
syntax_error:
ERR(ctx, "%s line %u: ignoring bad line starting with '%s'\n",
--
1.8.4.5
2.20.1

View File

@ -1,22 +1,22 @@
From 153da67042852b7667ce4479d14835450c908417 Mon Sep 17 00:00:00 2001
From 4a36f4a8b16c7fd345f6aec973d926d4e429328a Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Wed, 5 Mar 2014 14:40:14 +0100
Subject: [PATCH 3/5] libkmod: Implement filtering of unsupported modules (off
Subject: [PATCH 3/6] libkmod: Implement filtering of unsupported modules (off
by default)
References: fate#316971
Patch-mainline: never
---
libkmod/libkmod-config.c | 12 ++++++++++--
libkmod/libkmod-internal.h | 1 +
libkmod/libkmod-module.c | 31 +++++++++++++++++++++++++++++++
libkmod/libkmod-config.c | 12 ++++++++++--
libkmod/libkmod-internal.h | 1 +
libkmod/libkmod-module.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 2 deletions(-)
Index: kmod-24/libkmod/libkmod-config.c
===================================================================
--- kmod-24.orig/libkmod/libkmod-config.c
+++ kmod-24/libkmod/libkmod-config.c
@@ -651,8 +651,16 @@ static int kmod_config_parse(struct kmod
diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c
index 1b24536..07d6a9e 100644
--- a/libkmod/libkmod-config.c
+++ b/libkmod/libkmod-config.c
@@ -651,8 +651,16 @@ static int kmod_config_parse(struct kmod_config *config, int fd,
ERR(ctx, "%s: command %s is deprecated and not parsed anymore\n",
filename, cmd);
} else if (streq(cmd, "allow_unsupported_modules")) {
@ -35,10 +35,10 @@ Index: kmod-24/libkmod/libkmod-config.c
} else {
syntax_error:
ERR(ctx, "%s line %u: ignoring bad line starting with '%s'\n",
Index: kmod-24/libkmod/libkmod-internal.h
===================================================================
--- kmod-24.orig/libkmod/libkmod-internal.h
+++ kmod-24/libkmod/libkmod-internal.h
diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h
index a65ddd1..2ad74c7 100644
--- a/libkmod/libkmod-internal.h
+++ b/libkmod/libkmod-internal.h
@@ -119,6 +119,7 @@ struct kmod_config {
struct kmod_list *softdeps;
@ -47,11 +47,11 @@ Index: kmod-24/libkmod/libkmod-internal.h
};
int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **config, const char * const *config_paths) __attribute__((nonnull(1, 2,3)));
Index: kmod-24/libkmod/libkmod-module.c
===================================================================
--- kmod-24.orig/libkmod/libkmod-module.c
+++ kmod-24/libkmod/libkmod-module.c
@@ -798,6 +798,24 @@ KMOD_EXPORT int kmod_module_remove_modul
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index bffe715..9a3a35a 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -798,6 +798,24 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
extern long init_module(const void *mem, unsigned long len, const char *args);
@ -76,7 +76,7 @@ Index: kmod-24/libkmod/libkmod-module.c
/**
* kmod_module_insert_module:
* @mod: kmod module
@@ -823,6 +841,7 @@ KMOD_EXPORT int kmod_module_insert_modul
@@ -823,6 +841,7 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
struct kmod_elf *elf;
const char *path;
const char *args = options ? options : "";
@ -84,7 +84,7 @@ Index: kmod-24/libkmod/libkmod-module.c
if (mod == NULL)
return -ENOENT;
@@ -841,6 +860,18 @@ KMOD_EXPORT int kmod_module_insert_modul
@@ -841,6 +860,18 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
}
}
@ -103,3 +103,6 @@ Index: kmod-24/libkmod/libkmod-module.c
if (kmod_file_get_direct(mod->file)) {
unsigned int kernel_flags = 0;
--
2.20.1

View File

@ -1,7 +1,7 @@
From 5ed5ab09ff7d4fb581aec3a35f2eff24eaa838f9 Mon Sep 17 00:00:00 2001
From 6cf25e17064cb213ef8c3a9c84ab787dd2852f2a Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Wed, 5 Mar 2014 15:02:44 +0100
Subject: [PATCH] modprobe: Implement --allow-unsupported-modules
Subject: [PATCH 4/6] modprobe: Implement --allow-unsupported-modules
References: fate#316971
Patch-mainline: never
@ -15,11 +15,11 @@ Patch-mainline: never
create mode 100644 libkmod/libkmod-unsupported.h
diff --git a/Makefile.am b/Makefile.am
index 26384ccd6de1..d9856f77f8f6 100644
index ddb25f0..e332977 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -106,7 +106,9 @@ libkmod_libkmod_la_LIBADD = \
${libpkcs7asn1c_LIBS}
@@ -92,7 +92,9 @@ libkmod_libkmod_la_LIBADD = \
${liblzma_LIBS} ${zlib_LIBS} ${openssl_LIBS}
noinst_LTLIBRARIES += libkmod/libkmod-internal.la
-libkmod_libkmod_internal_la_SOURCES = $(libkmod_libkmod_la_SOURCES)
@ -31,7 +31,7 @@ index 26384ccd6de1..d9856f77f8f6 100644
libkmod_libkmod_internal_la_DEPENDENCIES = $(libkmod_libkmod_la_DEPENDENCIES)
diff --git a/libkmod/libkmod-unsupported.c b/libkmod/libkmod-unsupported.c
new file mode 100644
index 000000000000..7ef9fc875b46
index 0000000..7ef9fc8
--- /dev/null
+++ b/libkmod/libkmod-unsupported.c
@@ -0,0 +1,9 @@
@ -46,7 +46,7 @@ index 000000000000..7ef9fc875b46
+}
diff --git a/libkmod/libkmod-unsupported.h b/libkmod/libkmod-unsupported.h
new file mode 100644
index 000000000000..a95b4a22fd14
index 0000000..a95b4a2
--- /dev/null
+++ b/libkmod/libkmod-unsupported.h
@@ -0,0 +1,8 @@
@ -59,7 +59,7 @@ index 000000000000..a95b4a22fd14
+ */
+void kmod_internal_allow_unsupported(struct kmod_ctx *ctx);
diff --git a/tools/modprobe.c b/tools/modprobe.c
index c0b7c6854375..1f6f28666183 100644
index 3be2989..aa4033d 100644
--- a/tools/modprobe.c
+++ b/tools/modprobe.c
@@ -38,6 +38,8 @@
@ -71,15 +71,15 @@ index c0b7c6854375..1f6f28666183 100644
static int log_priority = LOG_CRIT;
static int use_syslog = 0;
#define LOG(...) log_printf(log_priority, __VA_ARGS__)
@@ -729,6 +731,7 @@ static int do_modprobe(int argc, char **orig_argv)
@@ -755,6 +757,7 @@ static int do_modprobe(int argc, char **orig_argv)
const char *dirname = NULL;
const char *root = NULL;
const char *kversion = NULL;
+ int allow_unsupported = 0;
int use_all = 0;
int do_remove = 0;
int do_show_config = 0;
int do_show_modversions = 0;
+ int allow_unsupported = 0;
int err;
argv = prepend_options_from_env(&argc, orig_argv);
@@ -812,7 +815,7 @@ static int do_modprobe(int argc, char **orig_argv)
@@ -846,7 +849,7 @@ static int do_modprobe(int argc, char **orig_argv)
kversion = optarg;
break;
case 128:
@ -88,7 +88,7 @@ index c0b7c6854375..1f6f28666183 100644
break;
case 's':
env_modprobe_options_append("-s");
@@ -885,6 +888,9 @@ static int do_modprobe(int argc, char **orig_argv)
@@ -919,6 +922,9 @@ static int do_modprobe(int argc, char **orig_argv)
log_setup_kmod_log(ctx, verbose);
@ -99,5 +99,5 @@ index c0b7c6854375..1f6f28666183 100644
if (do_show_config)
--
2.13.6
2.20.1

View File

@ -1,7 +1,7 @@
From be9bfe0f3724624d4b0240dbe6d580b7ae8b5256 Mon Sep 17 00:00:00 2001
From 9d2f7d1e372d79dfe732992effb33daf4ee56235 Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Fri, 4 Apr 2014 10:08:01 +0200
Subject: [PATCH 5/5] Do not filter unsupported modules when running a vanilla
Subject: [PATCH 5/6] Do not filter unsupported modules when running a vanilla
kernel
References: bnc#871066
@ -11,13 +11,14 @@ Patch-mainline: never
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c
index 9f47cfd..9a486c4 100644
index 07d6a9e..550a612 100644
--- a/libkmod/libkmod-config.c
+++ b/libkmod/libkmod-config.c
@@ -573,6 +573,18 @@ static int kmod_config_parse_kcmdline(struct kmod_config *config)
@@ -566,6 +566,18 @@ static int kmod_config_parse_kcmdline(struct kmod_config *config)
return 0;
}
/*
+/*
+ * Check if kernel is built with the SUSE "suppported-flag" patch
+ */
+static int is_suse_kernel(void)
@ -29,11 +30,10 @@ index 9f47cfd..9a486c4 100644
+ return 1;
+}
+
+/*
/*
* Take an fd and own it. It will be closed on return. filename is used only
* for debug messages
*/
@@ -674,9 +686,10 @@ static int kmod_config_parse(struct kmod_config *config, int fd,
@@ -657,9 +669,10 @@ static int kmod_config_parse(struct kmod_config *config, int fd,
goto syntax_error;
if (streq(param, "yes") || streq(param, "1"))
config->block_unsupported = 0;
@ -48,5 +48,5 @@ index 9f47cfd..9a486c4 100644
} else {
syntax_error:
--
1.8.4.5
2.20.1

View File

@ -1,7 +1,7 @@
From 7e04a4a70e514aec5ed2328cb0a2d48bf6408197 Mon Sep 17 00:00:00 2001
From e48d1ee5980643f56165a9ee1687ff64f864aeb6 Mon Sep 17 00:00:00 2001
From: Vlad Bespalov <vlad.bespalov@jetstreamsoft.com>
Date: Fri, 8 Jun 2018 21:13:00 +0000
Subject: [PATCH] modprobe: print status of "allow_unsupported_modules"
Subject: [PATCH 6/6] modprobe: print status of "allow_unsupported_modules"
variable
In SLES11 modprobe printed everything referenced in /etc/modprobe.d
@ -43,7 +43,7 @@ index 550a612..0fc2250 100644
* kmod_config_get_blacklists:
* @ctx: kmod library context
diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h
index f9e33c6..0ae8ab3 100644
index 352627e..c2b9657 100644
--- a/libkmod/libkmod.h
+++ b/libkmod/libkmod.h
@@ -115,6 +115,7 @@ const char *kmod_config_iter_get_key(const struct kmod_config_iter *iter);
@ -55,10 +55,10 @@ index f9e33c6..0ae8ab3 100644
/*
* kmod_module
diff --git a/tools/modprobe.c b/tools/modprobe.c
index 1f6f286..8064e37 100644
index aa4033d..4f1c54a 100644
--- a/tools/modprobe.c
+++ b/tools/modprobe.c
@@ -199,6 +199,11 @@ static int show_config(struct kmod_ctx *ctx)
@@ -201,6 +201,11 @@ static int show_config(struct kmod_ctx *ctx)
kmod_config_iter_free_iter(iter);
}
@ -71,5 +71,5 @@ index 1f6f286..8064e37 100644
fflush(stdout);
--
2.12.3
2.20.1

View File

@ -1,62 +0,0 @@
From a06bacf500d56b72b5f9b121ebf7f6af9e3df185 Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Mon, 17 Dec 2018 23:46:28 +0100
Subject: [PATCH] depmod: prevent module dependency files corruption due to
parallel invocation.
Depmod does not use unique filename for temporary files. There is no
guarantee the user does not attempt to run mutiple depmod processes in
parallel. If that happens a temporary file might be created by
depmod(1st), truncated by depmod(2nd), and renamed to final name by
depmod(1st) resulting in corrupted file seen by user.
Due to missing mkstempat() this is more complex than it should be.
Adding PID and timestamp to the filename should be reasonably reliable.
Adding O_EXCL as mkstemp does fails creating the file rather than
corrupting existing file.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
tools/depmod.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/depmod.c b/tools/depmod.c
index 18c0d61b2db3..0f7e33ccfd59 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/time.h>
#include <sys/utsname.h>
#include <shared/array.h>
@@ -2398,6 +2399,9 @@ static int depmod_output(struct depmod *depmod, FILE *out)
};
const char *dname = depmod->cfg->dirname;
int dfd, err = 0;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
if (out != NULL)
dfd = -1;
@@ -2416,11 +2420,12 @@ static int depmod_output(struct depmod *depmod, FILE *out)
int r, ferr;
if (fp == NULL) {
- int flags = O_CREAT | O_TRUNC | O_WRONLY;
+ int flags = O_CREAT | O_EXCL | O_WRONLY;
int mode = 0644;
int fd;
- snprintf(tmp, sizeof(tmp), "%s.tmp", itr->name);
+ snprintf(tmp, sizeof(tmp), "%s.%i.%li.%li", itr->name, getpid(),
+ tv.tv_usec, tv.tv_sec);
fd = openat(dfd, tmp, flags, mode);
if (fd < 0) {
ERR("openat(%s, %s, %o, %o): %m\n",
--
2.19.2

View File

@ -1,33 +0,0 @@
From c2996b5fa880e81f63c25e80a4157b2239e32c5d Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Mon, 10 Dec 2018 22:29:32 +0100
Subject: [PATCH] depmod: prevent module dependency files missing during depmod
invocation
depmod deletes the module dependency files before moving the temporary
files in their place. This results in user seeing no dependency files
while they are updated. Remove the unlink call. The rename call should
suffice to move the new file in place and unlink the old one. It should
also do both atomically so there is no window when no dependency file
exists.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
tools/depmod.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/tools/depmod.c b/tools/depmod.c
index 989d9077926c..18c0d61b2db3 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -2451,7 +2451,6 @@ static int depmod_output(struct depmod *depmod, FILE *out)
break;
}
- unlinkat(dfd, itr->name, 0);
if (renameat(dfd, tmp, dfd, itr->name) != 0) {
err = -errno;
CRIT("renameat(%s, %s, %s, %s): %m\n",
--
2.19.2

View File

@ -1,112 +0,0 @@
From 4a894aeaebf69166e6344d8a82c2600a1d4c0d08 Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Mon, 10 Dec 2018 22:29:34 +0100
Subject: [PATCH] depmod: shut up gcc insufficinet buffer warning
In a couple of places depmod concatenates the module directory and filename
with snprintf. This can technically overflow creating an unterminated string if
module directory name is long. Use openat instead as is done elsewhere in
depmod. This avoids the snprintf, the extra buffer on stack, and the gcc
warning. It may even fix a corner case when the module direcotry name is just
under PATH_MAX.
[ Lucas: fix up coding style and closing fd on error path ]
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
tools/depmod.c | 54 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/tools/depmod.c b/tools/depmod.c
index 0f7e33ccfd59..391afe9fe0a0 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -1389,19 +1389,45 @@ static int depmod_modules_build_array(struct depmod *depmod)
return 0;
}
+static FILE *dfdopen(const char *dname, const char *filename, int flags,
+ const char *mode)
+{
+ int fd, dfd;
+ FILE *ret;
+
+ dfd = open(dname, O_RDONLY);
+ if (dfd < 0) {
+ WRN("could not open directory %s: %m\n", dname);
+ return NULL;
+ }
+
+ fd = openat(dfd, filename, flags);
+ if (fd < 0) {
+ WRN("could not open %s at %s: %m\n", filename, dname);
+ ret = NULL;
+ } else {
+ ret = fdopen(fd, mode);
+ if (!ret) {
+ WRN("could not associate stream with %s: %m\n", filename);
+ close(fd);
+ }
+ }
+ close(dfd);
+ return ret;
+}
+
+
+
static void depmod_modules_sort(struct depmod *depmod)
{
- char order_file[PATH_MAX], line[PATH_MAX];
+ char line[PATH_MAX];
+ const char *order_file = "modules.order";
FILE *fp;
unsigned idx = 0, total = 0;
- snprintf(order_file, sizeof(order_file), "%s/modules.order",
- depmod->cfg->dirname);
- fp = fopen(order_file, "r");
- if (fp == NULL) {
- WRN("could not open %s: %m\n", order_file);
+ fp = dfdopen(depmod->cfg->dirname, order_file, O_RDONLY, "r");
+ if (fp == NULL)
return;
- }
while (fgets(line, sizeof(line), fp) != NULL) {
size_t len = strlen(line);
@@ -1409,8 +1435,8 @@ static void depmod_modules_sort(struct depmod *depmod)
if (len == 0)
continue;
if (line[len - 1] != '\n') {
- ERR("%s:%u corrupted line misses '\\n'\n",
- order_file, idx);
+ ERR("%s/%s:%u corrupted line misses '\\n'\n",
+ depmod->cfg->dirname, order_file, idx);
goto corrupted;
}
}
@@ -2287,18 +2313,14 @@ static int output_builtin_bin(struct depmod *depmod, FILE *out)
{
FILE *in;
struct index_node *idx;
- char infile[PATH_MAX], line[PATH_MAX], modname[PATH_MAX];
+ char line[PATH_MAX], modname[PATH_MAX];
if (out == stdout)
return 0;
- snprintf(infile, sizeof(infile), "%s/modules.builtin",
- depmod->cfg->dirname);
- in = fopen(infile, "r");
- if (in == NULL) {
- WRN("could not open %s: %m\n", infile);
+ in = dfdopen(depmod->cfg->dirname, "modules.builtin", O_RDONLY, "r");
+ if (in == NULL)
return 0;
- }
idx = index_create();
if (idx == NULL) {
--
2.19.2

View File

@ -1,37 +0,0 @@
From d5840458e01184e068a0226ec636cb1a454a1386 Mon Sep 17 00:00:00 2001
From: Jan Engelhardt <jengelh@inai.de>
Date: Wed, 18 Jul 2018 10:39:12 +0200
Subject: [PATCH] libkmod: drop _PAD enum constants
When are enums ever mapped to something smaller than int, other than
willful packing into a bitfield?
[Remove it until there is a better reasoning for its existence.]
---
libkmod/libkmod.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h
index 352627e..4fb5ba8 100644
--- a/libkmod/libkmod.h
+++ b/libkmod/libkmod.h
@@ -71,8 +71,6 @@ enum kmod_index {
KMOD_INDEX_MODULES_ALIAS,
KMOD_INDEX_MODULES_SYMBOL,
KMOD_INDEX_MODULES_BUILTIN,
- /* Padding to make sure enum is not mapped to char */
- _KMOD_INDEX_PAD = (1 << 31),
};
int kmod_dump_index(struct kmod_ctx *ctx, enum kmod_index type, int fd);
@@ -210,8 +208,6 @@ enum kmod_module_initstate {
KMOD_MODULE_LIVE,
KMOD_MODULE_COMING,
KMOD_MODULE_GOING,
- /* Padding to make sure enum is not mapped to char */
- _KMOD_MODULE_PAD = (1 << 31),
};
const char *kmod_module_initstate_str(enum kmod_module_initstate state);
int kmod_module_get_initstate(const struct kmod_module *mod);
--
2.18.0

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJaVBxEAAoJEJuipaYwy+pTv2UQAKlYoKuWqjq3IWgqCS+6JA6E
+gCo0UUhh7Jwu77+ZHyZ0y53UKfNLdY+PXDafAzx9vF8L702U2AE7CzYUO911Z/s
Hx+p6BXHhkPcwN3Eo1q8jSs2rsz5BEkOcA0r6S5k/i0BHCJxW/amJSub+jEn6MHx
cbBaUHX3AgTz+dpSJuwQdwJhRUBRKz9UadB8AKi64OXvXkbm6up6HZjiL5yeKJPw
yXFlhCMyrwLacNFKFwKJLgdmljueHRSZyrqFMbkIoyjWdlTUQas6CxVo8PO4k/5L
j/n7ttqNIo0+/qC/+HGG9UADNztjIaRbsLLZTXYYXaqrwIuBl0RBMpn5JqB5j3n3
PkmS9EjxCcMCcVtpiV/2bY+HCsQZI0obeYk+0SK3iSE0SRqltfXNpTMlVQuiB+wA
sggpkwx9Uq6FnmpS8uPraFJ7sCsoSaDby8Ye6NXKH4o/DqBRORbdF8H3+ZF6BWGk
mADU1EHIvLCXGyCE8f6CZOTP3GPNZonWbcId2RfpsBegb3i+P8NLJ+jwSEavJRXw
kuVq9hz5QsSjeCyz0bupYYZ58vgWpQSFKt8AWqoqVZ+Lz6knROiWerZGEzt7hi9V
KaxDr7SyBCxouuG7CP1h5J6zyAiY0NkzGgoluiDFgZE/XwP6nlRJiPboCO9d5bFX
cIpbHoJB4E4GPmfgzB3Z
=xgwm
-----END PGP SIGNATURE-----

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7165e6496656159dcb909a91ed708a0fe273a4b128b4b1dc997ccb5189eef1cd
size 545416

16
kmod-26.tar.sign Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJcXKdWAAoJEJuipaYwy+pTY18P/RG8vHLEHLMtymg+hjDroTA9
uVHx7rLhH56sZa3wssH9FdsZx+CCnPsY5aE2PnfLmAob1AVmDx9IewcLT7JKbLpk
2dI8n5Ayj/Pz+KKPKHDvfwhuBS0kkw/9ds1Vhl+fZZcwtTzs6/edu+HAJiHAc0sB
46R/q1tmd9x7HBYGw0usDNgT/rUkCiwwtgIpP9kEr2EimbwMZHbyR8yJ22Ej8oWj
v3OUkncBQvcyO5J85iCzw51LYGAX6bFpoX/CeExNepXKpvrS05b+lzzbDobOLcYN
sL1aAJwQClmOCm54yRKONu2kAd7OQhwuMN8wH0vUzWfdnLcW6nnpxhli591LNt2v
5bZgyTwg3GoVkE7K0XaxRP9eCVgmUDrChARvrT0hqXtumqvzABo1G0BQbkT6knG4
xyv3seRsPstQvQNOl9cj6elgfu67fT+rhvCyJseg2V9sM1FUT6nyfwDEgIuuKhD/
2hW4u5SxwSg/w+KnLsxVvfGkrSTJtGPj4YKzfQuqFx7LIF5Rp5GuGEnN5kF6uCMo
rorVh6tiQYzCyuJvd4xiUkCCpQ/2x5LzTx/krr2OHypjIbTSUTIuwvnL2SjZSGIB
dKDK9/WLDtgo3VAXWT5mvgRIGzjx5ukLNf1Bc/MXI6OYCgeKhwqZ3p5pzBGBqjiE
1QurXHkHJjro4R8Otffp
=PbAJ
-----END PGP SIGNATURE-----

3
kmod-26.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:57bb22c8bb56435991f6b0810a042b0a65e2f1e217551efa58235b7034cdbb9d
size 552032

View File

@ -1,3 +1,32 @@
-------------------------------------------------------------------
Tue Feb 12 19:41:20 UTC 2019 - Michal Suchanek <msuchanek@suse.com>
- Enable PKCS#7 signature parsing again - requires openssl
- Fix testsuite build - requires kernel-default-devel
-------------------------------------------------------------------
Fri Feb 8 00:31:29 UTC 2019 - Jan Engelhardt <jengelh@inai.de>
- Update to new upstream release 26
* depmod now handles parallel invocations better by protecting
the temporary files being used.
* modprobe has a new --show-exports option. Under the hood,
this reads the .symtab and .strtab sections rather than
__versions so it shows useful data even if kernel is
configured without modversions (CONFIG_MODVERSIONS).
* modinfo supports PKCS#7 parsing by using openssl.
- Replaced the asn1c-based parser by an openssl-based PKCS
parser.
- Remove libkmod-signature-Fix-crash-when-module-signature-is.patch,
libkmod-signature-pkcs-7-fix-crash-when-signer-info-.patch,
libkmod-signature-implement-pkcs7-parsing-with-asn1c.patch
(not accepted upstream)
- Remove enum.patch,
depmod-Prevent-module-dependency-files-corruption-du.patch,
depmod-Prevent-module-dependency-files-missing-durin.patch,
depmod-shut-up-gcc-insufficinet-buffer-warning.patch
(accepted upstream)
-------------------------------------------------------------------
Fri Dec 7 14:55:21 UTC 2018 - Michal Suchanek <msuchanek@suse.de>

View File

@ -1,7 +1,7 @@
#
# spec file for package kmod-testsuite
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -18,37 +18,28 @@
Name: kmod-testsuite
%define lname libkmod2
Version: 25
Version: 26
Release: 0
Summary: Testsuite of the kmod package
License: LGPL-2.1-or-later AND GPL-2.0-or-later
Group: System/Kernel
Url: http://www.jonmasters.org/blog/2011/12/20/libkmod-replaces-module-init-tools/
#Announce: https://lwn.net/Articles/664801/
URL: https://www.kernel.org/pub/linux/utils/kernel/kmod/
#Git-Web: http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=summary
#Git-Clone: git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod
Source: https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-%version.tar.xz
Source2: https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-%version.tar.sign
Patch0: libkmod-signature-implement-pkcs7-parsing-with-asn1c.patch
Patch1: 0002-modprobe-Recognize-allow-unsupported-modules-on-comm.patch
Patch2: 0003-libkmod-config-Recognize-allow_unsupported_modules-i.patch
Patch3: 0009-libkmod-Implement-filtering-of-unsupported-modules-o.patch
Patch4: 0010-modprobe-Implement-allow-unsupported-modules.patch
Patch5: 0011-Do-not-filter-unsupported-modules-when-running-a-van.patch
Patch6: libkmod-signature-Fix-crash-when-module-signature-is.patch
Patch7: libkmod-signature-pkcs-7-fix-crash-when-signer-info-.patch
Patch8: 0012-modprobe-print-unsupported-status.patch
Patch9: enum.patch
Patch10: depmod-Prevent-module-dependency-files-missing-durin.patch
Patch11: depmod-Prevent-module-dependency-files-corruption-du.patch
Patch12: depmod-shut-up-gcc-insufficinet-buffer-warning.patch
Patch6: 0012-modprobe-print-unsupported-status.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: asn1c
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: git-core
BuildRequires: kernel-default-devel
BuildRequires: libopenssl-devel >= 1.1.0
BuildRequires: libtool
BuildRequires: pkgconfig >= 0.21
BuildRequires: xz
@ -77,10 +68,10 @@ export LDFLAGS="-Wl,-z,relro,-z,now"
%configure \
--with-xz \
--with-zlib \
--with-openssl \
--includedir="%_includedir/kmod" \
--with-rootlibdir="%_libdir" \
--bindir="%_bindir"
make -C libkmod/pkcs7/asn1c-gen regen
make %{?_smp_mflags} V=1 KDIR="%kdir"
%install

View File

@ -1,3 +1,31 @@
-------------------------------------------------------------------
Tue Feb 12 19:41:20 UTC 2019 - Michal Suchanek <msuchanek@suse.com>
- Enable PKCS#7 signature parsing again - requires openssl
-------------------------------------------------------------------
Fri Feb 8 00:31:29 UTC 2019 - Jan Engelhardt <jengelh@inai.de>
- Update to new upstream release 26
* depmod now handles parallel invocations better by protecting
the temporary files being used.
* modprobe has a new --show-exports option. Under the hood,
this reads the .symtab and .strtab sections rather than
__versions so it shows useful data even if kernel is
configured without modversions (CONFIG_MODVERSIONS).
* modinfo supports PKCS#7 parsing by using openssl.
- Replaced the asn1c-based parser by an openssl-based PKCS
parser.
- Remove libkmod-signature-Fix-crash-when-module-signature-is.patch,
libkmod-signature-pkcs-7-fix-crash-when-signer-info-.patch,
libkmod-signature-implement-pkcs7-parsing-with-asn1c.patch
(not accepted upstream)
- Remove enum.patch,
depmod-Prevent-module-dependency-files-corruption-du.patch,
depmod-Prevent-module-dependency-files-missing-durin.patch,
depmod-shut-up-gcc-insufficinet-buffer-warning.patch
(accepted upstream)
-------------------------------------------------------------------
Fri Dec 7 14:55:21 UTC 2018 - Michal Suchanek <msuchanek@suse.de>
@ -9,7 +37,7 @@ Fri Dec 7 14:55:21 UTC 2018 - Michal Suchanek <msuchanek@suse.de>
-------------------------------------------------------------------
Wed Jul 18 08:51:06 UTC 2018 - jengelh@inai.de
- Remove enum padding constants, add enum.patch.
- Remove enum padding constants, add enum.patch (boo#1097869).
-------------------------------------------------------------------
Fri Jun 8 21:37:14 UTC 2018 - vlad.botanic@gmail.com

View File

@ -1,7 +1,7 @@
#
# spec file for package kmod
#
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -18,42 +18,34 @@
Name: kmod
%define lname libkmod2
Version: 25
Version: 26
Release: 0
Summary: Utilities to load modules into the kernel
License: LGPL-2.1-or-later AND GPL-2.0-or-later
Group: System/Kernel
Url: https://www.kernel.org/pub/linux/utils/kernel/kmod/
URL: https://www.kernel.org/pub/linux/utils/kernel/kmod/
#Git-Web: http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=summary
#Git-Clone: git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod
Source: https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-%version.tar.xz
Source2: https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-%version.tar.sign
Patch0: libkmod-signature-implement-pkcs7-parsing-with-asn1c.patch
Patch1: 0002-modprobe-Recognize-allow-unsupported-modules-on-comm.patch
Patch2: 0003-libkmod-config-Recognize-allow_unsupported_modules-i.patch
Patch3: 0009-libkmod-Implement-filtering-of-unsupported-modules-o.patch
Patch4: 0010-modprobe-Implement-allow-unsupported-modules.patch
Patch5: 0011-Do-not-filter-unsupported-modules-when-running-a-van.patch
Patch6: libkmod-signature-Fix-crash-when-module-signature-is.patch
Patch7: libkmod-signature-pkcs-7-fix-crash-when-signer-info-.patch
Patch8: 0012-modprobe-print-unsupported-status.patch
Patch9: enum.patch
Patch10: depmod-Prevent-module-dependency-files-missing-durin.patch
Patch11: depmod-Prevent-module-dependency-files-corruption-du.patch
Patch12: depmod-shut-up-gcc-insufficinet-buffer-warning.patch
Patch6: 0012-modprobe-print-unsupported-status.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: asn1c
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libopenssl-devel >= 1.1.0
BuildRequires: libtool
BuildRequires: pkgconfig >= 0.21
BuildRequires: suse-module-tools
BuildRequires: xz
BuildRequires: pkgconfig(liblzma) >= 4.99
BuildRequires: pkgconfig(zlib)
Requires(post): coreutils
Conflicts: kmod-compat < %version
Conflicts: kmod-compat < 25
%description
kmod is a set of tools to handle common tasks with Linux kernel
@ -123,10 +115,10 @@ export LDFLAGS="-Wl,-z,relro,-z,now"
%configure \
--with-xz \
--with-zlib \
--with-openssl \
--includedir="%_includedir/kmod" \
--with-rootlibdir="%_libdir" \
--bindir="%_bindir"
make -C libkmod/pkcs7/asn1c-gen regen
make %{?_smp_mflags} V=1
%install

View File

@ -1,235 +0,0 @@
From 5336a1d1c0815da3e3b9e57f2ca9d04de3bc65dc Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Thu, 8 Mar 2018 18:30:46 +0100
Subject: [PATCH] libkmod-signature: Fix crash when module signature is not
present.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
libkmod/libkmod-internal.h | 2 +-
libkmod/libkmod-module.c | 21 +++++++++---------
libkmod/libkmod-signature.c | 53 +++++++++++++++++++++++++--------------------
3 files changed, 42 insertions(+), 34 deletions(-)
diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h
index 2ad74c7a33a5..8bc9ecfb906e 100644
--- a/libkmod/libkmod-internal.h
+++ b/libkmod/libkmod-internal.h
@@ -192,5 +192,5 @@ struct kmod_signature_info {
void (*free)(void *);
void *private;
};
-bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info) _must_check_ __attribute__((nonnull(1, 2)));
+struct kmod_signature_info *kmod_module_signature_info(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
void kmod_module_signature_info_free(struct kmod_signature_info *sig_info) __attribute__((nonnull));
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 7b00d526edec..cbe35819932e 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -2304,7 +2304,7 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
struct kmod_elf *elf;
char **strings;
int i, count, ret = -ENOMEM;
- struct kmod_signature_info sig_info;
+ struct kmod_signature_info *sig_info = NULL;
if (mod == NULL || list == NULL)
return -ENOENT;
@@ -2341,32 +2341,32 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
goto list_error;
}
- if (kmod_module_signature_info(mod->file, &sig_info)) {
+ if (sig_info = kmod_module_signature_info(mod->file)) {
struct kmod_list *n;
n = kmod_module_info_append(list, "sig_id", strlen("sig_id"),
- sig_info.id_type, strlen(sig_info.id_type));
+ sig_info->id_type, strlen(sig_info->id_type));
if (n == NULL)
goto list_error;
count++;
n = kmod_module_info_append(list, "signer", strlen("signer"),
- sig_info.signer, sig_info.signer_len);
+ sig_info->signer, sig_info->signer_len);
if (n == NULL)
goto list_error;
count++;
n = kmod_module_info_append_hex(list, "sig_key", strlen("sig_key"),
- sig_info.key_id,
- sig_info.key_id_len);
+ sig_info->key_id,
+ sig_info->key_id_len);
if (n == NULL)
goto list_error;
count++;
n = kmod_module_info_append(list,
"sig_hashalgo", strlen("sig_hashalgo"),
- sig_info.hash_algo, strlen(sig_info.hash_algo));
+ sig_info->hash_algo, strlen(sig_info->hash_algo));
if (n == NULL)
goto list_error;
count++;
@@ -2377,8 +2377,8 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
*/
n = kmod_module_info_append_hex(list, "signature",
strlen("signature"),
- sig_info.sig,
- sig_info.sig_len);
+ sig_info->sig,
+ sig_info->sig_len);
if (n == NULL)
goto list_error;
@@ -2389,7 +2389,8 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
list_error:
/* aux structures freed in normal case also */
- kmod_module_signature_info_free(&sig_info);
+ if (sig_info)
+ kmod_module_signature_info_free(sig_info);
if (ret < 0) {
kmod_module_info_free_list(*list);
diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
index bdf84cb14718..fae074e6dd1d 100644
--- a/libkmod/libkmod-signature.c
+++ b/libkmod/libkmod-signature.c
@@ -93,13 +93,17 @@ struct module_signature {
uint32_t sig_len; /* Length of signature data (big endian) */
};
-static bool
+static struct kmod_signature_info *
kmod_module_signature_info_default(const char *mem,
off_t size,
const struct module_signature *modsig,
- size_t sig_len,
- struct kmod_signature_info *sig_info)
+ size_t sig_len)
{
+ struct kmod_signature_info *sig_info = malloc(sizeof *sig_info);
+
+ if (!sig_info)
+ return NULL;
+
size -= sig_len;
sig_info->sig = mem + size;
sig_info->sig_len = sig_len;
@@ -119,7 +123,7 @@ kmod_module_signature_info_default(const char *mem,
sig_info->free = NULL;
sig_info->private = NULL;
- return true;
+ return sig_info;
}
static void kmod_module_signature_info_pkcs7_free(void *s)
@@ -129,13 +133,13 @@ static void kmod_module_signature_info_pkcs7_free(void *s)
pkcs7_free_cert(si->private);
}
-static bool
+static struct kmod_signature_info *
kmod_module_signature_info_pkcs7(const char *mem,
off_t size,
const struct module_signature *modsig,
- size_t sig_len,
- struct kmod_signature_info *sig_info)
+ size_t sig_len)
{
+ struct kmod_signature_info *sig_info = NULL;
const char *pkcs7_raw;
struct pkcs7_cert *cert;
@@ -144,7 +148,13 @@ kmod_module_signature_info_pkcs7(const char *mem,
cert = pkcs7_parse_cert(pkcs7_raw, sig_len);
if (cert == NULL)
- return false;
+ return NULL;
+
+ sig_info = malloc(sizeof *sig_info);
+ if (!sig_info) {
+ free(cert);
+ return NULL;
+ }
sig_info->private = cert;
sig_info->free = kmod_module_signature_info_pkcs7_free;
@@ -162,7 +172,7 @@ kmod_module_signature_info_pkcs7(const char *mem,
sig_info->hash_algo = cert->hash_algo;
sig_info->id_type = pkey_id_type[modsig->id_type];
- return true;
+ return sig_info;
}
#define SIG_MAGIC "~Module signature appended~\n"
@@ -178,48 +188,45 @@ kmod_module_signature_info_pkcs7(const char *mem,
* [ SIG_MAGIC ]
*/
-bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info)
+struct kmod_signature_info *kmod_module_signature_info(const struct kmod_file *file)
{
const char *mem;
off_t size;
const struct module_signature *modsig;
size_t sig_len;
- bool ret;
size = kmod_file_get_size(file);
mem = kmod_file_get_contents(file);
if (size < (off_t)strlen(SIG_MAGIC))
- return false;
+ return NULL;
size -= strlen(SIG_MAGIC);
if (memcmp(SIG_MAGIC, mem + size, strlen(SIG_MAGIC)) != 0)
- return false;
+ return NULL;
if (size < (off_t)sizeof(struct module_signature))
- return false;
+ return NULL;
size -= sizeof(struct module_signature);
modsig = (struct module_signature *)(mem + size);
if (modsig->algo >= PKEY_ALGO__LAST ||
modsig->hash >= PKEY_HASH__LAST ||
modsig->id_type >= PKEY_ID_TYPE__LAST)
- return false;
+ return NULL;
sig_len = be32toh(get_unaligned(&modsig->sig_len));
if (sig_len == 0 ||
size < (int64_t)(modsig->signer_len + modsig->key_id_len + sig_len))
- return false;
+ return NULL;
if (modsig->id_type == PKEY_ID_PKCS7)
- ret = kmod_module_signature_info_pkcs7(mem, size,
- modsig, sig_len,
- sig_info);
+ return kmod_module_signature_info_pkcs7(mem, size,
+ modsig, sig_len);
else
- ret = kmod_module_signature_info_default(mem, size,
- modsig, sig_len,
- sig_info);
- return ret;
+ return kmod_module_signature_info_default(mem, size,
+ modsig, sig_len);
}
void kmod_module_signature_info_free(struct kmod_signature_info *sig_info)
{
if (sig_info->free)
sig_info->free(sig_info);
+ free(sig_info);
}
--
2.13.6

View File

@ -1,896 +0,0 @@
From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
Subject: [PATCH RFC PKCS7 asn1c 1/2] libkmod-signature: implement pkcs7 parsing with asn1c compiler
Date: Thu, 8 Mar 2018 15:58:09 +0200
The patch adds pkcs7.asn1 description, taken from the linux kernel
and modified to be suitable for the asn1c compiler and a wrapper on
the asn1c's parser to make it more suitable for kmod.
Since kmod (modinfo) supports only one signature at the moment, the
wrapper ignores others and it also analyzes object IDs only for
hashing algorithms.
To compile the stuff you need to have asn1c installed, finish
./configure and invoke
make -C libkmod/pkcs7/asn1c-gen regen
to generate the parser.
Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
---
Makefile.am | 22 ++-
configure.ac | 1 +
libkmod/libkmod-internal.h | 3 +
libkmod/libkmod-module.c | 3 +
libkmod/libkmod-signature.c | 105 ++++++++++---
libkmod/pkcs7/asn1c-gen/Makefile.am | 131 ++++++++++++++++
libkmod/pkcs7/pkcs7.asn1 | 135 ++++++++++++++++
libkmod/pkcs7/pkcs7_parser.c | 297 ++++++++++++++++++++++++++++++++++++
libkmod/pkcs7/pkcs7_parser.h | 42 +++++
9 files changed, 719 insertions(+), 20 deletions(-)
create mode 100644 libkmod/pkcs7/asn1c-gen/Makefile.am
create mode 100644 libkmod/pkcs7/pkcs7.asn1
create mode 100644 libkmod/pkcs7/pkcs7_parser.c
create mode 100644 libkmod/pkcs7/pkcs7_parser.h
diff --git a/Makefile.am b/Makefile.am
index 194e1115ae70..26384ccd6de1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . libkmod/docs
+SUBDIRS = . libkmod/docs libkmod/pkcs7/asn1c-gen
if BUILD_MANPAGES
SUBDIRS += man
@@ -62,6 +62,13 @@ shared_libshared_la_SOURCES = \
include_HEADERS = libkmod/libkmod.h
lib_LTLIBRARIES = libkmod/libkmod.la
+
+PKCS7_SRCS = \
+ libkmod/pkcs7/pkcs7_parser.c \
+ libkmod/pkcs7/pkcs7_parser.h
+
+AM_CPPFLAGS += -Ilibkmod/pkcs7/asn1c-gen -D_DEFAULT_SOURCE
+
libkmod_libkmod_la_SOURCES = \
libkmod/libkmod.h \
libkmod/libkmod-internal.h \
@@ -73,7 +80,14 @@ libkmod_libkmod_la_SOURCES = \
libkmod/libkmod-module.c \
libkmod/libkmod-file.c \
libkmod/libkmod-elf.c \
- libkmod/libkmod-signature.c
+ libkmod/libkmod-signature.c \
+ $(PKCS7_SRCS)
+
+libpkcs7asn1c = libkmod/pkcs7/asn1c-gen/libpkcs7asn1c.la
+libpkcs7asn1c_LIBS = ${libpkcs7asn1c}
+
+${libpkcs7asn1c}:
+ ${MAKE} -C libkmod/pkcs7/asn1c-gen
EXTRA_DIST += libkmod/libkmod.sym
EXTRA_DIST += libkmod/README \
@@ -84,10 +98,12 @@ libkmod_libkmod_la_LDFLAGS = $(AM_LDFLAGS) \
-Wl,--version-script=$(top_srcdir)/libkmod/libkmod.sym
libkmod_libkmod_la_DEPENDENCIES = \
shared/libshared.la \
+ ${libpkcs7asn1c} \
${top_srcdir}/libkmod/libkmod.sym
libkmod_libkmod_la_LIBADD = \
shared/libshared.la \
- ${liblzma_LIBS} ${zlib_LIBS}
+ ${liblzma_LIBS} ${zlib_LIBS} \
+ ${libpkcs7asn1c_LIBS}
noinst_LTLIBRARIES += libkmod/libkmod-internal.la
libkmod_libkmod_internal_la_SOURCES = $(libkmod_libkmod_la_SOURCES)
diff --git a/configure.ac b/configure.ac
index fbc7391b2d1b..0d5f83a45778 100644
--- a/configure.ac
+++ b/configure.ac
@@ -271,6 +271,7 @@ AC_CONFIG_FILES([
man/Makefile
libkmod/docs/Makefile
libkmod/docs/version.xml
+ libkmod/pkcs7/asn1c-gen/Makefile
])
diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h
index 346579c71aab..a65ddd156f18 100644
--- a/libkmod/libkmod-internal.h
+++ b/libkmod/libkmod-internal.h
@@ -188,5 +188,8 @@ struct kmod_signature_info {
const char *algo, *hash_algo, *id_type;
const char *sig;
size_t sig_len;
+ void (*free)(void *);
+ void *private;
};
bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signature_info *sig_info) _must_check_ __attribute__((nonnull(1, 2)));
+void kmod_module_signature_info_free(struct kmod_signature_info *sig_info) __attribute__((nonnull));
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 0a3ef11c860f..b5cee437ae0e 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -2357,6 +2357,9 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
ret = count;
list_error:
+ /* aux structures freed in normal case also */
+ kmod_module_signature_info_free(&sig_info);
+
if (ret < 0) {
kmod_module_info_free_list(*list);
*list = NULL;
diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
index 1f3e26dea203..bdf84cb14718 100644
--- a/libkmod/libkmod-signature.c
+++ b/libkmod/libkmod-signature.c
@@ -26,6 +26,7 @@
#include <shared/missing.h>
#include <shared/util.h>
+#include "pkcs7/pkcs7_parser.h"
#include "libkmod-internal.h"
/* These types and tables were copied from the 3.7 kernel sources.
@@ -92,6 +93,78 @@ struct module_signature {
uint32_t sig_len; /* Length of signature data (big endian) */
};
+static bool
+kmod_module_signature_info_default(const char *mem,
+ off_t size,
+ const struct module_signature *modsig,
+ size_t sig_len,
+ struct kmod_signature_info *sig_info)
+{
+ size -= sig_len;
+ sig_info->sig = mem + size;
+ sig_info->sig_len = sig_len;
+
+ size -= modsig->key_id_len;
+ sig_info->key_id = mem + size;
+ sig_info->key_id_len = modsig->key_id_len;
+
+ size -= modsig->signer_len;
+ sig_info->signer = mem + size;
+ sig_info->signer_len = modsig->signer_len;
+
+ sig_info->algo = pkey_algo[modsig->algo];
+ sig_info->hash_algo = pkey_hash_algo[modsig->hash];
+ sig_info->id_type = pkey_id_type[modsig->id_type];
+
+ sig_info->free = NULL;
+ sig_info->private = NULL;
+
+ return true;
+}
+
+static void kmod_module_signature_info_pkcs7_free(void *s)
+{
+ struct kmod_signature_info *si = s;
+
+ pkcs7_free_cert(si->private);
+}
+
+static bool
+kmod_module_signature_info_pkcs7(const char *mem,
+ off_t size,
+ const struct module_signature *modsig,
+ size_t sig_len,
+ struct kmod_signature_info *sig_info)
+{
+ const char *pkcs7_raw;
+ struct pkcs7_cert *cert;
+
+ size -= sig_len;
+ pkcs7_raw = mem + size;
+
+ cert = pkcs7_parse_cert(pkcs7_raw, sig_len);
+ if (cert == NULL)
+ return false;
+
+ sig_info->private = cert;
+ sig_info->free = kmod_module_signature_info_pkcs7_free;
+
+ sig_info->sig = (const char *)cert->signature;
+ sig_info->sig_len = cert->signature_size;
+
+ sig_info->key_id = (const char *)cert->key_id;
+ sig_info->key_id_len = cert->key_id_size;
+
+ sig_info->signer = cert->signer;
+ sig_info->signer_len = strlen(cert->signer);
+
+ sig_info->algo = NULL;
+ sig_info->hash_algo = cert->hash_algo;
+ sig_info->id_type = pkey_id_type[modsig->id_type];
+
+ return true;
+}
+
#define SIG_MAGIC "~Module signature appended~\n"
/*
@@ -111,7 +184,7 @@ bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signat
off_t size;
const struct module_signature *modsig;
size_t sig_len;
-
+ bool ret;
size = kmod_file_get_size(file);
mem = kmod_file_get_contents(file);
@@ -134,21 +207,19 @@ bool kmod_module_signature_info(const struct kmod_file *file, struct kmod_signat
size < (int64_t)(modsig->signer_len + modsig->key_id_len + sig_len))
return false;
- size -= sig_len;
- sig_info->sig = mem + size;
- sig_info->sig_len = sig_len;
-
- size -= modsig->key_id_len;
- sig_info->key_id = mem + size;
- sig_info->key_id_len = modsig->key_id_len;
-
- size -= modsig->signer_len;
- sig_info->signer = mem + size;
- sig_info->signer_len = modsig->signer_len;
-
- sig_info->algo = pkey_algo[modsig->algo];
- sig_info->hash_algo = pkey_hash_algo[modsig->hash];
- sig_info->id_type = pkey_id_type[modsig->id_type];
+ if (modsig->id_type == PKEY_ID_PKCS7)
+ ret = kmod_module_signature_info_pkcs7(mem, size,
+ modsig, sig_len,
+ sig_info);
+ else
+ ret = kmod_module_signature_info_default(mem, size,
+ modsig, sig_len,
+ sig_info);
+ return ret;
+}
- return true;
+void kmod_module_signature_info_free(struct kmod_signature_info *sig_info)
+{
+ if (sig_info->free)
+ sig_info->free(sig_info);
}
diff --git a/libkmod/pkcs7/asn1c-gen/Makefile.am b/libkmod/pkcs7/asn1c-gen/Makefile.am
new file mode 100644
index 000000000000..b9b613003039
--- /dev/null
+++ b/libkmod/pkcs7/asn1c-gen/Makefile.am
@@ -0,0 +1,131 @@
+ASN_MODULE_SOURCES= \
+ PKCS7ContentInfo.c \
+ ContentType.c \
+ SignedData.c \
+ ContentInfo.c \
+ Data.c \
+ DigestAlgorithmIdentifiers.c \
+ DigestAlgorithmIdentifier.c \
+ ExtendedCertificatesAndCertificates.c \
+ Certificates.c \
+ CertificateRevocationLists.c \
+ CertificateList.c \
+ CRLSequence.c \
+ Certificate.c \
+ SignerInfos.c \
+ SignerInfo.c \
+ SignerIdentifier.c \
+ IssuerAndSerialNumber.c \
+ CertificateSerialNumber.c \
+ SubjectKeyIdentifier.c \
+ SetOfAuthenticatedAttribute.c \
+ Values.c \
+ AuthenticatedAttribute.c \
+ UnauthenticatedAttribute.c \
+ DigestEncryptionAlgorithmIdentifier.c \
+ EncryptedDigest.c \
+ Name.c \
+ RelativeDistinguishedName.c \
+ AttributeValueAssertion.c
+
+ASN_MODULE_HEADERS= \
+ PKCS7ContentInfo.h \
+ ContentType.h \
+ SignedData.h \
+ ContentInfo.h \
+ Data.h \
+ DigestAlgorithmIdentifiers.h \
+ DigestAlgorithmIdentifier.h \
+ ExtendedCertificatesAndCertificates.h \
+ Certificates.h \
+ CertificateRevocationLists.h \
+ CertificateList.h \
+ CRLSequence.h \
+ Certificate.h \
+ SignerInfos.h \
+ SignerInfo.h \
+ SignerIdentifier.h \
+ IssuerAndSerialNumber.h \
+ CertificateSerialNumber.h \
+ SubjectKeyIdentifier.h \
+ SetOfAuthenticatedAttribute.h \
+ Values.h \
+ AuthenticatedAttribute.h \
+ UnauthenticatedAttribute.h \
+ DigestEncryptionAlgorithmIdentifier.h \
+ EncryptedDigest.h \
+ Name.h \
+ RelativeDistinguishedName.h \
+ AttributeValueAssertion.h
+
+ASN_MODULE_HEADERS+=ANY.h
+ASN_MODULE_SOURCES+=ANY.c
+ASN_MODULE_HEADERS+=INTEGER.h
+ASN_MODULE_HEADERS+=NativeEnumerated.h
+ASN_MODULE_SOURCES+=INTEGER.c
+ASN_MODULE_SOURCES+=NativeEnumerated.c
+ASN_MODULE_HEADERS+=NativeInteger.h
+ASN_MODULE_SOURCES+=NativeInteger.c
+ASN_MODULE_HEADERS+=OBJECT_IDENTIFIER.h
+ASN_MODULE_SOURCES+=OBJECT_IDENTIFIER.c
+ASN_MODULE_HEADERS+=asn_SEQUENCE_OF.h
+ASN_MODULE_SOURCES+=asn_SEQUENCE_OF.c
+ASN_MODULE_HEADERS+=asn_SET_OF.h
+ASN_MODULE_SOURCES+=asn_SET_OF.c
+ASN_MODULE_HEADERS+=constr_CHOICE.h
+ASN_MODULE_SOURCES+=constr_CHOICE.c
+ASN_MODULE_HEADERS+=constr_SEQUENCE.h
+ASN_MODULE_SOURCES+=constr_SEQUENCE.c
+ASN_MODULE_HEADERS+=constr_SEQUENCE_OF.h
+ASN_MODULE_SOURCES+=constr_SEQUENCE_OF.c
+ASN_MODULE_HEADERS+=constr_SET_OF.h
+ASN_MODULE_SOURCES+=constr_SET_OF.c
+ASN_MODULE_HEADERS+=asn_application.h
+ASN_MODULE_HEADERS+=asn_system.h
+ASN_MODULE_HEADERS+=asn_codecs.h
+ASN_MODULE_HEADERS+=asn_internal.h
+ASN_MODULE_HEADERS+=OCTET_STRING.h
+ASN_MODULE_SOURCES+=OCTET_STRING.c
+ASN_MODULE_HEADERS+=BIT_STRING.h
+ASN_MODULE_SOURCES+=BIT_STRING.c
+ASN_MODULE_SOURCES+=asn_codecs_prim.c
+ASN_MODULE_HEADERS+=asn_codecs_prim.h
+ASN_MODULE_HEADERS+=ber_tlv_length.h
+ASN_MODULE_SOURCES+=ber_tlv_length.c
+ASN_MODULE_HEADERS+=ber_tlv_tag.h
+ASN_MODULE_SOURCES+=ber_tlv_tag.c
+ASN_MODULE_HEADERS+=ber_decoder.h
+ASN_MODULE_SOURCES+=ber_decoder.c
+ASN_MODULE_HEADERS+=der_encoder.h
+ASN_MODULE_SOURCES+=der_encoder.c
+ASN_MODULE_HEADERS+=constr_TYPE.h
+ASN_MODULE_SOURCES+=constr_TYPE.c
+ASN_MODULE_HEADERS+=constraints.h
+ASN_MODULE_SOURCES+=constraints.c
+ASN_MODULE_HEADERS+=xer_support.h
+ASN_MODULE_SOURCES+=xer_support.c
+ASN_MODULE_HEADERS+=xer_decoder.h
+ASN_MODULE_SOURCES+=xer_decoder.c
+ASN_MODULE_HEADERS+=xer_encoder.h
+ASN_MODULE_SOURCES+=xer_encoder.c
+ASN_MODULE_HEADERS+=per_support.h
+ASN_MODULE_SOURCES+=per_support.c
+ASN_MODULE_HEADERS+=per_decoder.h
+ASN_MODULE_SOURCES+=per_decoder.c
+ASN_MODULE_HEADERS+=per_encoder.h
+ASN_MODULE_SOURCES+=per_encoder.c
+ASN_MODULE_HEADERS+=per_opentype.h
+ASN_MODULE_SOURCES+=per_opentype.c
+
+ASN_MODULEdir = .
+
+noinst_LTLIBRARIES=libpkcs7asn1c.la
+libpkcs7asn1c_la_SOURCES=$(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
+
+AM_CPPFLAGS = -DEMIT_ASN_DEBUG=0 -D_DEFAULT_SOURCE
+
+regen: regenerate-from-asn1-source
+
+regenerate-from-asn1-source:
+ asn1c -fwide-types ../pkcs7.asn1
+
diff --git a/libkmod/pkcs7/pkcs7.asn1 b/libkmod/pkcs7/pkcs7.asn1
new file mode 100644
index 000000000000..c7d59c2bb4ab
--- /dev/null
+++ b/libkmod/pkcs7/pkcs7.asn1
@@ -0,0 +1,135 @@
+PKCS7 DEFINITIONS ::=
+BEGIN
+
+PKCS7ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content [0] EXPLICIT SignedData OPTIONAL
+}
+
+ContentType ::= OBJECT IDENTIFIER
+
+SignedData ::= SEQUENCE {
+ version INTEGER,
+ digestAlgorithms DigestAlgorithmIdentifiers,
+ contentInfo ContentInfo,
+ certificates CHOICE {
+ certSet [0] IMPLICIT ExtendedCertificatesAndCertificates,
+ certSequence [2] IMPLICIT Certificates
+ } OPTIONAL,
+ crls CHOICE {
+ crlSet [1] IMPLICIT CertificateRevocationLists,
+ crlSequence [3] IMPLICIT CRLSequence
+ } OPTIONAL,
+ signerInfos SignerInfos
+}
+
+ContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ content [0] EXPLICIT Data OPTIONAL
+}
+
+Data ::= ANY
+
+DigestAlgorithmIdentifiers ::= CHOICE {
+ daSet SET OF DigestAlgorithmIdentifier,
+ daSequence SEQUENCE OF DigestAlgorithmIdentifier
+}
+
+DigestAlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY OPTIONAL
+}
+
+--
+-- Certificates and certificate lists
+--
+ExtendedCertificatesAndCertificates ::= SET OF Certificate
+
+Certificates ::= SEQUENCE OF Certificate
+
+CertificateRevocationLists ::= SET OF CertificateList
+
+CertificateList ::= SEQUENCE OF Certificate -- This may be defined incorrectly
+
+CRLSequence ::= SEQUENCE OF CertificateList
+
+Certificate ::= ANY -- X.509, Skip
+
+--
+-- Signer information
+--
+SignerInfos ::= CHOICE {
+ siSet SET OF SignerInfo,
+ siSequence SEQUENCE OF SignerInfo
+}
+
+SignerInfo ::= SEQUENCE {
+ version INTEGER,
+ sid SignerIdentifier, -- CMS variant, not PKCS#7
+ digestAlgorithm DigestAlgorithmIdentifier,
+ authenticatedAttributes CHOICE {
+ aaSet [0] IMPLICIT SetOfAuthenticatedAttribute,
+ aaSequence [2] EXPLICIT SEQUENCE OF AuthenticatedAttribute
+ -- Explicit because easier to compute digest on
+ -- sequence of attributes and then reuse encoded
+ -- sequence in aaSequence.
+ } OPTIONAL,
+ digestEncryptionAlgorithm
+ DigestEncryptionAlgorithmIdentifier,
+ encryptedDigest EncryptedDigest,
+ unauthenticatedAttributes CHOICE {
+ uaSet [1] IMPLICIT SET OF UnauthenticatedAttribute,
+ uaSequence [3] IMPLICIT SEQUENCE OF UnauthenticatedAttribute
+ } OPTIONAL
+}
+
+SignerIdentifier ::= CHOICE {
+ -- RFC5652 sec 5.3
+ issuerAndSerialNumber IssuerAndSerialNumber,
+ subjectKeyIdentifier [0] IMPLICIT SubjectKeyIdentifier
+}
+
+IssuerAndSerialNumber ::= SEQUENCE {
+ issuer ANY,
+ serialNumber ANY
+}
+
+CertificateSerialNumber ::= INTEGER
+
+SubjectKeyIdentifier ::= OCTET STRING
+
+SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute
+
+Values ::= SET OF ANY
+
+AuthenticatedAttribute ::= SEQUENCE {
+ type OBJECT IDENTIFIER,
+ values Values
+}
+
+UnauthenticatedAttribute ::= SEQUENCE {
+ type OBJECT IDENTIFIER,
+ values Values
+}
+
+DigestEncryptionAlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY OPTIONAL
+}
+
+EncryptedDigest ::= OCTET STRING
+
+---
+--- X.500 Name
+---
+Name ::= SEQUENCE OF RelativeDistinguishedName
+
+RelativeDistinguishedName ::= SET OF AttributeValueAssertion
+
+AttributeValueAssertion ::= SEQUENCE {
+ attributeType OBJECT IDENTIFIER,
+ attributeValue ANY
+}
+
+END
+
diff --git a/libkmod/pkcs7/pkcs7_parser.c b/libkmod/pkcs7/pkcs7_parser.c
new file mode 100644
index 000000000000..d1da9a6b4ac8
--- /dev/null
+++ b/libkmod/pkcs7/pkcs7_parser.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc., Yauheni Kaliuta
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pkcs7_parser.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+enum pkey_hash_algo {
+ PKEY_HASH_MD4,
+ PKEY_HASH_MD5,
+ PKEY_HASH_SHA1,
+ PKEY_HASH_SHA256,
+ PKEY_HASH_SHA384,
+ PKEY_HASH_SHA512,
+ PKEY_HASH_SHA224,
+ PKEY_HASH__LAST
+};
+
+static const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
+ [PKEY_HASH_MD4] = "md4",
+ [PKEY_HASH_MD5] = "md5",
+ [PKEY_HASH_SHA1] = "sha1",
+ [PKEY_HASH_SHA256] = "sha256",
+ [PKEY_HASH_SHA384] = "sha384",
+ [PKEY_HASH_SHA512] = "sha512",
+ [PKEY_HASH_SHA224] = "sha224",
+};
+
+/* 2.5.4.3 */
+static uint8_t OID_cn[] = { '\x55', '\x04', '\x03' };
+/* 1.3.14.3.2.26 */
+static uint8_t OID_SHA1[] = { '\x2b', '\x0e', '\x03', '\x02', '\x1a' };
+/* 2.16.840.1.101.3.4.2.1 */
+static uint8_t OID_SHA256[] = { '\x60', '\x86', '\x48', '\x01',
+ '\x65', '\x03', '\x04', '\x02', '\x01' };
+/* 2.16.840.1.101.3.4.2.2 */
+static uint8_t OID_SHA384[] = { '\x60', '\x86', '\x48', '\x01',
+ '\x65', '\x03', '\x04', '\x02', '\x02' };
+/* 2.16.840.1.101.3.4.2.3 */
+static uint8_t OID_SHA512[] = { '\x60', '\x86', '\x48', '\x01',
+ '\x65', '\x03', '\x04', '\x02', '\x03' };
+/* 2.16.840.1.101.3.4.2.4 */
+static uint8_t OID_SHA224[] = { '\x60', '\x86', '\x48', '\x01',
+ '\x65', '\x03', '\x04', '\x02', '\x04' };
+
+static uint8_t OID_MD4[] = { '\x2a', '\x86', '\x48', '\x86', '\xf7',
+ '\x0d', '\x02', '\x04' };
+static uint8_t OID_MD5[] = { '\x2a', '\x86', '\x48', '\x86', '\xf7',
+ '\x0d', '\x02', '\x05' };
+
+
+#define OID_TO_ID(oid) { OID_ ## oid, sizeof(OID_ ## oid), PKEY_HASH_ ## oid }
+static struct oid_to_id {
+ uint8_t *oid;
+ int oid_size;
+ int id;
+} oid_to_id[] = {
+ OID_TO_ID(SHA256),
+ OID_TO_ID(MD5),
+ OID_TO_ID(SHA1),
+ OID_TO_ID(SHA384),
+ OID_TO_ID(SHA512),
+ OID_TO_ID(SHA224),
+ OID_TO_ID(MD4),
+};
+
+
+static const char *pkey_hash_algo_to_str(unsigned id)
+{
+ if (id >= PKEY_HASH__LAST)
+ return "unknown";
+
+ return pkey_hash_algo[id];
+}
+
+void pkcs7_free_cert(struct pkcs7_cert *cert)
+{
+
+ asn_DEF_Name.free_struct(&asn_DEF_Name, cert->issuer, 0);
+
+ asn_DEF_PKCS7ContentInfo.free_struct
+ (&asn_DEF_PKCS7ContentInfo, cert->ci, 0);
+
+ free(cert->key_id);
+ free(cert->signer);
+ free(cert->signature);
+ free(cert);
+}
+
+static char *pkcs7_parse_utf8(uint8_t *buf, int size)
+{
+ char *p;
+ int len;
+ int llen = 1; /* length of length field */
+
+ if (buf[0] != 0x0C) /* utf8 string tag */
+ return NULL;
+
+ if (buf[1] & 0x80)
+ llen = (buf[1] & ~0x80) + 1;
+ len = size - 1 - llen; /* 1 is tag */
+
+ p = malloc(len + 1);
+ if (p == NULL)
+ return NULL;
+
+ memcpy(p, buf + 1 + llen, len);
+ p[len] = '\0';
+
+ return p;
+}
+
+static int pkcs7_parse_issuer(struct pkcs7_cert *cert, ANY_t *data)
+{
+ asn_dec_rval_t rval;
+ struct RelativeDistinguishedName **dnames;
+ int count;
+ int i;
+
+ rval = ber_decode(0, &asn_DEF_Name, (void **)&cert->issuer,
+ data->buf, data->size);
+
+ if(rval.code != RC_OK)
+ return -1;
+
+ dnames = cert->issuer->list.array;
+ count = cert->issuer->list.count;
+
+ for (i = 0; i < count; i++) {
+ int j;
+ int n = dnames[i]->list.count;
+ struct AttributeValueAssertion **ava = dnames[i]->list.array;
+
+ for (j = 0; j < n; j++) {
+ OBJECT_IDENTIFIER_t *oid = &ava[j]->attributeType;
+ ANY_t *d = &ava[j]->attributeValue;
+
+ if (oid->size != sizeof(OID_cn))
+ continue;
+
+ if (memcmp(oid->buf, OID_cn, sizeof(OID_cn)) == 0) {
+ cert->signer = pkcs7_parse_utf8(d->buf, d->size);
+ break;
+ }
+ }
+ if (cert->signer != NULL)
+ break;
+ }
+
+ return 0;
+}
+
+static int pkcs7_gen_keyid_from_skid(OCTET_STRING_t *skid,
+ uint8_t **buf, size_t *size)
+{
+ uint8_t *p;
+
+ p = malloc(skid->size);
+ if (p == NULL)
+ return -1;
+
+ memcpy(p, skid->buf, skid->size);
+
+ *buf = p;
+ *size = skid->size;
+
+ return 0;
+}
+
+static int pkcs7_gen_keyid_from_issuer(IssuerAndSerialNumber_t *issuer,
+ uint8_t **buf, size_t *size)
+{
+ size_t s;
+ uint8_t *p;
+
+ /*
+ * see asymmetric_key_generate_id(),
+ * crypto/asymmetric_keys/assymmetric_type.c in the linux kernel
+ */
+
+ s = issuer->issuer.size + issuer->serialNumber.size;
+
+ p = malloc(s);
+ if (p == NULL)
+ return -1;
+
+ memcpy(p, issuer->issuer.buf, issuer->issuer.size);
+ memcpy(p + issuer->issuer.size,
+ issuer->serialNumber.buf,
+ issuer->serialNumber.size);
+
+ *buf = p;
+ *size = s;
+
+ return 0;
+}
+
+static uint8_t pkcs7_hashalgo_oid_to_id(OBJECT_IDENTIFIER_t *oid)
+{
+ unsigned i;
+ struct oid_to_id *item;
+
+ for (i = 0; i < ARRAY_SIZE(oid_to_id); i++) {
+ item = &oid_to_id[i];
+ if (oid->size != item->oid_size)
+ continue;
+ if (memcmp(oid->buf, item->oid, oid->size) != 0)
+ continue;
+ return item->id;
+ }
+ return ~0;
+}
+
+static int pkcs7_parse_si(struct pkcs7_cert *cert)
+{
+ struct SignerInfo **infos;
+ struct SignerInfo *si;
+ int count;
+ OBJECT_IDENTIFIER_t *oid;
+ uint8_t *buf;
+
+ infos = cert->ci->content->signerInfos.choice.siSequence.list.array;
+ count = cert->ci->content->signerInfos.choice.siSequence.list.count;
+
+ if (count < 1)
+ return -1;
+
+ si = infos[0];
+
+ if (si->sid.present == SignerIdentifier_PR_subjectKeyIdentifier) {
+ if (pkcs7_gen_keyid_from_skid(&si->sid.choice.subjectKeyIdentifier, &cert->key_id, &cert->key_id_size) < 0)
+ return -1;
+ return 1;
+ }
+
+ if (pkcs7_parse_issuer(cert,
+ &si->sid.choice.issuerAndSerialNumber.issuer) < 0)
+ return -1;
+ if (pkcs7_gen_keyid_from_issuer(&si->sid.choice.issuerAndSerialNumber,
+ &cert->key_id, &cert->key_id_size) < 0)
+ return -1;
+
+ buf = malloc(si->encryptedDigest.size);
+ if (buf == NULL)
+ return -1;
+ memcpy(buf, si->encryptedDigest.buf, si->encryptedDigest.size);
+
+ cert->signature = buf;
+ cert->signature_size = si->encryptedDigest.size;
+
+ oid = &si->digestAlgorithm.algorithm;
+ cert->hash_algo = pkey_hash_algo_to_str(pkcs7_hashalgo_oid_to_id(oid));
+
+ return 0;
+}
+
+struct pkcs7_cert *pkcs7_parse_cert(const void *raw, size_t len)
+{
+ struct pkcs7_cert *cert;
+ asn_dec_rval_t rval;
+
+ cert = malloc(sizeof(*cert));
+ if (cert == NULL)
+ return NULL;
+ memset(cert, 0, sizeof(*cert));
+
+ rval = ber_decode(0, &asn_DEF_PKCS7ContentInfo, (void **)&cert->ci,
+ raw, len);
+
+ if(rval.code != RC_OK)
+ goto err;
+
+ if (cert->ci->content->signerInfos.present == SignerInfos_PR_NOTHING)
+ goto err;
+
+ if (pkcs7_parse_si(cert) < 0)
+ goto err;
+
+ return cert;
+err:
+ pkcs7_free_cert(cert);
+ return NULL;
+}
diff --git a/libkmod/pkcs7/pkcs7_parser.h b/libkmod/pkcs7/pkcs7_parser.h
new file mode 100644
index 000000000000..3a03a34ec240
--- /dev/null
+++ b/libkmod/pkcs7/pkcs7_parser.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc., Yauheni Kaliuta
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KMOD_PKCS7_PARSER_H_
+#define KMOD_PKCS7_PARSER_H_
+
+#define EMIT_ASN_DEBUG 0
+
+#include <PKCS7ContentInfo.h>
+#include <Name.h>
+
+struct pkcs7_cert {
+ PKCS7ContentInfo_t *ci;
+ /* issuer RAW data are needed as well, so parsed separately */
+ Name_t *issuer;
+
+ const char *hash_algo;
+ uint8_t *key_id;
+ size_t key_id_size;
+ char *signer; /* copy cn there, name like in module_signature */
+ uint8_t *signature;
+ size_t signature_size;
+};
+
+struct pkcs7_cert *pkcs7_parse_cert(const void *raw, size_t len);
+void pkcs7_free_cert(struct pkcs7_cert *cert);
+
+#endif
--
2.16.2

View File

@ -1,28 +0,0 @@
From 22afe9ca4bd26287554f282cbed9a367deb77186 Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Fri, 6 Apr 2018 12:36:41 +0200
Subject: [PATCH] libkmod-signature: pkcs#7: fix crash when signer info is not
present.
Reported-by: Kazuya Saito <saito.kazuya@jp.fujitsu.com>
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
libkmod/libkmod-signature.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libkmod/libkmod-signature.c b/libkmod/libkmod-signature.c
index fae074e6dd1d..782e96f69fef 100644
--- a/libkmod/libkmod-signature.c
+++ b/libkmod/libkmod-signature.c
@@ -166,7 +166,7 @@ kmod_module_signature_info_pkcs7(const char *mem,
sig_info->key_id_len = cert->key_id_size;
sig_info->signer = cert->signer;
- sig_info->signer_len = strlen(cert->signer);
+ sig_info->signer_len = cert->signer ? strlen(cert->signer) : 0;
sig_info->algo = NULL;
sig_info->hash_algo = cert->hash_algo;
--
2.13.6