]> granicus.if.org Git - php/commitdiff
Fix pointer UB in dynasm
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 23 Mar 2020 10:03:56 +0000 (11:03 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 23 Mar 2020 10:03:56 +0000 (11:03 +0100)
Looks like newer GCC versions started warning about this.

ext/opcache/jit/dynasm/dasm_x86.h

index 32874b40b9559768da796d462f74f53e5570358b..9cde63713b606d76e4801506c613bb08ea43c8f1 100644 (file)
@@ -79,6 +79,9 @@ struct dasm_State {
 /* The size of the core structure depends on the max. number of sections. */
 #define DASM_PSZ(ms)   (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
 
+/* Perform potentially overflowing pointer operations in a way that avoids UB. */
+#define DASM_PTR_SUB(p1, off) ((void *) ((uintptr_t) (p1) - sizeof(*p1) * (uintptr_t) (off)))
+#define DASM_PTR_ADD(p1, off) ((void *) ((uintptr_t) (p1) + sizeof(*p1) * (uintptr_t) (off)))
 
 /* Initialize DynASM state. */
 void dasm_init(Dst_DECL, int maxsection)
@@ -98,7 +101,7 @@ void dasm_init(Dst_DECL, int maxsection)
   D->maxsection = maxsection;
   for (i = 0; i < maxsection; i++) {
     D->sections[i].buf = NULL;  /* Need this for pass3. */
-    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
+    D->sections[i].rbuf = DASM_PTR_SUB(D->sections[i].buf, DASM_SEC2POS(i));
     D->sections[i].bsize = 0;
     D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */
   }
@@ -377,7 +380,7 @@ int dasm_encode(Dst_DECL, void *buffer)
   for (secnum = 0; secnum < D->maxsection; secnum++) {
     dasm_Section *sec = D->sections + secnum;
     int *b = sec->buf;
-    int *endb = sec->rbuf + sec->pos;
+    int *endb = DASM_PTR_ADD(sec->rbuf, sec->pos);
 
     while (b != endb) {
       dasm_ActList p = D->actionlist + *b++;