lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 2 Feb 2015 15:05:03 +0100
From:	Ricardo Ribalda Delgado <ricardo.ribalda@...il.com>
To:	Geert Uytterhoeven <geert@...ux-m68k.org>
Cc:	Arnd Bergmann <arnd@...db.de>,
	Linux-Arch <linux-arch@...r.kernel.org>,
	LKML <linux-kernel@...r.kernel.org>
Subject: Re: Can this be a invalid memory access? (was: Re: [PATCH]
 spi/xilinx: Cast ioread32/iowrite32 function pointers)

Hello Geert

On Mon, Feb 2, 2015 at 2:04 PM, Geert Uytterhoeven <geert@...ux-m68k.org> wrote:

>> void * pvar=varB;
>
> ... = &varB;
>
>> *pvar = ioread8(valid_memory);
>>
>> Depending if ioread8 returns a u8 or a unsigned int, aren't we also
>> accessing varC?
>>
>> Could not this be a problem?
>
> Please try to compile the above.
> The compiler will tell you you cannot dereference a void pointer.
>
> Now, replace "void *" by "unsigned int *".
> After that, varC will indeed be overwritten. But the compiler will still have
> warned you that you assigned the address of an u8 variable to an
> unsigned int pointer.

I am still a bit worried, that the same function has different
prototypes and implementations depending on the arch.  But
"unfortunately" I cannot make a counter-example that can cause an
error.

So far, the closest I have get is this:

ricardo@...pili:/tmp$ cat arch.c
#include <stdint.h>

unsigned int my_ioread8(){
return 0xdeadbeef;
}

void test_read();
int main(int argc, char *argv[]){

test_read();
return 0;
}


ricardo@...pili:/tmp$ cat io.h
#ifndef IO_H
#define IO_H
#include <stdint.h>

uint8_t my_ioread8();

#endif


ricardo@...pili:/tmp$ cat driver.c
#include "io.h"
#include <stdint.h>
#include <stdio.h>

void test_read(){
uint8_t varA=0x1;
uint8_t varB=0x2;
uint8_t varC=0x3;

varB = my_ioread8();

fprintf(stdout, "varA=%d varB=%d varC=%d\n",
varA, varB, varC);
}

It does not produce any error at build time:
 ricardo@...pili:/tmp$ make
cc -Wall   -c -o arch.o arch.c
cc -Wall   -c -o driver.o driver.c
cc -Wall arch.o driver.o -o test

and it works fine on amd86

ricardo@...pili:/tmp$ ./test
varA=1 varB=239 varC=3

But in the hypothetical case where the calling convention will be
different for unsigned int and u8, there will be an issue....

The reason that I am interested in this is that I want to be able to
have code like:

struct  priv_data{
   u16 (read *)(void __iomem *);
};

endian=detect_endianness()

if (endian == BIG)
  priv->read= ioread16be;
else
  priv->read= ioread16;

data = priv->read(iomem+DATA);

Unfortunately, with the current code, this does not work on all the
arches, and the workaround is having wrappers for ioread and iowrite
like in drivers/spi/spi-xilinx.c

static void xspi_write32(u32 val, void __iomem *addr)
{
iowrite32(val, addr);
}

static void xspi_write32_be(u32 val, void __iomem *addr)
{
iowrite32be(val, addr);
}



Regards




-- 
Ricardo Ribalda
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