All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [RFC PATCH] Add library support for /proc/sys/kernel/tainted
@ 2018-01-22 13:12 Michael Moese
  2018-01-22 15:39 ` Cyril Hrubis
  0 siblings, 1 reply; 3+ messages in thread
From: Michael Moese @ 2018-01-22 13:12 UTC (permalink / raw)
  To: ltp

Someteimes, it is important to detect if the kernel has issued a
warning, or died. From 2.6.26 on, Linux has these inside
/proc/sys/kernel/tainted. The bitmask there can be analyzed to
detect the occurrance of these.

Signed-off-by: Michael Moese <mmoese@suse.de>
---
 include/tst_taint.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/tst_taint.c     | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)
 create mode 100644 include/tst_taint.h
 create mode 100644 lib/tst_taint.c

diff --git a/include/tst_taint.h b/include/tst_taint.h
new file mode 100644
index 000000000..b01d07d60
--- /dev/null
+++ b/include/tst_taint.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Michael Moese <mmoese@suse.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TST_TAINTED_H__
+#define TST_TAINTED_H__
+
+/*
+ * This are all flags that are supported by kernel 4.4.15
+ * see kernel/panic.c in kernel sources
+ */
+#define TST_TAINT_G     (1 <<  0) /* a module with non-GPL license loaded */
+#define TST_TAINT_F     (1 <<  1) /* a module was force-loaded */
+#define TST_TAINT_S     (1 <<  2) /* SMP with Non-SMP kernel */
+#define TST_TAINT_R     (1 <<  3) /* module force unloaded */
+#define TST_TAINT_M     (1 <<  4) /* machine check error occurred */
+#define TST_TAINT_B     (1 <<  5) /* page-release function found bad page */
+#define TST_TAINT_U     (1 <<  6) /* user requested taint flag */
+#define TST_TAINT_D     (1 <<  7) /* kernel died recently - OOPS or BUG */
+#define TST_TAINT_A     (1 <<  8) /* ACPI table has been overwritten */
+#define TST_TAINT_W     (1 <<  9) /* a warning has been issued by kernel */
+#define TST_TAINT_C     (1 << 10) /* driver from drivers/staging was loaded */
+#define TST_TAINT_I     (1 << 11) /* working around BIOS/Firmware bug */
+#define TST_TAINT_O     (1 << 12) /* out of tree module loaded */
+#define TST_TAINT_E     (1 << 13) /* unsigned module was loaded */
+#define TST_TAINT_L     (1 << 14) /* A soft lock-up has previously occurred */
+#define TST_TAINT_K     (1 << 15) /* kernel has been live-patched */
+#define TST_TAINT_X	(1 << 16) /* auxiliary taint, for distro's use */
+
+/*
+ * check if kernel is recent enough to support the tainted-flags that
+ * allow us to check if the kernel issued a warning or died
+ *
+ * returns 1 if supported, 0 otherwise
+ */
+int tst_taint_supported(void);
+
+/*
+ * read /proc/sys/kernel/tainted and return the value
+ * this function allows to be called even when the relevant flags are
+ * unsupported.
+ *
+ * returns bitmask of taint flag, or (unsigned int) -1 on read error.
+ */
+unsigned int tst_taint_read(void);
+
+/*
+ * a small helper function to check if flags specified by mask are set
+ *
+ * returns 1 if@least one of the flags is set, 0 otherwise
+ */
+int tst_taint_check_mask(unsigned int taint, unsigned int mask);
+
+#endif /* TST_TAINTED_H__ */
diff --git a/lib/tst_taint.c b/lib/tst_taint.c
new file mode 100644
index 000000000..38bf355ec
--- /dev/null
+++ b/lib/tst_taint.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <linux/version.h>
+
+#include "tst_test.h"
+#include "tst_taint.h"
+#include "tst_safe_stdio.h"
+
+#define TAINT_FILE "/proc/sys/kernel/tainted"
+
+static int taint_supported = -1;
+
+int tst_taint_supported(void)
+{
+	struct utsname uname_data;
+	int maj, min, patch;
+
+	if (uname(&uname_data) == -1)
+		return -1;
+
+	if (sscanf(uname_data.release, "%d.%d.%d-", &maj, &min, &patch) != 3)
+		fprintf(stderr, "error parsing uname information\n");
+
+	if ((maj < 2) || ((maj == 2) && (min < 26))) {
+		fprintf(stderr, "Kernel version prior to 2.6.26 detected.\n");
+		fprintf(stderr, "please check kernel output manually\n");
+		taint_supported = 0;
+	} else
+		taint_supported = 1;
+
+
+	return taint_supported;
+}
+
+unsigned int tst_taint_read(void)
+{
+	int fd;
+	unsigned int val;
+	char buffer[11];
+
+	if (taint_supported == -1)
+		tst_taint_supported();
+
+	buffer[10] = 0;
+
+	fd = SAFE_OPEN(TAINT_FILE, O_RDONLY);
+
+	val = read(fd, buffer, 10);
+	SAFE_CLOSE(fd);
+	if (val == -1) {
+		fprintf(stderr, "unable to read %s\n", TAINT_FILE);
+		return (unsigned int) -1;
+	}
+	val = safe_atoi(buffer);
+
+	return val;
+}
+
+int tst_taint_check_mask(unsigned int taint, unsigned int mask)
+{
+	if ((taint & mask) != 0)
+		return 1;
+	return 0;
+}
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [LTP] [RFC PATCH] Add library support for /proc/sys/kernel/tainted
  2018-01-22 13:12 [LTP] [RFC PATCH] Add library support for /proc/sys/kernel/tainted Michael Moese
@ 2018-01-22 15:39 ` Cyril Hrubis
  2018-01-23  9:16   ` Michael Moese
  0 siblings, 1 reply; 3+ messages in thread
From: Cyril Hrubis @ 2018-01-22 15:39 UTC (permalink / raw)
  To: ltp

Hi!
> +/*
> + * check if kernel is recent enough to support the tainted-flags that
> + * allow us to check if the kernel issued a warning or died
> + *
> + * returns 1 if supported, 0 otherwise
> + */
> +int tst_taint_supported(void);
> +
> +/*
> + * read /proc/sys/kernel/tainted and return the value
> + * this function allows to be called even when the relevant flags are
> + * unsupported.
> + *
> + * returns bitmask of taint flag, or (unsigned int) -1 on read error.
> + */
> +unsigned int tst_taint_read(void);
> +
> +/*
> + * a small helper function to check if flags specified by mask are set
> + *
> + * returns 1 if at least one of the flags is set, 0 otherwise
> + */
> +int tst_taint_check_mask(unsigned int taint, unsigned int mask);
> +
> +#endif /* TST_TAINTED_H__ */

This patch lacks information on how this API is supposed to be used
which is quite important for the review. What I mean is that, while
important, the documentation for the function parameters and return
values is not enough. What should be included is some sketch code of
this is supposed to be used from an actual test source.

> diff --git a/lib/tst_taint.c b/lib/tst_taint.c
> new file mode 100644
> index 000000000..38bf355ec
> --- /dev/null
> +++ b/lib/tst_taint.c
> @@ -0,0 +1,69 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/utsname.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +
> +#include <linux/version.h>
> +
> +#include "tst_test.h"
> +#include "tst_taint.h"
> +#include "tst_safe_stdio.h"
> +
> +#define TAINT_FILE "/proc/sys/kernel/tainted"
> +
> +static int taint_supported = -1;
> +
> +int tst_taint_supported(void)
> +{
> +	struct utsname uname_data;
> +	int maj, min, patch;
> +
> +	if (uname(&uname_data) == -1)
> +		return -1;
> +
> +	if (sscanf(uname_data.release, "%d.%d.%d-", &maj, &min, &patch) != 3)
> +		fprintf(stderr, "error parsing uname information\n");
> +
> +	if ((maj < 2) || ((maj == 2) && (min < 26))) {
> +		fprintf(stderr, "Kernel version prior to 2.6.26 detected.\n");
> +		fprintf(stderr, "please check kernel output manually\n");

These messages should go out via tst_res().

> +		taint_supported = 0;
> +	} else
> +		taint_supported = 1;

We have tst_kvercmp() exactly for this purpose, see include/tst_kvercmp.h

> +	return taint_supported;
> +}
> +
> +unsigned int tst_taint_read(void)
> +{
> +	int fd;
> +	unsigned int val;
> +	char buffer[11];
> +
> +	if (taint_supported == -1)
> +		tst_taint_supported();

So this will only cause warning to be printed into the stderr, then we
go ahead and read the file? Shouldn't we just tst_brk(TCONF, "") at this
point?

> +	buffer[10] = 0;
> +
> +	fd = SAFE_OPEN(TAINT_FILE, O_RDONLY);
> +
> +	val = read(fd, buffer, 10);
> +	SAFE_CLOSE(fd);
> +	if (val == -1) {
> +		fprintf(stderr, "unable to read %s\n", TAINT_FILE);
> +		return (unsigned int) -1;
> +	}
> +	val = safe_atoi(buffer);

What about using SAFE_FILE_SCANF() instead?

> +	return val;
> +}
> +
> +int tst_taint_check_mask(unsigned int taint, unsigned int mask)
> +{
> +	if ((taint & mask) != 0)
> +		return 1;
> +	return 0;
> +}

Hmm, should this be combined with the read function?

-- 
Cyril Hrubis
chrubis@suse.cz

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [LTP] [RFC PATCH] Add library support for /proc/sys/kernel/tainted
  2018-01-22 15:39 ` Cyril Hrubis
