@@ -274,6 +274,44 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
274274 return err ;
275275}
276276
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+
277315/**
278316 * sys_landlock_add_rule - Add a new rule to a ruleset
279317 *
@@ -306,11 +344,8 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
306344 const enum landlock_rule_type , rule_type ,
307345 const void __user * const , rule_attr , const __u32 , flags )
308346{
309- struct landlock_path_beneath_attr path_beneath_attr ;
310- struct path path ;
311347 struct landlock_ruleset * ruleset ;
312- int res , err ;
313- access_mask_t mask ;
348+ int err ;
314349
315350 if (!landlock_initialized )
316351 return - EOPNOTSUPP ;
@@ -324,48 +359,14 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
324359 if (IS_ERR (ruleset ))
325360 return PTR_ERR (ruleset );
326361
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 :
354367 err = - EINVAL ;
355- goto out_put_ruleset ;
368+ break ;
356369 }
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 :
369370 landlock_put_ruleset (ruleset );
370371 return err ;
371372}
0 commit comments