From patchwork Mon Feb 24 17:21:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 212758 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A426AC11D2F for ; Mon, 24 Feb 2020 17:22:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 82C6D20836 for ; Mon, 24 Feb 2020 17:22:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728226AbgBXRV4 (ORCPT ); Mon, 24 Feb 2020 12:21:56 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:57092 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728054AbgBXRVZ (ORCPT ); Mon, 24 Feb 2020 12:21:25 -0500 Received: from ip5f5bf7ec.dynamic.kabel-deutschland.de ([95.91.247.236] helo=wittgenstein.fritz.box) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1j6HQ2-0004D9-7u; Mon, 24 Feb 2020 17:21:22 +0000 From: Christian Brauner To: "David S. Miller" , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: "Rafael J. Wysocki" , Pavel Machek , Jakub Kicinski , Eric Dumazet , Stephen Hemminger , linux-pm@vger.kernel.org, Christian Brauner Subject: [PATCH v4 2/9] sysfs: add sysfs_link_change_owner() Date: Mon, 24 Feb 2020 18:21:03 +0100 Message-Id: <20200224172110.4121492-3-christian.brauner@ubuntu.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200224172110.4121492-1-christian.brauner@ubuntu.com> References: <20200224172110.4121492-1-christian.brauner@ubuntu.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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. Signed-off-by: Christian Brauner --- /* v2 */ - Greg Kroah-Hartman : - Add comment how ownership of sysfs object is changed. /* v3 */ - Greg Kroah-Hartman : - Add explicit uid/gid parameters. /* v4 */ - Christian Brauner : - Add more documentation. --- fs/sysfs/file.c | 41 +++++++++++++++++++++++++++++++++++++++++ include/linux/sysfs.h | 10 ++++++++++ 2 files changed, 51 insertions(+) diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 4ca936ca3ba4..332cd69b378c 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -570,6 +570,47 @@ static int internal_change_owner(struct kernfs_node *kn, kuid_t kuid, return kernfs_setattr(kn, &newattrs); } +/** + * sysfs_link_change_owner - change owner of a sysfs file. + * @kobj: object of the kernfs_node the symlink is located in. + * @targ: object of the kernfs_node the symlink points to. + * @name: name of the link. + * @kuid: new owner's kuid + * @kgid: new owner's kgid + * + * This function looks up the sysfs symlink entry @name under @kobj and changes + * the ownership to @kuid/@kgid. The symlink is looked up in the namespace of + * @targ. + * + * Returns 0 on success or error code on failure. + */ +int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ, + const char *name, kuid_t kuid, kgid_t kgid) +{ + struct kernfs_node *kn = NULL; + int error; + + if (!name || !kobj->state_in_sysfs || !targ->state_in_sysfs) + return -EINVAL; + + error = -ENOENT; + kn = kernfs_find_and_get_ns(kobj->sd, name, targ->sd->ns); + if (!kn) + goto out; + + error = -EINVAL; + if (kernfs_type(kn) != KERNFS_LINK) + goto out; + if (kn->symlink.target_kn->priv != targ) + goto out; + + error = internal_change_owner(kn, kuid, kgid); + +out: + kernfs_put(kn); + return error; +} + /** * sysfs_file_change_owner - change owner of a sysfs file. * @kobj: object. diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index a7884024a911..7e15ebfd750e 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -312,6 +312,8 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn) int sysfs_file_change_owner(struct kobject *kobj, const char *name, kuid_t kuid, kgid_t kgid); +int sysfs_link_change_owner(struct kobject *kobj, struct kobject *targ, + const char *name, kuid_t kuid, kgid_t kgid); #else /* CONFIG_SYSFS */ @@ -532,6 +534,14 @@ static inline int sysfs_file_change_owner(struct kobject *kobj, return 0; } +static inline int sysfs_link_change_owner(struct kobject *kobj, + struct kobject *targ, + const char *name, kuid_t kuid, + kgid_t kgid) +{ + return 0; +} + #endif /* CONFIG_SYSFS */ static inline int __must_check sysfs_create_file(struct kobject *kobj,