Blame SOURCES/0682-detect-virt-do-not-try-to-read-all-of-proc-cpuinfo.patch

17b0f1
From 7bb8b4580b19f1d48e9beb201387d6c321b3ae7b Mon Sep 17 00:00:00 2001
17b0f1
From: Jan Synacek <jsynacek@redhat.com>
17b0f1
Date: Tue, 2 Oct 2018 16:07:00 +0200
17b0f1
Subject: [PATCH] detect-virt: do not try to read all of /proc/cpuinfo
17b0f1
17b0f1
Quoting #10074:
17b0f1
> detect_vm_uml() reads /proc/cpuinfo with read_full_file()
17b0f1
> read_full_file() has a file max limit size of READ_FULL_BYTES_MAX=(4U*1024U*1024U)
17b0f1
> Unfortunately, the size of my /proc/cpuinfo is bigger, approximately:
17b0f1
> echo $(( 4* $(cat /proc/cpuinfo | wc -c)))
17b0f1
> 9918072
17b0f1
> This causes read_full_file() to fail and the Condition test fallout.
17b0f1
17b0f1
Let's just read line by line until we find an intersting line. This also
17b0f1
helps if not running under UML, because we avoid reading as much data.
17b0f1
17b0f1
(cherry picked from commit 6058516a14ada1748313af6783f5b4e7e3006654)
17b0f1
Resolves: #1631531
17b0f1
---
17b0f1
 src/shared/virt.c | 40 ++++++++++++++++++++++++++++++++--------
17b0f1
 1 file changed, 32 insertions(+), 8 deletions(-)
17b0f1
17b0f1
diff --git a/src/shared/virt.c b/src/shared/virt.c
17b0f1
index 55a6ca90fb..e6362f6645 100644
17b0f1
--- a/src/shared/virt.c
17b0f1
+++ b/src/shared/virt.c
17b0f1
@@ -185,7 +185,8 @@ static int detect_vm_dmi(const char **_id) {
17b0f1
 
17b0f1
 /* Returns a short identifier for the various VM implementations */
17b0f1
 int detect_vm(const char **id) {
17b0f1
-        _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL;
17b0f1
+        _cleanup_free_ char *domcap = NULL;
17b0f1
+        _cleanup_fclose_ FILE *f = NULL;
17b0f1
         static thread_local int cached_found = -1;
17b0f1
         static thread_local const char *cached_id = NULL;
17b0f1
         const char *_id = NULL;
17b0f1
@@ -252,13 +253,36 @@ int detect_vm(const char **id) {
17b0f1
         }
17b0f1
 
17b0f1
         /* Detect User-Mode Linux by reading /proc/cpuinfo */
17b0f1
-        r = read_full_file("/proc/cpuinfo", &cpuinfo_contents, NULL);
17b0f1
-        if (r < 0)
17b0f1
-                return r;
17b0f1
-        if (strstr(cpuinfo_contents, "\nvendor_id\t: User Mode Linux\n")) {
17b0f1
-                _id = "uml";
17b0f1
-                r = 1;
17b0f1
-                goto finish;
17b0f1
+        f = fopen("/proc/cpuinfo", "re");
17b0f1
+        if (!f) {
17b0f1
+                if (errno == ENOENT) {
17b0f1
+                        log_debug("/proc/cpuinfo not found, assuming no UML virtualization.");
17b0f1
+                        r = 0;
17b0f1
+                        goto finish;
17b0f1
+                }
17b0f1
+                return -errno;
17b0f1
+        }
17b0f1
+        for (;;) {
17b0f1
+                _cleanup_free_ char *line = NULL;
17b0f1
+                const char *t;
17b0f1
+
17b0f1
+                r = read_line(f, LONG_LINE_MAX, &line);
17b0f1
+                if (r < 0)
17b0f1
+                        return r;
17b0f1
+                if (r == 0)
17b0f1
+                        break;
17b0f1
+
17b0f1
+                t = startswith(line, "vendor_id\t: ");
17b0f1
+                if (t) {
17b0f1
+                        if (startswith(t, "User Mode Linux")) {
17b0f1
+                                log_debug("UML virtualization found in /proc/cpuinfo");
17b0f1
+                                _id = "uml";
17b0f1
+                                r = 1;
17b0f1
+                                goto finish;
17b0f1
+                        }
17b0f1
+
17b0f1
+                        break;
17b0f1
+                }
17b0f1
         }
17b0f1
 
17b0f1
 #if defined(__s390__)