Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Geert Uytterhoeven
Hi Ricardo,

On Mon, Feb 2, 2015 at 3:05 PM, Ricardo Ribalda Delgado
 wrote:
> On Mon, Feb 2, 2015 at 2:04 PM, Geert Uytterhoeven  
> wrote:
>>> void * pvar=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@neopili:/tmp$ cat arch.c
> #include 

You should include io.h here...

>
> unsigned int my_ioread8(){

... then the compiler will complain here.

> return 0xdeadbeef;
> }
>
> void test_read();
> int main(int argc, char *argv[]){
>
> test_read();
> return 0;
> }
>
>
> ricardo@neopili:/tmp$ cat io.h
> #ifndef IO_H
> #define IO_H
> #include 
>
> uint8_t my_ioread8();
>
> #endif
>
>
> ricardo@neopili:/tmp$ cat driver.c
> #include "io.h"
> #include 
> #include 
>
> 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@neopili:/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@neopili:/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

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Ricardo Ribalda Delgado
Hello Geert

On Mon, Feb 2, 2015 at 2:04 PM, Geert Uytterhoeven  wrote:

>> void * pvar=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@neopili:/tmp$ cat arch.c
#include 

unsigned int my_ioread8(){
return 0xdeadbeef;
}

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

test_read();
return 0;
}


ricardo@neopili:/tmp$ cat io.h
#ifndef IO_H
#define IO_H
#include 

uint8_t my_ioread8();

#endif


ricardo@neopili:/tmp$ cat driver.c
#include "io.h"
#include 
#include 

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@neopili:/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@neopili:/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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Geert Uytterhoeven
Hi Ricardo,

On Mon, Feb 2, 2015 at 1:49 PM, Ricardo Ribalda Delgado
 wrote:
> Regarding ioread8 et al.
>
> On include/asm-generic/io.h is defined as:
> extern unsigned int ioread8(void __iomem *);
>
> On include/asm-generic/io.h:
> static inline u8 ioread8(const volatile void __iomem *addr)
>
> Please ignore the qualifiers right now. The first function returns an
> unsigned integer, the second a u8.
>
> Through #ifdefs, different arches uses the first or the second definitions.
>
> If we consider this code:
>
> u8 varA;
> u8 varB;
> u8 varC;
> void * pvar=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.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Ricardo Ribalda Delgado
Hello

Regarding ioread8 et al.

On include/asm-generic/io.h is defined as:
extern unsigned int ioread8(void __iomem *);

On include/asm-generic/io.h:
static inline u8 ioread8(const volatile void __iomem *addr)

Please ignore the qualifiers right now. The first function returns an
unsigned integer, the second a u8.

Through #ifdefs, different arches uses the first or the second definitions.

If we consider this code:

u8 varA;
u8 varB;
u8 varC;
void * pvar=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?

If I decide to send a patch and fix it, is there a clever script that
I can run on my x86 computer to test if the patch works on all arches?


Thanks

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


Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Geert Uytterhoeven
Hi Ricardo,

On Mon, Feb 2, 2015 at 3:05 PM, Ricardo Ribalda Delgado
ricardo.riba...@gmail.com wrote:
 On Mon, Feb 2, 2015 at 2:04 PM, Geert Uytterhoeven ge...@linux-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@neopili:/tmp$ cat arch.c
 #include stdint.h

You should include io.h here...


 unsigned int my_ioread8(){

... then the compiler will complain here.

 return 0xdeadbeef;
 }

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

 test_read();
 return 0;
 }


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

 uint8_t my_ioread8();

 #endif


 ricardo@neopili:/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@neopili:/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@neopili:/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

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Ricardo Ribalda Delgado
Hello Geert

On Mon, Feb 2, 2015 at 2:04 PM, Geert Uytterhoeven ge...@linux-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@neopili:/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@neopili:/tmp$ cat io.h
#ifndef IO_H
#define IO_H
#include stdint.h

uint8_t my_ioread8();

#endif


ricardo@neopili:/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@neopili:/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@neopili:/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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Ricardo Ribalda Delgado
Hello

Regarding ioread8 et al.

On include/asm-generic/io.h is defined as:
extern unsigned int ioread8(void __iomem *);

On include/asm-generic/io.h:
static inline u8 ioread8(const volatile void __iomem *addr)

Please ignore the qualifiers right now. The first function returns an
unsigned integer, the second a u8.

Through #ifdefs, different arches uses the first or the second definitions.

If we consider this code:

u8 varA;
u8 varB;
u8 varC;
void * pvar=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?

If I decide to send a patch and fix it, is there a clever script that
I can run on my x86 computer to test if the patch works on all arches?


Thanks

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


Re: Can this be a invalid memory access? (was: Re: [PATCH] spi/xilinx: Cast ioread32/iowrite32 function pointers)

2015-02-02 Thread Geert Uytterhoeven
Hi Ricardo,

On Mon, Feb 2, 2015 at 1:49 PM, Ricardo Ribalda Delgado
ricardo.riba...@gmail.com wrote:
 Regarding ioread8 et al.

 On include/asm-generic/io.h is defined as:
 extern unsigned int ioread8(void __iomem *);

 On include/asm-generic/io.h:
 static inline u8 ioread8(const volatile void __iomem *addr)

 Please ignore the qualifiers right now. The first function returns an
 unsigned integer, the second a u8.

 Through #ifdefs, different arches uses the first or the second definitions.

 If we consider this code:

 u8 varA;
 u8 varB;
 u8 varC;
 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.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/