File module-init-tools-suse.diff of Package module-init-tools
This patch contains suse-specific changes against upstream commit 768b9984b254d0dbb3f21f5a75adeb2a8bab1edf
Index: module-init-tools-3.15/doc/modprobe.conf.sgml
===================================================================
--- module-init-tools-3.15.orig/doc/modprobe.conf.sgml
+++ module-init-tools-3.15/doc/modprobe.conf.sgml
@@ -205,6 +205,19 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>allow_unsupported_modules <replaceable>[0|1]</replaceable>
+ </term>
+ <listitem>
+ <para>
+ In SUSE kernels, every kernel module has a flag 'supported'. If
+ this flag is not set loading this module will taint your kernel.
+ Setting this option to 0 disables loading of unsupported modules
+ and avoids tainting the kernel. This is typically set in
+ <filename>/etc/modprobe.d/unsupported-modules</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
Index: module-init-tools-3.15/doc/modprobe.sgml
===================================================================
--- module-init-tools-3.15.orig/doc/modprobe.sgml
+++ module-init-tools-3.15/doc/modprobe.sgml
@@ -441,9 +441,28 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--allow-unsupported-modules</option>
+ </term>
+ <listitem>
+ <para>
+ Load unsupported modules even if disabled in configuration.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
+ <title>RETURN VALUE</title>
+
+ <para>
+ <command>modprobe</command> returns 0 on success, 1 on an unspecified
+ error and 2 if the module is not supported. Use the
+ <option>--allow-unsupported-modules</option> option to force
+ using an unsupported module.
+ </para>
+ </refsect1>
+ <refsect1>
<title>ENVIRONMENT</title>
<para>
The MODPROBE_OPTIONS environment variable can also be used to
Index: module-init-tools-3.15/logging.c
===================================================================
--- module-init-tools-3.15.orig/logging.c
+++ module-init-tools-3.15/logging.c
@@ -57,13 +57,15 @@ void error(const char *fmt, ...)
va_end(arglist);
}
+/* can be overriden for different kinds of errors */
+int fatal_exit_code = 1;
void fatal(const char *fmt, ...)
{
va_list arglist;
va_start(arglist, fmt);
message("FATAL: ", fmt, &arglist);
va_end(arglist);
- exit(1);
+ exit(fatal_exit_code);
}
/* If we don't flush, then child processes print before we do */
Index: module-init-tools-3.15/logging.h
===================================================================
--- module-init-tools-3.15.orig/logging.h
+++ module-init-tools-3.15/logging.h
@@ -10,6 +10,9 @@ extern int quiet;
/* Do we want informative messages as well as errors? */
extern int verbose;
+/* Exit code returned by fatal() */
+extern int fatal_exit_code;
+
#ifdef __GNUC__
#define _printf __attribute__((format(printf, 1, 2)))
#else
Index: module-init-tools-3.15/modprobe.c
===================================================================
--- module-init-tools-3.15.orig/modprobe.c
+++ module-init-tools-3.15/modprobe.c
@@ -55,6 +55,9 @@
/* NOTE: in the future, binary indexes will always be used */
static int use_binary_indexes = 1; /* default to enabled. */
+/* Allow loading of unsupported modules? */
+static int allow_unsupported = 1;
+
/* Limit do_softdep/do_modprobe recursion.
* This is a simple way to handle dependency loops
* caused by poorly written softdep commands.
@@ -84,6 +87,7 @@ typedef enum
mit_strip_modversion = 256,
mit_resolve_alias = 512
+ ,mit_force_allow_unsupported = 1<<20
} modprobe_flags_t;
#ifndef MODULE_DIR
@@ -392,6 +396,23 @@ static void clear_magic(struct elf_file
}
}
+static int module_supported(struct elf_file *module)
+{
+ struct string_table *tbl;
+ int j;
+
+ /* Grab from new-style .modinfo section. */
+ tbl = module->ops->load_strings(module, ".modinfo", NULL);
+ for (j = 0; tbl && j < tbl->cnt; j++) {
+ const char *p = tbl->str[j];
+ if (streq(p, "supported=yes") ||
+ streq(p, "supported=external")) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* keep track of module options from config file(s) */
struct module_options
{
@@ -1184,6 +1205,16 @@ static int parse_config_file(const char
if (streq(tmp, "no"))
use_binary_indexes = 0;
}
+ } else if (strcmp(cmd, "allow_unsupported_modules") == 0) {
+ const char *option = strsep_skipspace(&ptr, "\t ");
+ if (!option)
+ grammar(cmd, filename, linenum);
+ else if (streq(option, "yes") || streq(option, "1"))
+ allow_unsupported = 1;
+ else if (streq(option, "no") || streq(option, "0"))
+ allow_unsupported = 0;
+ else
+ goto syntax_error;
} else {
syntax_error:
grammar(cmd, filename, linenum);
@@ -1778,6 +1809,17 @@ static int insmod(struct list_head *list
strerror(errno));
goto out;
}
+ /* Supported? */
+ if (!allow_unsupported && !module_supported(module)) {
+ if (error == fatal)
+ fatal_exit_code = 2;
+ error("module '%s' is unsupported\n"
+ "Use --allow-unsupported or set allow_unsupported_modules to 1 in\n"
+ "/etc/modprobe.d/10-unsupported-modules.conf\n",
+ mod->filename);
+ goto out;
+ }
+
if (flags & mit_strip_modversion)
module->ops->strip_section(module, "__versions");
if (flags & mit_strip_vermagic)
@@ -2008,6 +2050,17 @@ static int do_modprobe(const char *modna
LIST_HEAD(list);
int failed = 0;
+ if (flags & mit_force_allow_unsupported)
+ allow_unsupported = 1;
+ /* Be nice to people running non-suse kernels and allow
+ * unsupported modules */
+ if (!allow_unsupported) {
+ if (access("/proc/sys/kernel/", F_OK) == 0 &&
+ access("/proc/sys/kernel/unsupported", F_OK) == -1 &&
+ errno == ENOENT)
+ allow_unsupported = 1;
+ }
+
matching_aliases = find_aliases(conf->aliases, modname);
/* No luck? Try symbol names, if starts with symbol:. */
@@ -2113,6 +2166,7 @@ static const struct option options[] = {
{ "force-modversion", 0, NULL, 2 },
{ "first-time", 0, NULL, 3 },
{ "dump-modversions", 0, NULL, 4 },
+ { "allow-unsupported-modules", 0, NULL, 128 },
{ NULL, 0, NULL, 0 } };
int main(int argc, char *argv[])
@@ -2219,6 +2273,9 @@ int main(int argc, char *argv[])
case 4:
dump_modver = 1;
break;
+ case 128:
+ flags |= mit_force_allow_unsupported;
+ break;
default:
print_usage(argv[0]);
}
Index: module-init-tools-3.15/modprobe.d.5
===================================================================
--- module-init-tools-3.15.orig/modprobe.d.5
+++ module-init-tools-3.15/modprobe.d.5
@@ -1 +1 @@
-.so modprobe.conf.5
+.so man5/modprobe.conf.5
Index: module-init-tools-3.15/zlibsupport.c
===================================================================
--- module-init-tools-3.15.orig/zlibsupport.c
+++ module-init-tools-3.15/zlibsupport.c
@@ -12,6 +12,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <stdio.h>
+#include <string.h>
#include "zlibsupport.h"
#include "logging.h"
@@ -19,52 +21,35 @@
#ifdef CONFIG_USE_ZLIB
#include <zlib.h>
+#endif
-void *grab_contents(gzFile *gzfd, unsigned long *size)
+#ifdef CONFIG_USE_ZLIB
+static int check_gz_magic(int fd)
{
- unsigned int max = 16384;
- void *buffer = NOFAIL(malloc(max));
- int ret;
+ unsigned char magic[2];
- *size = 0;
- while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
- *size += ret;
- if (*size == max)
- buffer = NOFAIL(realloc(buffer, max *= 2));
- }
- if (ret < 0) {
- free(buffer);
- buffer = NULL;
- }
-
- return buffer;
+ if (read(fd, magic, 2) != 2)
+ return -1;
+ lseek(fd, 0, SEEK_SET);
+ if (magic[0] == 0x1f && magic[1] == 0x8b)
+ return 1;
+ return 0;
}
-/* gzopen handles uncompressed files transparently. */
-void *grab_file(const char *filename, unsigned long *size)
+static char *tmpdir(void)
{
- gzFile gzfd;
- void *buffer;
+ static char *TMPDIR;
- errno = 0;
- gzfd = gzopen(filename, "rb");
- if (!gzfd) {
- if (errno == ENOMEM)
- fatal("Memory allocation failure in gzopen\n");
- return NULL;
- }
- buffer = grab_contents(gzfd, size);
- gzclose(gzfd);
- return buffer;
+ if (TMPDIR)
+ return TMPDIR;
+ TMPDIR = getenv("TMPDIR");
+ if (!TMPDIR)
+ TMPDIR = "/tmp";
+ return TMPDIR;
}
+#endif
-void release_file(void *data, unsigned long size)
-{
- free(data);
-}
-#else /* ... !CONFIG_USE_ZLIB */
-
-void *grab_fd(int fd, unsigned long *size)
+void *do_grab_fd(int fd, unsigned long *size)
{
struct stat st;
void *map;
@@ -80,6 +65,60 @@ void *grab_fd(int fd, unsigned long *siz
return map;
}
+void *grab_fd(int fd, unsigned long *size)
+{
+#ifdef CONFIG_USE_ZLIB
+ int magic = check_gz_magic(fd);
+ if (magic == -1)
+ return NULL;
+ if (magic) {
+ gzFile gzfd;
+ int tmp;
+ char buffer[4096];
+ char *template;
+ int r, w;
+ void *ret = NULL;
+
+ template = NOFAIL(malloc(strlen(tmpdir()) + sizeof("/m-i-t.XXXXXX")));
+ sprintf(template, "%s/m-i-t.XXXXXX", tmpdir());
+ gzfd = gzdopen(dup(fd), "rb");
+ if (!gzfd) {
+ if (errno == ENOMEM)
+ fatal("Memory allocation failure in gzdopen\n");
+ goto out_template;
+ }
+ tmp = mkstemp(template);
+ if (tmp == -1)
+ goto out_template;
+
+ while ((r = gzread(gzfd, buffer, sizeof(buffer))) > 0) {
+ char *p = buffer;
+ do {
+ w = write(tmp, p, r);
+ if (w > 0) {
+ r -= w;
+ p += w;
+ }
+ } while (w > 0 || (w == -1 && errno == EINTR));
+ if (w == -1)
+ goto out;
+ }
+ if (r < 0)
+ goto out;
+ gzclose(gzfd);
+ ret = do_grab_fd(tmp, size);
+out:
+ close(tmp);
+ unlink(template);
+out_template:
+ free(template);
+ return ret;
+ } else
+#endif
+ return do_grab_fd(fd, size);
+}
+
+
void *grab_file(const char *filename, unsigned long *size)
{
int fd;
@@ -97,4 +136,4 @@ void release_file(void *data, unsigned l
{
munmap(data, size);
}
-#endif
+