@@ -274,6 +274,44 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
274
274
return err ;
275
275
}
276
276
277
+ static int add_rule_path_beneath (struct landlock_ruleset * const ruleset ,
278
+ const void __user * const rule_attr )
279
+ {
280
+ struct landlock_path_beneath_attr path_beneath_attr ;
281
+ struct path path ;
282
+ int res , err ;
283
+ access_mask_t mask ;
284
+
285
+ /* Copies raw user space buffer, only one type for now. */
286
+ res = copy_from_user (& path_beneath_attr , rule_attr ,
287
+ sizeof (path_beneath_attr ));
288
+ if (res )
289
+ return - EFAULT ;
290
+
291
+ /*
292
+ * Informs about useless rule: empty allowed_access (i.e. deny rules)
293
+ * are ignored in path walks.
294
+ */
295
+ if (!path_beneath_attr .allowed_access )
296
+ return - ENOMSG ;
297
+
298
+ /* Checks that allowed_access matches the @ruleset constraints. */
299
+ mask = landlock_get_raw_fs_access_mask (ruleset , 0 );
300
+ if ((path_beneath_attr .allowed_access | mask ) != mask )
301
+ return - EINVAL ;
302
+
303
+ /* Gets and checks the new rule. */
304
+ err = get_path_from_fd (path_beneath_attr .parent_fd , & path );
305
+ if (err )
306
+ return err ;
307
+
308
+ /* Imports the new rule. */
309
+ err = landlock_append_fs_rule (ruleset , & path ,
310
+ path_beneath_attr .allowed_access );
311
+ path_put (& path );
312
+ return err ;
313
+ }
314
+
277
315
/**
278
316
* sys_landlock_add_rule - Add a new rule to a ruleset
279
317
*
@@ -306,11 +344,8 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
306
344
const enum landlock_rule_type , rule_type ,
307
345
const void __user * const , rule_attr , const __u32 , flags )
308
346
{
309
- struct landlock_path_beneath_attr path_beneath_attr ;
310
- struct path path ;
311
347
struct landlock_ruleset * ruleset ;
312
- int res , err ;
313
- access_mask_t mask ;
348
+ int err ;
314
349
315
350
if (!landlock_initialized )
316
351
return - EOPNOTSUPP ;
@@ -324,48 +359,14 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
324
359
if (IS_ERR (ruleset ))
325
360
return PTR_ERR (ruleset );
326
361
327
- if (rule_type != LANDLOCK_RULE_PATH_BENEATH ) {
328
- err = - EINVAL ;
329
- goto out_put_ruleset ;
330
- }
331
-
332
- /* Copies raw user space buffer, only one type for now. */
333
- res = copy_from_user (& path_beneath_attr , rule_attr ,
334
- sizeof (path_beneath_attr ));
335
- if (res ) {
336
- err = - EFAULT ;
337
- goto out_put_ruleset ;
338
- }
339
-
340
- /*
341
- * Informs about useless rule: empty allowed_access (i.e. deny rules)
342
- * are ignored in path walks.
343
- */
344
- if (!path_beneath_attr .allowed_access ) {
345
- err = - ENOMSG ;
346
- goto out_put_ruleset ;
347
- }
348
- /*
349
- * Checks that allowed_access matches the @ruleset constraints
350
- * (ruleset->access_masks[0] is automatically upgraded to 64-bits).
351
- */
352
- mask = landlock_get_raw_fs_access_mask (ruleset , 0 );
353
- if ((path_beneath_attr .allowed_access | mask ) != mask ) {
362
+ switch (rule_type ) {
363
+ case LANDLOCK_RULE_PATH_BENEATH :
364
+ err = add_rule_path_beneath (ruleset , rule_attr );
365
+ break ;
366
+ default :
354
367
err = - EINVAL ;
355
- goto out_put_ruleset ;
368
+ break ;
356
369
}
357
-
358
- /* Gets and checks the new rule. */
359
- err = get_path_from_fd (path_beneath_attr .parent_fd , & path );
360
- if (err )
361
- goto out_put_ruleset ;
362
-
363
- /* Imports the new rule. */
364
- err = landlock_append_fs_rule (ruleset , & path ,
365
- path_beneath_attr .allowed_access );
366
- path_put (& path );
367
-
368
- out_put_ruleset :
369
370
landlock_put_ruleset (ruleset );
370
371
return err ;
371
372
}
0 commit comments