diff mbox series

getdents02: Add case for errno EFAULT

Message ID 20240819082213.2150403-1-maxj.fnst@fujitsu.com
State Accepted
Headers show
Series getdents02: Add case for errno EFAULT | expand

Commit Message

Ma Xinjian Aug. 19, 2024, 8:22 a.m. UTC
Currently there is no case for EFAULT, so a new case is added.

Signed-off-by: Ma Xinjian <maxj.fnst@fujitsu.com>
---
 testcases/kernel/syscalls/getdents/getdents02.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Avinesh Kumar Aug. 20, 2024, 7:31 a.m. UTC | #1
Hi,

Reviewed-by: Avinesh Kumar <akumar@suse.de>


On Monday, August 19, 2024 10:22:13 AM GMT+2 Ma Xinjian via ltp wrote:
> Currently there is no case for EFAULT, so a new case is added.
> 
> Signed-off-by: Ma Xinjian <maxj.fnst@fujitsu.com>
> ---
>  testcases/kernel/syscalls/getdents/getdents02.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/testcases/kernel/syscalls/getdents/getdents02.c b/testcases/kernel/syscalls/getdents/getdents02.c
> index ade1c9476..578db9d1e 100644
> --- a/testcases/kernel/syscalls/getdents/getdents02.c
> +++ b/testcases/kernel/syscalls/getdents/getdents02.c
> @@ -15,6 +15,7 @@
>   *   - getdents() fails with EINVAL if result buffer is too small
>   *   - getdents() fails with ENOTDIR if file descriptor does not refer to a directory
>   *   - getdents() fails with ENOENT if directory was unlinked()
> + *   - getdents() fails with EFAULT if argument points outside the calling process's address space
>   */
>  
>  #define _GNU_SOURCE
> @@ -34,6 +35,7 @@ static size_t size;
>  
>  static char dirp1_arr[1];
>  static char *dirp1 = dirp1_arr;
> +static char *dirp_bad;
>  static size_t size1 = 1;
>  
>  static int fd_inv = -5;
> @@ -51,6 +53,7 @@ static struct tcase {
>  	{ &fd, &dirp1, &size1, EINVAL },
>  	{ &fd_file, &dirp, &size, ENOTDIR },
>  	{ &fd_unlinked, &dirp, &size, ENOENT },
> +	{ &fd, &dirp_bad, &size, EFAULT },
>  };
>  
>  static void setup(void)
> @@ -63,6 +66,8 @@ static void setup(void)
>  	fd = SAFE_OPEN(".", O_RDONLY);
>  	fd_file = SAFE_OPEN("test", O_CREAT | O_RDWR, 0644);
>  
> +	dirp_bad = tst_get_bad_addr(NULL);
> +
>  	SAFE_MKDIR(TEST_DIR, DIR_MODE);
>  	fd_unlinked = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
>  	SAFE_RMDIR(TEST_DIR);
> 

Regards,
Avinesh
Li Wang Aug. 20, 2024, 11:59 a.m. UTC | #2
Avinesh Kumar <akumar@suse.de> wrote:

Hi,
>
> Reviewed-by: Avinesh Kumar <akumar@suse.de>
>

Patch merged, thanks!
Avinesh Kumar Aug. 26, 2024, 6:12 p.m. UTC | #3
On Monday, August 19, 2024 10:22:13 AM GMT+2 Ma Xinjian via ltp wrote:
> Currently there is no case for EFAULT, so a new case is added.
> 
> Signed-off-by: Ma Xinjian <maxj.fnst@fujitsu.com>
> ---
>  testcases/kernel/syscalls/getdents/getdents02.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/testcases/kernel/syscalls/getdents/getdents02.c b/testcases/kernel/syscalls/getdents/getdents02.c
> index ade1c9476..578db9d1e 100644
> --- a/testcases/kernel/syscalls/getdents/getdents02.c
> +++ b/testcases/kernel/syscalls/getdents/getdents02.c
> @@ -15,6 +15,7 @@
>   *   - getdents() fails with EINVAL if result buffer is too small
>   *   - getdents() fails with ENOTDIR if file descriptor does not refer to a directory
>   *   - getdents() fails with ENOENT if directory was unlinked()
> + *   - getdents() fails with EFAULT if argument points outside the calling process's address space
>   */
>  
>  #define _GNU_SOURCE
> @@ -34,6 +35,7 @@ static size_t size;
>  
>  static char dirp1_arr[1];
>  static char *dirp1 = dirp1_arr;
> +static char *dirp_bad;
>  static size_t size1 = 1;
>  
>  static int fd_inv = -5;
> @@ -51,6 +53,7 @@ static struct tcase {
>  	{ &fd, &dirp1, &size1, EINVAL },
>  	{ &fd_file, &dirp, &size, ENOTDIR },
>  	{ &fd_unlinked, &dirp, &size, ENOENT },
> +	{ &fd, &dirp_bad, &size, EFAULT },
>  };
>  
>  static void setup(void)
> @@ -63,6 +66,8 @@ static void setup(void)
>  	fd = SAFE_OPEN(".", O_RDONLY);
>  	fd_file = SAFE_OPEN("test", O_CREAT | O_RDWR, 0644);
>  
> +	dirp_bad = tst_get_bad_addr(NULL);
> +
>  	SAFE_MKDIR(TEST_DIR, DIR_MODE);
>  	fd_unlinked = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
>  	SAFE_RMDIR(TEST_DIR);
> 

