]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/objtool/special.c
Merge tag 'stream_open-5.2' of https://lab.nexedi.com/kirr/linux
[linux.git] / tools / objtool / special.c
index 50af4e1274b39d20758208a4944453c46b3aa448..4e50563d87c6466aca09ec1ec756503d97e1921a 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "builtin.h"
 #include "special.h"
 #include "warn.h"
 
@@ -42,6 +43,7 @@
 #define ALT_NEW_LEN_OFFSET     11
 
 #define X86_FEATURE_POPCNT (4*32+23)
+#define X86_FEATURE_SMAP   (9*32+20)
 
 struct special_entry {
        const char *sec;
@@ -110,6 +112,22 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
                 */
                if (feature == X86_FEATURE_POPCNT)
                        alt->skip_orig = true;
+
+               /*
+                * If UACCESS validation is enabled; force that alternative;
+                * otherwise force it the other way.
+                *
+                * What we want to avoid is having both the original and the
+                * alternative code flow at the same time, in that case we can
+                * find paths that see the STAC but take the NOP instead of
+                * CLAC and the other way around.
+                */
+               if (feature == X86_FEATURE_SMAP) {
+                       if (uaccess)
+                               alt->skip_orig = true;
+                       else
+                               alt->skip_alt = true;
+               }
        }
 
        orig_rela = find_rela_by_dest(sec, offset + entry->orig);