On Sat, Aug 30, 2014 at 10:56:26AM +0800, Xishi Qiu wrote:
> Here is my test code.
> #include <sys/types.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/stat.h>
> 
> int main(int ac, char **av)
> {
>     int test;
>     char *path = "/tmp/stat01";  // I have created stat01 before
>     test = stat(path, -1);
>     printf("stat=%d\n", test);
>     return 0;
> }
> 
> Then I use strace to trace it.
> ....
> ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 
> {B115200 opost isig icanon echo ...}) = 0
> ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 
> {B115200 opost isig icanon echo ...}) = 0
> stat64("/tmp/stat01", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
> --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xffffffff} ---  
> // This is the segmentfault
> +++ killed by SIGSEGV +++
> sh-4.2#
> 
> Here is uclibc code.
> int stat(const char *file_name, struct stat *buf)
> {
>       int result;
> # ifdef __NR_stat64
>       /* normal stat call has limited values for various stat elements
>        * e.g. uid device major/minor etc.
>        * so we use 64 variant if available
>        * in order to get newer versions of stat elements
>        */
>       struct kernel_stat64 kbuf;
>       result = INLINE_SYSCALL(stat64, 2, file_name, &kbuf);  // return success
>       if (result == 0) {
>               __xstat32_conv(&kbuf, buf);  // memset address(-1) cause the 
> segmentfault
>       }
> # else
>       struct kernel_stat kbuf;
> 
>       result = INLINE_SYSCALL(stat, 2, file_name, &kbuf);
>       if (result == 0) {
>               __xstat_conv(&kbuf, buf);
>       }
> # endif /* __NR_stat64 */
>       return result;
> }
> #endif /* __NR_fstat64 */
> libc_hidden_def(stat)
> 
> Is this a bug or we should not pass a invalid parameter to stat()?

Would you expect it to work if you passed (struct stat *)rand() to
stat? No, because it would potentially clobber a random part of your
program's memory. So why should passing -1 be safe? This is not a bug
in uclibc, just in the caller that's passing an invalid pointer, which
is (always) undefined behavior.

Rich
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to