hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/efivarfs/file.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Red Hat, Inc.
34 * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
85 */
96
107 #include <linux/efi.h>
....@@ -54,6 +51,7 @@
5451 } else {
5552 inode_lock(inode);
5653 i_size_write(inode, datasize + sizeof(attributes));
54
+ inode->i_mtime = current_time(inode);
5755 inode_unlock(inode);
5856 }
5957
....@@ -75,10 +73,8 @@
7573 ssize_t size = 0;
7674 int err;
7775
78
- while (!__ratelimit(&file->f_cred->user->ratelimit)) {
79
- if (!msleep_interruptible(50))
80
- return -EINTR;
81
- }
76
+ while (!__ratelimit(&file->f_cred->user->ratelimit))
77
+ msleep(50);
8278
8379 err = efivar_entry_size(var, &datasize);
8480
....@@ -110,16 +106,22 @@
110106 return size;
111107 }
112108
113
-static int
114
-efivarfs_ioc_getxflags(struct file *file, void __user *arg)
109
+static inline unsigned int efivarfs_getflags(struct inode *inode)
115110 {
116
- struct inode *inode = file->f_mapping->host;
117111 unsigned int i_flags;
118112 unsigned int flags = 0;
119113
120114 i_flags = inode->i_flags;
121115 if (i_flags & S_IMMUTABLE)
122116 flags |= FS_IMMUTABLE_FL;
117
+ return flags;
118
+}
119
+
120
+static int
121
+efivarfs_ioc_getxflags(struct file *file, void __user *arg)
122
+{
123
+ struct inode *inode = file->f_mapping->host;
124
+ unsigned int flags = efivarfs_getflags(inode);
123125
124126 if (copy_to_user(arg, &flags, sizeof(flags)))
125127 return -EFAULT;
....@@ -132,6 +134,7 @@
132134 struct inode *inode = file->f_mapping->host;
133135 unsigned int flags;
134136 unsigned int i_flags = 0;
137
+ unsigned int oldflags = efivarfs_getflags(inode);
135138 int error;
136139
137140 if (!inode_owner_or_capable(inode))
....@@ -143,9 +146,6 @@
143146 if (flags & ~FS_IMMUTABLE_FL)
144147 return -EOPNOTSUPP;
145148
146
- if (!capable(CAP_LINUX_IMMUTABLE))
147
- return -EPERM;
148
-
149149 if (flags & FS_IMMUTABLE_FL)
150150 i_flags |= S_IMMUTABLE;
151151
....@@ -155,12 +155,16 @@
155155 return error;
156156
157157 inode_lock(inode);
158
+
159
+ error = vfs_ioc_setflags_prepare(inode, oldflags, flags);
160
+ if (error)
161
+ goto out;
162
+
158163 inode_set_flags(inode, i_flags, S_IMMUTABLE);
164
+out:
159165 inode_unlock(inode);
160
-
161166 mnt_drop_write_file(file);
162
-
163
- return 0;
167
+ return error;
164168 }
165169
166170 static long