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