Commit e4792aa30f9d33584d7192685ed149cc5fee737f
Committed by
Greg Kroah-Hartman
1 parent
156f5a7801
Exists in
master
and in
7 other branches
debugfs: use specified mode to possibly mark files read/write only
In many SoC implementations there are hardware registers can be read or write only. This extends the debugfs to enforce the file permissions for these types of registers by providing a set of fops which are read or write only. This assumes that the kernel developer knows more about the hardware than the user (even root users) -- which is normally true. Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Bryan Wu <cooloney@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 1 changed file with 63 additions and 0 deletions Side-by-side Diff
fs/debugfs/file.c
... | ... | @@ -67,6 +67,8 @@ |
67 | 67 | return 0; |
68 | 68 | } |
69 | 69 | DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); |
70 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u8_ro, debugfs_u8_get, NULL, "%llu\n"); | |
71 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u8_wo, NULL, debugfs_u8_set, "%llu\n"); | |
70 | 72 | |
71 | 73 | /** |
72 | 74 | * debugfs_create_u8 - create a debugfs file that is used to read and write an unsigned 8-bit value |
... | ... | @@ -95,6 +97,13 @@ |
95 | 97 | struct dentry *debugfs_create_u8(const char *name, mode_t mode, |
96 | 98 | struct dentry *parent, u8 *value) |
97 | 99 | { |
100 | + /* if there are no write bits set, make read only */ | |
101 | + if (!(mode & S_IWUGO)) | |
102 | + return debugfs_create_file(name, mode, parent, value, &fops_u8_ro); | |
103 | + /* if there are no read bits set, make write only */ | |
104 | + if (!(mode & S_IRUGO)) | |
105 | + return debugfs_create_file(name, mode, parent, value, &fops_u8_wo); | |
106 | + | |
98 | 107 | return debugfs_create_file(name, mode, parent, value, &fops_u8); |
99 | 108 | } |
100 | 109 | EXPORT_SYMBOL_GPL(debugfs_create_u8); |
... | ... | @@ -110,6 +119,8 @@ |
110 | 119 | return 0; |
111 | 120 | } |
112 | 121 | DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); |
122 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u16_ro, debugfs_u16_get, NULL, "%llu\n"); | |
123 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u16_wo, NULL, debugfs_u16_set, "%llu\n"); | |
113 | 124 | |
114 | 125 | /** |
115 | 126 | * debugfs_create_u16 - create a debugfs file that is used to read and write an unsigned 16-bit value |
... | ... | @@ -138,6 +149,13 @@ |
138 | 149 | struct dentry *debugfs_create_u16(const char *name, mode_t mode, |
139 | 150 | struct dentry *parent, u16 *value) |
140 | 151 | { |
152 | + /* if there are no write bits set, make read only */ | |
153 | + if (!(mode & S_IWUGO)) | |
154 | + return debugfs_create_file(name, mode, parent, value, &fops_u16_ro); | |
155 | + /* if there are no read bits set, make write only */ | |
156 | + if (!(mode & S_IRUGO)) | |
157 | + return debugfs_create_file(name, mode, parent, value, &fops_u16_wo); | |
158 | + | |
141 | 159 | return debugfs_create_file(name, mode, parent, value, &fops_u16); |
142 | 160 | } |
143 | 161 | EXPORT_SYMBOL_GPL(debugfs_create_u16); |
... | ... | @@ -153,6 +171,8 @@ |
153 | 171 | return 0; |
154 | 172 | } |
155 | 173 | DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); |
174 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u32_ro, debugfs_u32_get, NULL, "%llu\n"); | |
175 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n"); | |
156 | 176 | |
157 | 177 | /** |
158 | 178 | * debugfs_create_u32 - create a debugfs file that is used to read and write an unsigned 32-bit value |
... | ... | @@ -181,6 +201,13 @@ |
181 | 201 | struct dentry *debugfs_create_u32(const char *name, mode_t mode, |
182 | 202 | struct dentry *parent, u32 *value) |
183 | 203 | { |
204 | + /* if there are no write bits set, make read only */ | |
205 | + if (!(mode & S_IWUGO)) | |
206 | + return debugfs_create_file(name, mode, parent, value, &fops_u32_ro); | |
207 | + /* if there are no read bits set, make write only */ | |
208 | + if (!(mode & S_IRUGO)) | |
209 | + return debugfs_create_file(name, mode, parent, value, &fops_u32_wo); | |
210 | + | |
184 | 211 | return debugfs_create_file(name, mode, parent, value, &fops_u32); |
185 | 212 | } |
186 | 213 | EXPORT_SYMBOL_GPL(debugfs_create_u32); |
... | ... | @@ -197,6 +224,8 @@ |
197 | 224 | return 0; |
198 | 225 | } |
199 | 226 | DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n"); |
227 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u64_ro, debugfs_u64_get, NULL, "%llu\n"); | |
228 | +DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); | |
200 | 229 | |
201 | 230 | /** |
202 | 231 | * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value |
203 | 232 | |
204 | 233 | |
205 | 234 | |
... | ... | @@ -225,15 +254,28 @@ |
225 | 254 | struct dentry *debugfs_create_u64(const char *name, mode_t mode, |
226 | 255 | struct dentry *parent, u64 *value) |
227 | 256 | { |
257 | + /* if there are no write bits set, make read only */ | |
258 | + if (!(mode & S_IWUGO)) | |
259 | + return debugfs_create_file(name, mode, parent, value, &fops_u64_ro); | |
260 | + /* if there are no read bits set, make write only */ | |
261 | + if (!(mode & S_IRUGO)) | |
262 | + return debugfs_create_file(name, mode, parent, value, &fops_u64_wo); | |
263 | + | |
228 | 264 | return debugfs_create_file(name, mode, parent, value, &fops_u64); |
229 | 265 | } |
230 | 266 | EXPORT_SYMBOL_GPL(debugfs_create_u64); |
231 | 267 | |
232 | 268 | DEFINE_SIMPLE_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n"); |
269 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x8_ro, debugfs_u8_get, NULL, "0x%02llx\n"); | |
270 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x8_wo, NULL, debugfs_u8_set, "0x%02llx\n"); | |
233 | 271 | |
234 | 272 | DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n"); |
273 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x16_ro, debugfs_u16_get, NULL, "0x%04llx\n"); | |
274 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x16_wo, NULL, debugfs_u16_set, "0x%04llx\n"); | |
235 | 275 | |
236 | 276 | DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n"); |
277 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x32_ro, debugfs_u32_get, NULL, "0x%08llx\n"); | |
278 | +DEFINE_SIMPLE_ATTRIBUTE(fops_x32_wo, NULL, debugfs_u32_set, "0x%08llx\n"); | |
237 | 279 | |
238 | 280 | /* |
239 | 281 | * debugfs_create_x{8,16,32} - create a debugfs file that is used to read and write an unsigned {8,16,32}-bit value |
... | ... | @@ -256,6 +298,13 @@ |
256 | 298 | struct dentry *debugfs_create_x8(const char *name, mode_t mode, |
257 | 299 | struct dentry *parent, u8 *value) |
258 | 300 | { |
301 | + /* if there are no write bits set, make read only */ | |
302 | + if (!(mode & S_IWUGO)) | |
303 | + return debugfs_create_file(name, mode, parent, value, &fops_x8_ro); | |
304 | + /* if there are no read bits set, make write only */ | |
305 | + if (!(mode & S_IRUGO)) | |
306 | + return debugfs_create_file(name, mode, parent, value, &fops_x8_wo); | |
307 | + | |
259 | 308 | return debugfs_create_file(name, mode, parent, value, &fops_x8); |
260 | 309 | } |
261 | 310 | EXPORT_SYMBOL_GPL(debugfs_create_x8); |
... | ... | @@ -273,6 +322,13 @@ |
273 | 322 | struct dentry *debugfs_create_x16(const char *name, mode_t mode, |
274 | 323 | struct dentry *parent, u16 *value) |
275 | 324 | { |
325 | + /* if there are no write bits set, make read only */ | |
326 | + if (!(mode & S_IWUGO)) | |
327 | + return debugfs_create_file(name, mode, parent, value, &fops_x16_ro); | |
328 | + /* if there are no read bits set, make write only */ | |
329 | + if (!(mode & S_IRUGO)) | |
330 | + return debugfs_create_file(name, mode, parent, value, &fops_x16_wo); | |
331 | + | |
276 | 332 | return debugfs_create_file(name, mode, parent, value, &fops_x16); |
277 | 333 | } |
278 | 334 | EXPORT_SYMBOL_GPL(debugfs_create_x16); |
... | ... | @@ -290,6 +346,13 @@ |
290 | 346 | struct dentry *debugfs_create_x32(const char *name, mode_t mode, |
291 | 347 | struct dentry *parent, u32 *value) |
292 | 348 | { |
349 | + /* if there are no write bits set, make read only */ | |
350 | + if (!(mode & S_IWUGO)) | |
351 | + return debugfs_create_file(name, mode, parent, value, &fops_x32_ro); | |
352 | + /* if there are no read bits set, make write only */ | |
353 | + if (!(mode & S_IRUGO)) | |
354 | + return debugfs_create_file(name, mode, parent, value, &fops_x32_wo); | |
355 | + | |
293 | 356 | return debugfs_create_file(name, mode, parent, value, &fops_x32); |
294 | 357 | } |
295 | 358 | EXPORT_SYMBOL_GPL(debugfs_create_x32); |