@ 2018-01-23  9:16   ` Michael Moese
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Moese @ 2018-01-23  9:16 UTC (permalink / raw)
  To: ltp

Hi,

On Mon, Jan 22, 2018 at 04:39:42PM +0100, Cyril Hrubis wrote:

> This patch lacks information on how this API is supposed to be used
> which is quite important for the review. What I mean is that, while
> important, the documentation for the function parameters and return
> values is not enough. What should be included is some sketch code of
> this is supposed to be used from an actual test source.

Agree. I will spend more effort on the documentation before
submitting again.


> These messages should go out via tst_res().
Agreed.

> We have tst_kvercmp() exactly for this purpose, see include/tst_kvercmp.h
Well, I tried to find this. But somehow I failed :) Thanks for pointing 
this out.

 
> > +	return taint_supported;
> > +}
> > +
> > +unsigned int tst_taint_read(void)
> > +{
> > +	int fd;
> > +	unsigned int val;
> > +	char buffer[11];
> > +
> > +	if (taint_supported == -1)
> > +		tst_taint_supported();
> 
> So this will only cause warning to be printed into the stderr, then we
> go ahead and read the file? Shouldn't we just tst_brk(TCONF, "") at this
> point?
> 
> > +	return val;
> > +}
> > +
> > +int tst_taint_check_mask(unsigned int taint, unsigned int mask)
> > +{
> > +	if ((taint & mask) != 0)
> > +		return 1;
> > +	return 0;
> > +}
> 
> Hmm, should this be combined with the read function?
I had this consideration. But maybe someone needs to compare the flags 
for two points in time, and just check if the mask matched the delta. 
In this case, doing a implicit read would not be what the user wants.
On the other hand, when this is not needed, we could save a line.

Thanks,
Michael

-- 
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-01-23  9:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-22 13:12 [LTP] [RFC PATCH] Add library support for /proc/sys/kernel/tainted Michael Moese
2018-01-22 15:39 ` Cyril Hrubis
2018-01-23  9:16   ` Michael Moese

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.