From patchwork Thu May 7 08:04:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Domenico Andreoli X-Patchwork-Id: 11532817 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D1C811392 for ; Thu, 7 May 2020 08:09:35 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 90B0920753 for ; Thu, 7 May 2020 08:09:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="f1l63tFz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 90B0920753 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 4807F900004; Thu, 7 May 2020 04:09:33 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 431B0900002; Thu, 7 May 2020 04:09:33 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 31FC8900004; Thu, 7 May 2020 04:09:33 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0023.hostedemail.com [216.40.44.23]) by kanga.kvack.org (Postfix) with ESMTP id 1ACBA900002 for ; Thu, 7 May 2020 04:09:33 -0400 (EDT) Received: from smtpin18.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id D56072472 for ; Thu, 7 May 2020 08:09:32 +0000 (UTC) X-FDA: 76789198584.18.gold76_8d844fd2aab2a X-Spam-Summary: 2,0,0,d41d8cd98f00b204,d41d8cd98f00b204,domenico.andreoli.it@gmail.com,,RULES_HIT:152:355:379:871:988:989:1183:1260:1277:1312:1313:1314:1345:1516:1518:1519:1522:1535:1593:1594:1595:1596:1692:1730:1747:1777:1792:2392:2393:2559:2562:3138:3139:3140:3141:3142:3876:3877:4119:5007:6114:6261:6642:6653:6742:7281:10004:11914:12297:12517:12519:13895:14394:14659:21080:21444:21627:30051:30054:30064:30070,0,RBL:209.85.221.68:@gmail.com:.lbl8.mailshell.net-62.18.0.100 66.100.201.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:23,LUA_SUMMARY:none X-HE-Tag: gold76_8d844fd2aab2a X-Filterd-Recvd-Size: 8767 Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by imf45.hostedemail.com (Postfix) with ESMTP for ; Thu, 7 May 2020 08:09:32 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id e16so5187010wra.7 for ; Thu, 07 May 2020 01:09:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:resent-from:resent-date:resent-message-id:resent-to :message-id:user-agent:date:from:to:cc:subject:references :mime-version:content-disposition; bh=xV3Ps0RsdCVhfxWoq/YPpZZAsZRZc/1bRKCvZXY1C2s=; b=f1l63tFzPYekUF5/P/qZk8XOI5QYNw6EkCD1pgFct2Oun2QZOeS/oz4CVT0hZ8lhUr h839qr7rMRncHscWHM3CRjhaHSE6XTFCN6P2llKiNJOL2Q0nUk5EqCezUPz0LkC8rzPp H2C9TgIK5bJEHoiUwwDXbrLOK9gRo+DuPEpz7FbLkuBXqWXrtRJAB4wygJGpUJnJvU/Q 3c3nxNgg+kkeS27OBGL0ttQe8VpO87fyDXw1Z5OyOGMASm3q1FZb1GBqwhqVbdTpri+5 AHwyCtBQWwG+u1PudeigXxYuC17mZNPTwCyzsZmRD/QKqL46Cp9u6tO2Ktz8tvgYSQkY //Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:resent-from:resent-date:resent-message-id :resent-to:message-id:user-agent:date:from:to:cc:subject:references :mime-version:content-disposition; bh=xV3Ps0RsdCVhfxWoq/YPpZZAsZRZc/1bRKCvZXY1C2s=; b=r+ljvegHBbxLJ0rOaiC1j361whyv7OiJOnEVFouleDHZRY1Q7wF6KYgTjW/A2NtMOz t01jlHs5HLVEJPbZqfykPgO8BdTnijPXuMYbSa2j167xGTGR+vzeJ48K4ZUuXJT7d14Z i1CI1ZMofBeUVaI/sFQ1sUgrfun+s6+onRmxVgK0BhUKm5xaw724LpyN1G/spqv/mG2A 5ErCvH7Cg7piUauPBsxpfKtAukwEwpxvx90iF9OOOCFshbII8L4SI1eCdFtVnYIbK0BF 7N+7hPS73RdB6DKaDfqzzrXbHRhjmFHrmZzTtK7mwpsyaiDx7r4Z/Vgn7mBY8Ol84+oY sI+Q== X-Gm-Message-State: AGi0PuZSIsCn2BPouGqV2ILESexPE53rwjKsp3/ZvJD26e43uAHi4m0H 0HMf6VqJ+t7zOMDF7eaZxvc= X-Google-Smtp-Source: APiQypISzecItIXL6bUSv7pE5bwW/O6vts2MY1mF5Ku1rioJ7tRNh4kjLBp9y9/ZHIkyuDTwfZAdoA== X-Received: by 2002:adf:face:: with SMTP id a14mr13599009wrs.397.1588838971476; Thu, 07 May 2020 01:09:31 -0700 (PDT) Received: from dumbo ([2a01:230:2::ec6]) by smtp.gmail.com with ESMTPSA id p7sm7046956wrf.31.2020.05.07.01.09.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2020 01:09:30 -0700 (PDT) Received: from cavok by dumbo with local (Exim 4.92) (envelope-from ) id 1jWbaw-0004TM-GV; Thu, 07 May 2020 10:09:26 +0200 Message-Id: <20200507080650.439636033@linux.com> User-Agent: quilt/0.65 Date: Thu, 07 May 2020 10:04:57 +0200 From: Domenico Andreoli To: "Rafael J. Wysocki" , "Darrick J. Wong" Cc: Pavel Machek , Christoph Hellwig , viro@zeniv.linux.org.uk, tytso@mit.edu, len.brown@intel.com, linux-pm@vger.kernel.org, linux-mm@kvack.org, linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Domenico Andreoli Subject: [PATCH 1/1] hibernate: restrict writes to the snapshot device References: <20200507080456.069724962@linux.com> MIME-Version: 1.0 Content-Disposition: inline; filename=hibernate-restrict-writes-to-snapshot-dev X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Domenico Andreoli Hibernation via snapshot device requires write permission to the swap block device, the one that more often (but not necessarily) is used to store the hibernation image. With this patch, such permissions are granted iff: 1) snapshot device config option is enabled 2) swap partition is used as snapshot device In other circumstance the swap device is not writable from userspace. In order to achieve this, every write attempt to a swap device is checked against the device configured as part of the uswsusp API [0] using a pointer to the inode struct in memory. If the swap device being written was not configured for snapshotting, the write request is denied. NOTE: this implementation works only for swap block devices, where the inode configured by swapon (which sets S_SWAPFILE) is the same used by SNAPSHOT_SET_SWAP_AREA. In case of swapfile, SNAPSHOT_SET_SWAP_AREA indeed receives the inode of the block device containing the filesystem where the swap files is located (+ offset in it) which is never passed to swapon and then has not the S_SWAPFILE set. As result, the swapfile itself (as a file) has never an option to be written from userspace. Instead it remains writable if accessed directly from the containing block device, which is always writeable from root. [0] Documentation/power/userland-swsusp.rst Signed-off-by: Domenico Andreoli Cc: "Rafael J. Wysocki" Cc: Pavel Machek Cc: Darrick J. Wong Cc: Christoph Hellwig Cc: viro@zeniv.linux.org.uk Cc: tytso@mit.edu Cc: len.brown@intel.com Cc: linux-pm@vger.kernel.org Cc: linux-mm@kvack.org Cc: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- fs/block_dev.c | 3 +-- include/linux/suspend.h | 6 ++++++ kernel/power/user.c | 14 +++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) Index: b/include/linux/suspend.h =================================================================== --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -466,6 +466,12 @@ static inline bool system_entering_hiber static inline bool hibernation_available(void) { return false; } #endif /* CONFIG_HIBERNATION */ +#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV +int is_hibernate_snapshot_dev(const struct inode *); +#else +static inline int is_hibernate_snapshot_dev(const struct inode *i) { return 0; } +#endif + /* Hibernation and suspend events */ #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ #define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ Index: b/kernel/power/user.c =================================================================== --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -35,8 +35,14 @@ static struct snapshot_data { bool ready; bool platform_support; bool free_bitmaps; + struct inode *bd_inode; } snapshot_state; +int is_hibernate_snapshot_dev(const struct inode *bd_inode) +{ + return hibernation_available() && snapshot_state.bd_inode == bd_inode; +} + static int snapshot_open(struct inode *inode, struct file *filp) { struct snapshot_data *data; @@ -95,6 +101,7 @@ static int snapshot_open(struct inode *i data->frozen = false; data->ready = false; data->platform_support = false; + data->bd_inode = NULL; Unlock: unlock_system_sleep(); @@ -110,6 +117,7 @@ static int snapshot_release(struct inode swsusp_free(); data = filp->private_data; + data->bd_inode = NULL; free_all_swap_pages(data->swap); if (data->frozen) { pm_restore_gfp_mask(); @@ -202,6 +210,7 @@ struct compat_resume_swap_area { static int snapshot_set_swap_area(struct snapshot_data *data, void __user *argp) { + struct block_device *bdev; sector_t offset; dev_t swdev; @@ -232,9 +241,12 @@ static int snapshot_set_swap_area(struct data->swap = -1; return -EINVAL; } - data->swap = swap_type_of(swdev, offset, NULL); + data->swap = swap_type_of(swdev, offset, &bdev); if (data->swap < 0) return -ENODEV; + + data->bd_inode = bdev->bd_inode; + bdput(bdev); return 0; } Index: b/fs/block_dev.c =================================================================== --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -2023,8 +2023,7 @@ ssize_t blkdev_write_iter(struct kiocb * if (bdev_read_only(I_BDEV(bd_inode))) return -EPERM; - /* uswsusp needs write permission to the swap */ - if (IS_SWAPFILE(bd_inode) && !hibernation_available()) + if (IS_SWAPFILE(bd_inode) && !is_hibernate_snapshot_dev(bd_inode)) return -ETXTBSY; if (!iov_iter_count(from))