fix long long cast in pte macro
RFC PATCH 1/1 fix long long cast in pte macro
Hi,
PaX Team sent me this patch, which I think is valid. It fixes a long long cast in the pte macro for i386 and mips. If nobody has any objections, I will apply it to 2.4. I'd also like someone to check whether it's needed for 2.6 and to forward port it if needed.
Thanks,
Willy
--
the current idiom used for initializing a structure of two unsigned longs from unsigned long long is wrong, it effectively loses the upper 32 bits which in this particular case could turn a non-executable PTE into an executable one on NX capable i386 (i.e., it's a potential security bug). fortunately the in-tree users in 2.4 (drivers/char/drm-4.0/ffb_drv.c and arch/mips/baget/baget.c) are not affected.
include/asm-i386/page.h +2 -1
@@ -41,11 +41,13 @@typedef struct {unsigned long long pmd; }pmd_t ;typedef struct {unsigned long long pgd; }pgd_t ;#define pte_val (x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) +#define __pte (x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })#else typedef struct {unsigned long pte_low; }pte_t ;typedef struct {unsigned long pmd; }pmd_t ;typedef struct {unsigned long pgd; }pgd_t ;#define pte_val (x) ((x).pte_low) +#define __pte (x) ((pte_t) { (x) } )#endif #define PTE_MASK PAGE_MASK
@@ -55,7 +57,6 @@#define pgd_val (x) ((x).pgd)#define pgprot_val (x) ((x).pgprot) -#define __pte (x) ((pte_t) { (x) } )#define __pmd (x) ((pmd_t) { (x) } )#define __pgd (x) ((pgd_t) { (x) } )#define __pgprot (x) ((pgprot_t) { (x) } )
include/asm-mips/page.h +3 -1
@@ -77,13 +77,16 @@#ifdef CONFIG_CPU_MIPS32 typedef struct {unsigned long pte_low, pte_high; }pte_t ;#define pte_val (x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) +#define __pte (x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })#else typedef struct {unsigned long long pte_low; }pte_t ;#define pte_val (x) ((x).pte_low) +#define __pte (x) ((pte_t) { (x) } )#endif #else typedef struct {unsigned long pte_low; }pte_t ;#define pte_val (x) ((x).pte_low) +#define __pte (x) ((pte_t) { (x) } )#endif typedef struct {unsigned long pmd; }pmd_t ;
@@ -96,7 +99,6 @@#define ptep_buddy (x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t))) -#define __pte (x) ((pte_t) { (x) } )#define __pmd (x) ((pmd_t) { (x) } )#define __pgd (x) ((pgd_t) { (x) } )#define __pgprot (x) ((pgprot_t) { (x) } )
Quoted 4 lines · Willy Tarreau
PaX Team sent me this patch, which I think is valid. It fixes a long long cast in the pte macro for i386 and mips. If nobody has any objections, I will apply it to 2.4. I'd also like someone to check whether it's needed for 2.6 and to forward port it if needed.
Yes, a similar 2.6 patch is needed as well, I'll care of that. For the MIPS segment of your 2.4 patch:
Ralf
Quoted 7 lines · Ralf Baechle
Quoted 4 lines · Willy Tarreau
PaX Team sent me this patch, which I think is valid. It fixes a long long cast in the pte macro for i386 and mips. If nobody has any objections, I will apply it to 2.4. I'd also like someone to check whether it's needed for 2.6 and to forward port it if needed.
Quoted 6 lines
Yes, a similar 2.6 patch is needed as well, I'll care of that. For the MIPS segment of your 2.4 patch:
Acked-by Ralf Baechle <[email protected]>Ralf
Thanks Ralf,
Willy