Commit e4792aa30f9d33584d7192685ed149cc5fee737f

Authored by Robin Getz
Committed by Greg Kroah-Hartman
1 parent 156f5a7801

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

... ... @@ -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);