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>] [day] [month] [year] [list]
Date:	Thu, 9 Apr 2009 18:30:53 +0530
From:	Maxin John <maxin.john@...il.com>
To:	linux-kernel@...r.kernel.org
Cc:	kernel-janitors@...r.kernel.org, ralf@...ux-mips.org
Subject: [PATCH] cacheflush system call not returning -EINVAL

Hi,

cacheflush man page states that cacheflush() will set  EINVAL if cache
parameter is not one of ICACHE, DCACHE, or BCACHE.
In order to confirm this behavior, I have executed the below listed
program (cacheflush_check.c) in Toshiba RBTX4937 board (MIPS) with
2.6.29.1 kernel.

=================================================================
 /*
  *  cacheflush_check.c
  *
  *  Description:
  * Tests EINVAL error of cacheflush system call
  *
  *  Expected behaviour:
  * cacheflush() should return -EINVAL when cache parameter is not one
of ICACHE, DCACHE, or BCACHE.
  *
  */

#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#if defined __mips__
#include <asm/cachectl.h>

int cacheflush(char *addr, int nbytes, int cache)
{
        return syscall(__NR_cacheflush, addr, nbytes, cache);
}
#endif /* __mips__ */


int main()
{
        /* cacheflush man page states that cacheflush() is only
applicable to MIPS architecture */

        char *addr = NULL;

        /* Create some user address range */
        addr = malloc(getpagesize());
        if (addr == NULL) {
                printf("Malloc error\n");
                exit(-1);
        }

        /* Invokes cacheflush() with proper parameters */
        cacheflush(addr, getpagesize(), ICACHE);
        cacheflush(addr, getpagesize(), DCACHE);
        cacheflush(addr, getpagesize(), BCACHE);

       /* Tests whether cacheflush() returns -EINVAL */
        if (cacheflush(addr, getpagesize(), 0) < 0) {
                if (errno == EINVAL) {
                        printf("cacheflush EINVAL : TEST PASS\n");
                        exit(0);
                } else {
                        printf("cacheflush EINVAL : TEST FAIL\n");
                }
        }
        printf("cacheflush EINVAL : TEST FAIL\n");
        return -1;
}
=======================================================

I have observed that the test failed when executed in target board.

-bash-3.2# ./cacheflush_err_check
cacheflush EINVAL : TEST FAIL

I have checked the 'arch/mips/mm/cache.c' and observed that the
cacheflush() implementation is not setting EINVAL.
So, I have modified this file by including these two lines for EINVAL.
 if ( (cache != ICACHE) && (cache != DCACHE) && (cache != BCACHE) )
            return -EINVAL;

After this modification, I have straced the cacheflush_check program
with the modified kernel:
strace ./cacheflush_check
....
set_thread_area(0x2aacd3e0)             = 0
mprotect(0x2ac1a000, 28672, PROT_READ)  = 0
mprotect(0x2aad4000, 4096, PROT_READ)   = 0
brk(0)                                  = 0x411000
brk(0x432000)                           = 0x432000
syscall(0x1033, 0x411050, 0x1000, 0x1, 0x418e90, 0x2aac5280, 0x418e90,
0x2aad4ef0) = 0
syscall(0x1033, 0x411050, 0x1000, 0x2, 0x418e90, 0x2aac5280, 0x418e90,
0x2aad4ef0) = 0
syscall(0x1033, 0x411050, 0x1000, 0x3, 0x418e90, 0x2aac5280, 0x418e90,
0x2aad4ef0) = 0
syscall(0x1033, 0x411050, 0x1000, 0, 0x418e90, 0x2aac5280, 0x418e90,
0x2aad4ef0) = -1 EINVAL (Invalid argument)
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0
old_mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0x2ac2a000
....

The test passes when executed in the modified kernel.I have tested
this patch and seen no adverse effects.
Cheers,

Signed-off-by: Maxin B. John <maxinbjohn@...il.com>

--------
diff -uNr linux-2.6.29.1/arch/mips/mm/cache.c
linux-2.6.29.1-a/arch/mips/mm/cache.c
--- linux-2.6.29.1/arch/mips/mm/cache.c 2009-04-03 02:25:27.000000000 +0530
+++ linux-2.6.29.1-a/arch/mips/mm/cache.c       2009-04-09
18:24:50.000000000 +0530
@@ -64,6 +64,10 @@
 {
        if (bytes == 0)
                return 0;
+
+       if ( (cache != ICACHE) && (cache != DCACHE) && (cache != BCACHE) )
+                return -EINVAL;
+
        if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes))
                return -EFAULT;

----------
--
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