Hi,

I noticed, this new testcase for verifying EFAULT is failing with 32-bit
compat layer [1]  as well as on 32-bit archs [2]
getdents() / getdents64() returns EINVAL instead of expected EFAULT, which
means that size for buffer dirp is too small.
And buffer size issue also affects other errno cases, but we never encountered
it as syscall returns the expected errno before hitting the size issue.


getdents.h:148: TINFO: Testing the SYS_getdents syscall
tst_buffers.c:57: TINFO: Test is using guarded buffers
getdents02.c:88: TPASS: getdents failed as expected: EBADF (9)
getdents02.c:88: TPASS: getdents failed as expected: EINVAL (22)
getdents02.c:88: TPASS: getdents failed as expected: ENOTDIR (20)
getdents02.c:88: TPASS: getdents failed as expected: ENOENT (2)
getdents02.c:92: TFAIL: getdents failed unexpectedly: EINVAL (22)
getdents.h:151: TINFO: Testing the SYS_getdents64 syscall
tst_buffers.c:57: TINFO: Test is using guarded buffers
getdents02.c:88: TPASS: getdents failed as expected: EBADF (9)
getdents02.c:88: TPASS: getdents failed as expected: EINVAL (22)
getdents02.c:88: TPASS: getdents failed as expected: ENOTDIR (20)
getdents02.c:88: TPASS: getdents failed as expected: ENOENT (2)
getdents02.c:92: TFAIL: getdents failed unexpectedly: EINVAL (22)
getdents.h:157: TCONF: libc getdents() is not implemented
getdents.h:162: TINFO: Testing libc getdents64()
tst_buffers.c:57: TINFO: Test is using guarded buffers
getdents02.c:88: TPASS: getdents failed as expected: EBADF (9)
getdents02.c:88: TPASS: getdents failed as expected: EINVAL (22)
getdents02.c:88: TPASS: getdents failed as expected: ENOTDIR (20)
getdents02.c:88: TPASS: getdents failed as expected: ENOENT (2)
getdents02.c:88: TPASS: getdents failed as expected: EFAULT (14)


[1] https://openqa.opensuse.org/tests/4432756#step/getdents02/8
[2] https://openqa.opensuse.org/tests/4431957#step/getdents02/8


Regards,
Avinesh
diff mbox series

Patch

diff --git a/testcases/kernel/syscalls/getdents/getdents02.c b/testcases/kernel/syscalls/getdents/getdents02.c
index ade1c9476..578db9d1e 100644
--- a/testcases/kernel/syscalls/getdents/getdents02.c
+++ b/testcases/kernel/syscalls/getdents/getdents02.c
@@ -15,6 +15,7 @@ 
  *   - getdents() fails with EINVAL if result buffer is too small
  *   - getdents() fails with ENOTDIR if file descriptor does not refer to a directory
  *   - getdents() fails with ENOENT if directory was unlinked()
+ *   - getdents() fails with EFAULT if argument points outside the calling process's address space
  */
 
 #define _GNU_SOURCE
@@ -34,6 +35,7 @@  static size_t size;
 
 static char dirp1_arr[1];
 static char *dirp1 = dirp1_arr;
+static char *dirp_bad;
 static size_t size1 = 1;
 
 static int fd_inv = -5;
@@ -51,6 +53,7 @@  static struct tcase {
 	{ &fd, &dirp1, &size1, EINVAL },
 	{ &fd_file, &dirp, &size, ENOTDIR },
 	{ &fd_unlinked, &dirp, &size, ENOENT },
+	{ &fd, &dirp_bad, &size, EFAULT },
 };
 
 static void setup(void)
@@ -63,6 +66,8 @@  static void setup(void)
 	fd = SAFE_OPEN(".", O_RDONLY);
 	fd_file = SAFE_OPEN("test", O_CREAT | O_RDWR, 0644);
 
+	dirp_bad = tst_get_bad_addr(NULL);
+
 	SAFE_MKDIR(TEST_DIR, DIR_MODE);
 	fd_unlinked = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
 	SAFE_RMDIR(TEST_DIR);