Skip to content

Commit e9b4c58

Browse files
committed
Merge tag 'landlock-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull Landlock updates from Mickaël Salaün: "New tests, a slight optimization, and some cosmetic changes" * tag 'landlock-6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: landlock: Optimize the number of calls to get_access_mask slightly selftests/landlock: Rename "permitted" to "allowed" in ftruncate tests landlock: Remove remaining "inline" modifiers in .c files [v6.6] landlock: Remove remaining "inline" modifiers in .c files [v6.1] landlock: Remove remaining "inline" modifiers in .c files [v5.15] selftests/landlock: Add tests to check unhandled rule's access rights selftests/landlock: Add tests to check unknown rule's access rights
2 parents 063a7ce + 0daaa61 commit e9b4c58

File tree

4 files changed

+145
-27
lines changed

4 files changed

+145
-27
lines changed

security/landlock/fs.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset,
193193
*
194194
* Returns NULL if no rule is found or if @dentry is negative.
195195
*/
196-
static inline const struct landlock_rule *
196+
static const struct landlock_rule *
197197
find_rule(const struct landlock_ruleset *const domain,
198198
const struct dentry *const dentry)
199199
{
@@ -220,7 +220,7 @@ find_rule(const struct landlock_ruleset *const domain,
220220
* sockfs, pipefs), but can still be reachable through
221221
* /proc/<pid>/fd/<file-descriptor>
222222
*/
223-
static inline bool is_nouser_or_private(const struct dentry *dentry)
223+
static bool is_nouser_or_private(const struct dentry *dentry)
224224
{
225225
return (dentry->d_sb->s_flags & SB_NOUSER) ||
226226
(d_is_positive(dentry) &&
@@ -264,7 +264,7 @@ static const struct landlock_ruleset *get_current_fs_domain(void)
264264
*
265265
* @layer_masks_child2: Optional child masks.
266266
*/
267-
static inline bool no_more_access(
267+
static bool no_more_access(
268268
const layer_mask_t (*const layer_masks_parent1)[LANDLOCK_NUM_ACCESS_FS],
269269
const layer_mask_t (*const layer_masks_child1)[LANDLOCK_NUM_ACCESS_FS],
270270
const bool child1_is_directory,
@@ -316,7 +316,7 @@ static inline bool no_more_access(
316316
*
317317
* Returns true if the request is allowed, false otherwise.
318318
*/
319-
static inline bool
319+
static bool
320320
scope_to_request(const access_mask_t access_request,
321321
layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS])
322322
{
@@ -335,7 +335,7 @@ scope_to_request(const access_mask_t access_request,
335335
* Returns true if there is at least one access right different than
336336
* LANDLOCK_ACCESS_FS_REFER.
337337
*/
338-
static inline bool
338+
static bool
339339
is_eacces(const layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS],
340340
const access_mask_t access_request)
341341
{
@@ -551,9 +551,9 @@ static bool is_access_to_paths_allowed(
551551
return allowed_parent1 && allowed_parent2;
552552
}
553553

554-
static inline int check_access_path(const struct landlock_ruleset *const domain,
555-
const struct path *const path,
556-
access_mask_t access_request)
554+
static int check_access_path(const struct landlock_ruleset *const domain,
555+
const struct path *const path,
556+
access_mask_t access_request)
557557
{
558558
layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {};
559559

@@ -565,8 +565,8 @@ static inline int check_access_path(const struct landlock_ruleset *const domain,
565565
return -EACCES;
566566
}
567567

568-
static inline int current_check_access_path(const struct path *const path,
569-
const access_mask_t access_request)
568+
static int current_check_access_path(const struct path *const path,
569+
const access_mask_t access_request)
570570
{
571571
const struct landlock_ruleset *const dom = get_current_fs_domain();
572572

@@ -575,7 +575,7 @@ static inline int current_check_access_path(const struct path *const path,
575575
return check_access_path(dom, path, access_request);
576576
}
577577

578-
static inline access_mask_t get_mode_access(const umode_t mode)
578+
static access_mask_t get_mode_access(const umode_t mode)
579579
{
580580
switch (mode & S_IFMT) {
581581
case S_IFLNK:
@@ -600,7 +600,7 @@ static inline access_mask_t get_mode_access(const umode_t mode)
600600
}
601601
}
602602

603-
static inline access_mask_t maybe_remove(const struct dentry *const dentry)
603+
static access_mask_t maybe_remove(const struct dentry *const dentry)
604604
{
605605
if (d_is_negative(dentry))
606606
return 0;
@@ -1086,7 +1086,7 @@ static int hook_path_truncate(const struct path *const path)
10861086
* Returns the access rights that are required for opening the given file,
10871087
* depending on the file type and open mode.
10881088
*/
1089-
static inline access_mask_t
1089+
static access_mask_t
10901090
get_required_file_open_access(const struct file *const file)
10911091
{
10921092
access_mask_t access = 0;

security/landlock/ruleset.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ int landlock_insert_rule(struct landlock_ruleset *const ruleset,
305305
return insert_rule(ruleset, id, &layers, ARRAY_SIZE(layers));
306306
}
307307

308-
static inline void get_hierarchy(struct landlock_hierarchy *const hierarchy)
308+
static void get_hierarchy(struct landlock_hierarchy *const hierarchy)
309309
{
310310
if (hierarchy)
311311
refcount_inc(&hierarchy->usage);
@@ -723,11 +723,12 @@ landlock_init_layer_masks(const struct landlock_ruleset *const domain,
723723
/* Saves all handled accesses per layer. */
724724
for (layer_level = 0; layer_level < domain->num_layers; layer_level++) {
725725
const unsigned long access_req = access_request;
726+
const access_mask_t access_mask =
727+
get_access_mask(domain, layer_level);
726728
unsigned long access_bit;
727729

728730
for_each_set_bit(access_bit, &access_req, num_access) {
729-
if (BIT_ULL(access_bit) &
730-
get_access_mask(domain, layer_level)) {
731+
if (BIT_ULL(access_bit) & access_mask) {
731732
(*layer_masks)[access_bit] |=
732733
BIT_ULL(layer_level);
733734
handled_accesses |= BIT_ULL(access_bit);

tools/testing/selftests/landlock/fs_test.c

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ TEST_F_FORK(layout1, file_and_dir_access_rights)
589589
ASSERT_EQ(0, close(ruleset_fd));
590590
}
591591

592-
TEST_F_FORK(layout0, unknown_access_rights)
592+
TEST_F_FORK(layout0, ruleset_with_unknown_access)
593593
{
594594
__u64 access_mask;
595595

@@ -605,6 +605,67 @@ TEST_F_FORK(layout0, unknown_access_rights)
605605
}
606606
}
607607

608+
TEST_F_FORK(layout0, rule_with_unknown_access)
609+
{
610+
__u64 access;
611+
struct landlock_path_beneath_attr path_beneath = {};
612+
const struct landlock_ruleset_attr ruleset_attr = {
613+
.handled_access_fs = ACCESS_ALL,
614+
};
615+
const int ruleset_fd =
616+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
617+
618+
ASSERT_LE(0, ruleset_fd);
619+
620+
path_beneath.parent_fd =
621+
open(TMP_DIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
622+
ASSERT_LE(0, path_beneath.parent_fd);
623+
624+
for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
625+
path_beneath.allowed_access = access;
626+
EXPECT_EQ(-1, landlock_add_rule(ruleset_fd,
627+
LANDLOCK_RULE_PATH_BENEATH,
628+
&path_beneath, 0));
629+
EXPECT_EQ(EINVAL, errno);
630+
}
631+
ASSERT_EQ(0, close(path_beneath.parent_fd));
632+
ASSERT_EQ(0, close(ruleset_fd));
633+
}
634+
635+
TEST_F_FORK(layout1, rule_with_unhandled_access)
636+
{
637+
struct landlock_ruleset_attr ruleset_attr = {
638+
.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
639+
};
640+
struct landlock_path_beneath_attr path_beneath = {};
641+
int ruleset_fd;
642+
__u64 access;
643+
644+
ruleset_fd =
645+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
646+
ASSERT_LE(0, ruleset_fd);
647+
648+
path_beneath.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
649+
ASSERT_LE(0, path_beneath.parent_fd);
650+
651+
for (access = 1; access > 0; access <<= 1) {
652+
int err;
653+
654+
path_beneath.allowed_access = access;
655+
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
656+
&path_beneath, 0);
657+
if (access == ruleset_attr.handled_access_fs) {
658+
EXPECT_EQ(0, err);
659+
} else {
660+
EXPECT_EQ(-1, err);
661+
EXPECT_EQ(EINVAL, errno);
662+
}
663+
}
664+
665+
EXPECT_EQ(0, close(path_beneath.parent_fd));
666+
EXPECT_EQ(0, close(ruleset_fd));
667+
}
668+
608669
static void add_path_beneath(struct __test_metadata *const _metadata,
609670
const int ruleset_fd, const __u64 allowed_access,
610671
const char *const path)
@@ -3627,7 +3688,7 @@ FIXTURE_TEARDOWN(ftruncate)
36273688
FIXTURE_VARIANT(ftruncate)
36283689
{
36293690
const __u64 handled;
3630-
const __u64 permitted;
3691+
const __u64 allowed;
36313692
const int expected_open_result;
36323693
const int expected_ftruncate_result;
36333694
};
@@ -3636,7 +3697,7 @@ FIXTURE_VARIANT(ftruncate)
36363697
FIXTURE_VARIANT_ADD(ftruncate, w_w) {
36373698
/* clang-format on */
36383699
.handled = LANDLOCK_ACCESS_FS_WRITE_FILE,
3639-
.permitted = LANDLOCK_ACCESS_FS_WRITE_FILE,
3700+
.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
36403701
.expected_open_result = 0,
36413702
.expected_ftruncate_result = 0,
36423703
};
@@ -3645,7 +3706,7 @@ FIXTURE_VARIANT_ADD(ftruncate, w_w) {
36453706
FIXTURE_VARIANT_ADD(ftruncate, t_t) {
36463707
/* clang-format on */
36473708
.handled = LANDLOCK_ACCESS_FS_TRUNCATE,
3648-
.permitted = LANDLOCK_ACCESS_FS_TRUNCATE,
3709+
.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
36493710
.expected_open_result = 0,
36503711
.expected_ftruncate_result = 0,
36513712
};
@@ -3654,7 +3715,7 @@ FIXTURE_VARIANT_ADD(ftruncate, t_t) {
36543715
FIXTURE_VARIANT_ADD(ftruncate, wt_w) {
36553716
/* clang-format on */
36563717
.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3657-
.permitted = LANDLOCK_ACCESS_FS_WRITE_FILE,
3718+
.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
36583719
.expected_open_result = 0,
36593720
.expected_ftruncate_result = EACCES,
36603721
};
@@ -3663,8 +3724,7 @@ FIXTURE_VARIANT_ADD(ftruncate, wt_w) {
36633724
FIXTURE_VARIANT_ADD(ftruncate, wt_wt) {
36643725
/* clang-format on */
36653726
.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3666-
.permitted = LANDLOCK_ACCESS_FS_WRITE_FILE |
3667-
LANDLOCK_ACCESS_FS_TRUNCATE,
3727+
.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
36683728
.expected_open_result = 0,
36693729
.expected_ftruncate_result = 0,
36703730
};
@@ -3673,7 +3733,7 @@ FIXTURE_VARIANT_ADD(ftruncate, wt_wt) {
36733733
FIXTURE_VARIANT_ADD(ftruncate, wt_t) {
36743734
/* clang-format on */
36753735
.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3676-
.permitted = LANDLOCK_ACCESS_FS_TRUNCATE,
3736+
.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
36773737
.expected_open_result = EACCES,
36783738
};
36793739

@@ -3683,7 +3743,7 @@ TEST_F_FORK(ftruncate, open_and_ftruncate)
36833743
const struct rule rules[] = {
36843744
{
36853745
.path = path,
3686-
.access = variant->permitted,
3746+
.access = variant->allowed,
36873747
},
36883748
{},
36893749
};
@@ -3724,7 +3784,7 @@ TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes)
37243784
const struct rule rules[] = {
37253785
{
37263786
.path = path,
3727-
.access = variant->permitted,
3787+
.access = variant->allowed,
37283788
},
37293789
{},
37303790
};

tools/testing/selftests/landlock/net_test.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ TEST_F(mini, network_access_rights)
12601260
}
12611261

12621262
/* Checks invalid attribute, out of landlock network access range. */
1263-
TEST_F(mini, unknown_access_rights)
1263+
TEST_F(mini, ruleset_with_unknown_access)
12641264
{
12651265
__u64 access_mask;
12661266

@@ -1276,6 +1276,63 @@ TEST_F(mini, unknown_access_rights)
12761276
}
12771277
}
12781278

1279+
TEST_F(mini, rule_with_unknown_access)
1280+
{
1281+
const struct landlock_ruleset_attr ruleset_attr = {
1282+
.handled_access_net = ACCESS_ALL,
1283+
};
1284+
struct landlock_net_port_attr net_port = {
1285+
.port = sock_port_start,
1286+
};
1287+
int ruleset_fd;
1288+
__u64 access;
1289+
1290+
ruleset_fd =
1291+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1292+
ASSERT_LE(0, ruleset_fd);
1293+
1294+
for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
1295+
net_port.allowed_access = access;
1296+
EXPECT_EQ(-1,
1297+
landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1298+
&net_port, 0));
1299+
EXPECT_EQ(EINVAL, errno);
1300+
}
1301+
EXPECT_EQ(0, close(ruleset_fd));
1302+
}
1303+
1304+
TEST_F(mini, rule_with_unhandled_access)
1305+
{
1306+
struct landlock_ruleset_attr ruleset_attr = {
1307+
.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
1308+
};
1309+
struct landlock_net_port_attr net_port = {
1310+
.port = sock_port_start,
1311+
};
1312+
int ruleset_fd;
1313+
__u64 access;
1314+
1315+
ruleset_fd =
1316+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1317+
ASSERT_LE(0, ruleset_fd);
1318+
1319+
for (access = 1; access > 0; access <<= 1) {
1320+
int err;
1321+
1322+
net_port.allowed_access = access;
1323+
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
1324+
&net_port, 0);
1325+
if (access == ruleset_attr.handled_access_net) {
1326+
EXPECT_EQ(0, err);
1327+
} else {
1328+
EXPECT_EQ(-1, err);
1329+
EXPECT_EQ(EINVAL, errno);
1330+
}
1331+
}
1332+
1333+
EXPECT_EQ(0, close(ruleset_fd));
1334+
}
1335+
12791336
TEST_F(mini, inval)
12801337
{
12811338
const struct landlock_ruleset_attr ruleset_attr = {

0 commit comments

Comments
 (0)