17
17
#include "../kselftest_harness.h"
18
18
#include "../clone3/clone3_selftests.h"
19
19
20
+
21
+ #ifndef F_LINUX_SPECIFIC_BASE
22
+ #define F_LINUX_SPECIFIC_BASE 1024
23
+ #endif
24
+
25
+ #ifndef F_DUPFD_QUERY
26
+ #define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
27
+ #endif
28
+
20
29
static inline int sys_close_range (unsigned int fd , unsigned int max_fd ,
21
30
unsigned int flags )
22
31
{
@@ -45,6 +54,15 @@ TEST(core_close_range)
45
54
SKIP (return , "close_range() syscall not supported" );
46
55
}
47
56
57
+ for (i = 0 ; i < 100 ; i ++ ) {
58
+ ret = fcntl (open_fds [i ], F_DUPFD_QUERY , open_fds [i + 1 ]);
59
+ if (ret < 0 ) {
60
+ EXPECT_EQ (errno , EINVAL );
61
+ } else {
62
+ EXPECT_EQ (ret , 0 );
63
+ }
64
+ }
65
+
48
66
EXPECT_EQ (0 , sys_close_range (open_fds [0 ], open_fds [50 ], 0 ));
49
67
50
68
for (i = 0 ; i <= 50 ; i ++ )
@@ -358,7 +376,7 @@ TEST(close_range_cloexec_unshare)
358
376
*/
359
377
TEST (close_range_cloexec_syzbot )
360
378
{
361
- int fd1 , fd2 , fd3 , flags , ret , status ;
379
+ int fd1 , fd2 , fd3 , fd4 , flags , ret , status ;
362
380
pid_t pid ;
363
381
struct __clone_args args = {
364
382
.flags = CLONE_FILES ,
@@ -372,6 +390,13 @@ TEST(close_range_cloexec_syzbot)
372
390
fd2 = dup2 (fd1 , 1000 );
373
391
EXPECT_GT (fd2 , 0 );
374
392
393
+ flags = fcntl (fd1 , F_DUPFD_QUERY , fd2 );
394
+ if (flags < 0 ) {
395
+ EXPECT_EQ (errno , EINVAL );
396
+ } else {
397
+ EXPECT_EQ (flags , 1 );
398
+ }
399
+
375
400
pid = sys_clone3 (& args , sizeof (args ));
376
401
ASSERT_GE (pid , 0 );
377
402
@@ -396,6 +421,15 @@ TEST(close_range_cloexec_syzbot)
396
421
fd3 = dup2 (fd1 , 42 );
397
422
EXPECT_GT (fd3 , 0 );
398
423
424
+ flags = fcntl (fd1 , F_DUPFD_QUERY , fd3 );
425
+ if (flags < 0 ) {
426
+ EXPECT_EQ (errno , EINVAL );
427
+ } else {
428
+ EXPECT_EQ (flags , 1 );
429
+ }
430
+
431
+
432
+
399
433
/*
400
434
* Duplicating the file descriptor must remove the
401
435
* FD_CLOEXEC flag.
@@ -426,13 +460,32 @@ TEST(close_range_cloexec_syzbot)
426
460
fd3 = dup2 (fd1 , 42 );
427
461
EXPECT_GT (fd3 , 0 );
428
462
463
+ flags = fcntl (fd1 , F_DUPFD_QUERY , fd3 );
464
+ if (flags < 0 ) {
465
+ EXPECT_EQ (errno , EINVAL );
466
+ } else {
467
+ EXPECT_EQ (flags , 1 );
468
+ }
469
+
470
+ fd4 = open ("/dev/null" , O_RDWR );
471
+ EXPECT_GT (fd4 , 0 );
472
+
473
+ /* Same inode, different file pointers. */
474
+ flags = fcntl (fd1 , F_DUPFD_QUERY , fd4 );
475
+ if (flags < 0 ) {
476
+ EXPECT_EQ (errno , EINVAL );
477
+ } else {
478
+ EXPECT_EQ (flags , 0 );
479
+ }
480
+
429
481
flags = fcntl (fd3 , F_GETFD );
430
482
EXPECT_GT (flags , -1 );
431
483
EXPECT_EQ (flags & FD_CLOEXEC , 0 );
432
484
433
485
EXPECT_EQ (close (fd1 ), 0 );
434
486
EXPECT_EQ (close (fd2 ), 0 );
435
487
EXPECT_EQ (close (fd3 ), 0 );
488
+ EXPECT_EQ (close (fd4 ), 0 );
436
489
}
437
490
438
491
/*
0 commit comments