Skip to content

Commit 0666a3a

Browse files
Christian Braunerdavem330
authored andcommitted
sysfs: add sysfs_link_change_owner()
Add a helper to change the owner of a sysfs link. This function will be used to correctly account for kobject ownership changes, e.g. when moving network devices between network namespaces. Reviewed-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f70ce18 commit 0666a3a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

fs/sysfs/file.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,47 @@ static int internal_change_owner(struct kernfs_node *kn, kuid_t kuid,
570570
return kernfs_setattr(kn, &newattrs);
571571
}
572572

573+
/**
574+
* sysfs_link_change_owner - change owner of a sysfs file.
575+
* @kobj: object of the kernfs_node the symlink is located in.
576+
* @targ: object of the kernfs_node the symlink points to.
577+
* @name: name of the link.
578+
* @kuid: new owner's kuid
579+
* @kgid: new owner's kgid
580+
*
581+
* This function looks up the sysfs symlink entry @name under @kobj and changes
582+
* the ownership to @kuid/@kgid. The symlink is looked up in the namespace of
583+
* @targ.
584+
*
585+
* Returns 0 on success or error code on failure.
586+
*/
587+
int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ,
588+
const char *name, kuid_t kuid, kgid_t kgid)
589+
{
590+
struct kernfs_node *kn = NULL;
591+
int error;
592+
593+
if (!name || !kobj->state_in_sysfs || !targ->state_in_sysfs)
594+
return -EINVAL;
595+
596+
error = -ENOENT;
597+
kn = kernfs_find_and_get_ns(kobj->sd, name, targ->sd->ns);
598+
if (!kn)
599+
goto out;
600+
601+
error = -EINVAL;
602+
if (kernfs_type(kn) != KERNFS_LINK)
603+
goto out;
604+
if (kn->symlink.target_kn->priv != targ)
605+
goto out;
606+
607+
error = internal_change_owner(kn, kuid, kgid);
608+
609+
out:
610+
kernfs_put(kn);
611+
return error;
612+
}
613+
573614
/**
574615
* sysfs_file_change_owner - change owner of a sysfs file.
575616
* @kobj: object.

include/linux/sysfs.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn)
312312

313313
int sysfs_file_change_owner(struct kobject *kobj, const char *name, kuid_t kuid,
314314
kgid_t kgid);
315+
int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ,
316+
const char *name, kuid_t kuid, kgid_t kgid);
315317

316318
#else /* CONFIG_SYSFS */
317319

@@ -532,6 +534,14 @@ static inline int sysfs_file_change_owner(struct kobject *kobj,
532534
return 0;
533535
}
534536

537+
static inline int sysfs_link_change_owner(struct kobject *kobj,
538+
struct kobject *targ,
539+
const char *name, kuid_t kuid,
540+
kgid_t kgid)
541+
{
542+
return 0;
543+
}
544+
535545
#endif /* CONFIG_SYSFS */
536546

537547
static inline int __must_check sysfs_create_file(struct kobject *kobj,

0 commit comments

Comments
 (0)