summaryrefslogtreecommitdiffstats
path: root/security/inode.c
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2017-05-07 08:53:37 -0400
committerJohn Johansen <john.johansen@canonical.com>2017-06-08 15:51:43 -0400
commit6623ec7c4dbe18a5a2878e2d888be70d08a91826 (patch)
treeb0276f0c66e05836c58eb57b04a545f1dfd06260 /security/inode.c
parent4227c333f65cddc6c2f048e5b67cfe796b9df9a6 (diff)
securityfs: add the ability to support symlinks
Signed-off-by: John Johansen <john.johansen@canonical.com> Reviewed-by: Seth Arnold <seth.arnold@canonical.com> Acked-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'security/inode.c')
-rw-r--r--security/inode.c144
1 files changed, 123 insertions, 21 deletions
diff --git a/security/inode.c b/security/inode.c
index eccd58ef2ae8..8dd9ca8848e4 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -26,11 +26,31 @@
26static struct vfsmount *mount; 26static struct vfsmount *mount;
27static int mount_count; 27static int mount_count;
28 28
29static void securityfs_evict_inode(struct inode *inode)
30{
31 truncate_inode_pages_final(&inode->i_data);
32 clear_inode(inode);
33 if (S_ISLNK(inode->i_mode))
34 kfree(inode->i_link);
35}
36
37static const struct super_operations securityfs_super_operations = {
38 .statfs = simple_statfs,
39 .evict_inode = securityfs_evict_inode,
40};
41
29static int fill_super(struct super_block *sb, void *data, int silent) 42static int fill_super(struct super_block *sb, void *data, int silent)
30{ 43{
31 static const struct tree_descr files[] = {{""}}; 44 static const struct tree_descr files[] = {{""}};
45 int error;
46
47 error = simple_fill_super(sb, SECURITYFS_MAGIC, files);
48 if (error)
49 return error;
50
51 sb->s_op = &securityfs_super_operations;
32 52
33 return simple_fill_super(sb, SECURITYFS_MAGIC, files); 53 return 0;
34} 54}
35 55
36static struct dentry *get_sb(struct file_system_type *fs_type, 56static struct dentry *get_sb(struct file_system_type *fs_type,
@@ -48,7 +68,7 @@ static struct file_system_type fs_type = {
48}; 68};
49 69
50/** 70/**
51 * securityfs_create_file - create a file in the securityfs filesystem 71 * securityfs_create_dentry - create a dentry in the securityfs filesystem
52 * 72 *
53 * @name: a pointer to a string containing the name of the file to create. 73 * @name: a pointer to a string containing the name of the file to create.
54 * @mode: the permission that the file should have 74 * @mode: the permission that the file should have
@@ -60,34 +80,35 @@ static struct file_system_type fs_type = {
60 * the open() call. 80 * the open() call.
61 * @fops: a pointer to a struct file_operations that should be used for 81 * @fops: a pointer to a struct file_operations that should be used for
62 * this file. 82 * this file.
83 * @iops: a point to a struct of inode_operations that should be used for
84 * this file/dir
63 * 85 *
64 * This is the basic "create a file" function for securityfs. It allows for a 86 * This is the basic "create a file/dir/symlink" function for
65 * wide range of flexibility in creating a file, or a directory (if you 87 * securityfs. It allows for a wide range of flexibility in creating
66 * want to create a directory, the securityfs_create_dir() function is 88 * a file, or a directory (if you want to create a directory, the
67 * recommended to be used instead). 89 * securityfs_create_dir() function is recommended to be used
90 * instead).
68 * 91 *
69 * This function returns a pointer to a dentry if it succeeds. This 92 * This function returns a pointer to a dentry if it succeeds. This
70 * pointer must be passed to the securityfs_remove() function when the file is 93 * pointer must be passed to the securityfs_remove() function when the
71 * to be removed (no automatic cleanup happens if your module is unloaded, 94 * file is to be removed (no automatic cleanup happens if your module
72 * you are responsible here). If an error occurs, the function will return 95 * is unloaded, you are responsible here). If an error occurs, the
73 * the error value (via ERR_PTR). 96 * function will return the error value (via ERR_PTR).
74 * 97 *
75 * If securityfs is not enabled in the kernel, the value %-ENODEV is 98 * If securityfs is not enabled in the kernel, the value %-ENODEV is
76 * returned. 99 * returned.
77 */ 100 */
78struct dentry *securityfs_create_file(const char *name, umode_t mode, 101static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
79 struct dentry *parent, void *data, 102 struct dentry *parent, void *data,
80 const struct file_operations *fops) 103 const struct file_operations *fops,
104 const struct inode_operations *iops)
81{ 105{
82 struct dentry *dentry; 106 struct dentry *dentry;
83 int is_dir = S_ISDIR(mode);
84 struct inode *dir, *inode; 107 struct inode *dir, *inode;
85 int error; 108 int error;
86 109
87 if (!is_dir) { 110 if (!(mode & S_IFMT))
88 BUG_ON(!fops);
89 mode = (mode & S_IALLUGO) | S_IFREG; 111 mode = (mode & S_IALLUGO) | S_IFREG;
90 }
91 112
92 pr_debug("securityfs: creating file '%s'\n",name); 113 pr_debug("securityfs: creating file '%s'\n",name);
93 114
@@ -120,11 +141,14 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
120 inode->i_mode = mode; 141 inode->i_mode = mode;
121 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); 142 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
122 inode->i_private = data; 143 inode->i_private = data;
123 if (is_dir) { 144 if (S_ISDIR(mode)) {
124 inode->i_op = &simple_dir_inode_operations; 145 inode->i_op = &simple_dir_inode_operations;
125 inode->i_fop = &simple_dir_operations; 146 inode->i_fop = &simple_dir_operations;
126 inc_nlink(inode); 147 inc_nlink(inode);
127 inc_nlink(dir); 148 inc_nlink(dir);
149 } else if (S_ISLNK(mode)) {
150 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
151 inode->i_link = data;
128 } else { 152 } else {
129 inode->i_fop = fops; 153 inode->i_fop = fops;
130 } 154 }
@@ -141,6 +165,38 @@ out:
141 simple_release_fs(&mount, &mount_count); 165 simple_release_fs(&mount, &mount_count);
142 return dentry; 166 return dentry;
143} 167}
168
169/**
170 * securityfs_create_file - create a file in the securityfs filesystem
171 *
172 * @name: a pointer to a string containing the name of the file to create.
173 * @mode: the permission that the file should have
174 * @parent: a pointer to the parent dentry for this file. This should be a
175 * directory dentry if set. If this parameter is %NULL, then the
176 * file will be created in the root of the securityfs filesystem.
177 * @data: a pointer to something that the caller will want to get to later
178 * on. The inode.i_private pointer will point to this value on
179 * the open() call.
180 * @fops: a pointer to a struct file_operations that should be used for
181 * this file.
182 *
183 * This function creates a file in securityfs with the given @name.
184 *
185 * This function returns a pointer to a dentry if it succeeds. This
186 * pointer must be passed to the securityfs_remove() function when the file is
187 * to be removed (no automatic cleanup happens if your module is unloaded,
188 * you are responsible here). If an error occurs, the function will return
189 * the error value (via ERR_PTR).
190 *
191 * If securityfs is not enabled in the kernel, the value %-ENODEV is
192 * returned.
193 */
194struct dentry *securityfs_create_file(const char *name, umode_t mode,
195 struct dentry *parent, void *data,
196 const struct file_operations *fops)
197{
198 return securityfs_create_dentry(name, mode, parent, data, fops, NULL);
199}
144EXPORT_SYMBOL_GPL(securityfs_create_file); 200EXPORT_SYMBOL_GPL(securityfs_create_file);
145 201
146/** 202/**
@@ -165,13 +221,59 @@ EXPORT_SYMBOL_GPL(securityfs_create_file);
165 */ 221 */
166struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 222struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
167{ 223{
168 return securityfs_create_file(name, 224 return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL);
169 S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
170 parent, NULL, NULL);
171} 225}
172EXPORT_SYMBOL_GPL(securityfs_create_dir); 226EXPORT_SYMBOL_GPL(securityfs_create_dir);
173 227
174/** 228/**
229 * securityfs_create_symlink - create a symlink in the securityfs filesystem
230 *
231 * @name: a pointer to a string containing the name of the symlink to
232 * create.
233 * @parent: a pointer to the parent dentry for the symlink. This should be a
234 * directory dentry if set. If this parameter is %NULL, then the
235 * directory will be created in the root of the securityfs filesystem.
236 * @target: a pointer to a string containing the name of the symlink's target.
237 * If this parameter is %NULL, then the @iops parameter needs to be
238 * setup to handle .readlink and .get_link inode_operations.
239 * @iops: a pointer to the struct inode_operations to use for the symlink. If
240 * this parameter is %NULL, then the default simple_symlink_inode
241 * operations will be used.
242 *
243 * This function creates a symlink in securityfs with the given @name.
244 *
245 * This function returns a pointer to a dentry if it succeeds. This
246 * pointer must be passed to the securityfs_remove() function when the file is
247 * to be removed (no automatic cleanup happens if your module is unloaded,
248 * you are responsible here). If an error occurs, the function will return
249 * the error value (via ERR_PTR).
250 *
251 * If securityfs is not enabled in the kernel, the value %-ENODEV is
252 * returned.
253 */
254struct dentry *securityfs_create_symlink(const char *name,
255 struct dentry *parent,
256 const char *target,
257 const struct inode_operations *iops)
258{
259 struct dentry *dent;
260 char *link = NULL;
261
262 if (target) {
263 link = kstrdup(target, GFP_KERNEL);
264 if (!link)
265 return ERR_PTR(-ENOMEM);
266 }
267 dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent,
268 link, NULL, iops);
269 if (IS_ERR(dent))
270 kfree(link);
271
272 return dent;
273}
274EXPORT_SYMBOL_GPL(securityfs_create_symlink);
275
276/**
175 * securityfs_remove - removes a file or directory from the securityfs filesystem 277 * securityfs_remove - removes a file or directory from the securityfs filesystem
176 * 278 *
177 * @dentry: a pointer to a the dentry of the file or directory to be removed. 279 * @dentry: a pointer to a the dentry of the file or directory to be removed.