naccyde / rpms / systemd

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