/[fuse_dbi]/fuse/cvs/patch/user-mount-2.6.5.patch
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /fuse/cvs/patch/user-mount-2.6.5.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Wed Aug 4 11:36:44 2004 UTC (19 years, 7 months ago) by dpavlin
File size: 12424 byte(s)
import current CVS of fuse

1 dpavlin 4 diff -rup linux-2.6.5.orig/fs/filesystems.c linux-2.6.5/fs/filesystems.c
2     --- linux-2.6.5.orig/fs/filesystems.c 2003-12-18 03:59:18.000000000 +0100
3     +++ linux-2.6.5/fs/filesystems.c 2004-04-05 10:54:37.000000000 +0200
4     @@ -222,7 +222,8 @@ struct file_system_type *get_fs_type(con
5     if (fs && !try_module_get(fs->owner))
6     fs = NULL;
7     read_unlock(&file_systems_lock);
8     - if (!fs && (request_module("%s", name) == 0)) {
9     + if (!fs && capable(CAP_SYS_ADMIN) &&
10     + (request_module("%s", name) == 0)) {
11     read_lock(&file_systems_lock);
12     fs = *(find_filesystem(name));
13     if (fs && !try_module_get(fs->owner))
14     diff -rup linux-2.6.5.orig/fs/namespace.c linux-2.6.5/fs/namespace.c
15     --- linux-2.6.5.orig/fs/namespace.c 2004-04-05 10:50:46.000000000 +0200
16     +++ linux-2.6.5/fs/namespace.c 2004-04-05 10:54:37.000000000 +0200
17     @@ -25,13 +25,16 @@
18    
19     extern int __init init_rootfs(void);
20     extern int __init sysfs_init(void);
21     +extern void put_filesystem(struct file_system_type *fs);
22     +
23     +#define MAX_MOUNTS 256
24    
25     /* spinlock for vfsmount related operations, inplace of dcache_lock */
26     spinlock_t vfsmount_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
27     static struct list_head *mount_hashtable;
28     static int hash_mask, hash_bits;
29     static kmem_cache_t *mnt_cache;
30     -
31     +struct mounts_stat_struct mounts_stat = { .max_mounts = MAX_MOUNTS };
32     static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
33     {
34     unsigned long tmp = ((unsigned long) mnt / L1_CACHE_BYTES);
35     @@ -40,10 +43,38 @@ static inline unsigned long hash(struct
36     return tmp & hash_mask;
37     }
38    
39     +static inline int inc_nr_mounts(void)
40     +{
41     + int err = 0;
42     + spin_lock(&vfsmount_lock);
43     + if (capable(CAP_SYS_ADMIN) ||
44     + mounts_stat.nr_mounts < mounts_stat.max_mounts)
45     + mounts_stat.nr_mounts++;
46     + else
47     + err = mounts_stat.max_mounts ? -EMFILE : -EPERM;
48     + spin_unlock(&vfsmount_lock);
49     + return err;
50     +}
51     +
52     +static inline void dec_nr_mounts(void)
53     +{
54     + spin_lock(&vfsmount_lock);
55     + mounts_stat.nr_mounts--;
56     + spin_unlock(&vfsmount_lock);
57     +}
58     +
59     struct vfsmount *alloc_vfsmnt(const char *name)
60     {
61     - struct vfsmount *mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
62     - if (mnt) {
63     + struct vfsmount *mnt;
64     + int err = inc_nr_mounts();
65     + if (err)
66     + return ERR_PTR(err);
67     +
68     + mnt = kmem_cache_alloc(mnt_cache, GFP_KERNEL);
69     + if (!mnt) {
70     + dec_nr_mounts();
71     + return ERR_PTR(-ENOMEM);
72     + } else {
73     memset(mnt, 0, sizeof(struct vfsmount));
74     atomic_set(&mnt->mnt_count,1);
75     INIT_LIST_HEAD(&mnt->mnt_hash);
76     @@ -66,6 +97,7 @@ void free_vfsmnt(struct vfsmount *mnt)
77     {
78     kfree(mnt->mnt_devname);
79     kmem_cache_free(mnt_cache, mnt);
80     + dec_nr_mounts();
81     }
82    
83     /*
84     @@ -147,13 +179,14 @@ clone_mnt(struct vfsmount *old, struct d
85     struct super_block *sb = old->mnt_sb;
86     struct vfsmount *mnt = alloc_vfsmnt(old->mnt_devname);
87    
88     - if (mnt) {
89     + if (!IS_ERR(mnt)) {
90     mnt->mnt_flags = old->mnt_flags;
91     atomic_inc(&sb->s_active);
92     mnt->mnt_sb = sb;
93     mnt->mnt_root = dget(root);
94     mnt->mnt_mountpoint = mnt->mnt_root;
95     mnt->mnt_parent = mnt;
96     + mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
97     }
98     return mnt;
99     }
100     @@ -238,6 +271,8 @@ static int show_vfsmnt(struct seq_file *
101     if (mnt->mnt_flags & fs_infop->flag)
102     seq_puts(m, fs_infop->str);
103     }
104     + if (mnt->user)
105     + seq_printf(m, ",user=%i", mnt->user);
106     if (mnt->mnt_sb->s_op->show_options)
107     err = mnt->mnt_sb->s_op->show_options(m, mnt);
108     seq_puts(m, " 0 0\n");
109     @@ -388,8 +423,10 @@ asmlinkage long sys_umount(char __user *
110     goto dput_and_out;
111    
112     retval = -EPERM;
113     - if (!capable(CAP_SYS_ADMIN))
114     - goto dput_and_out;
115     + if (!capable(CAP_SYS_ADMIN)) {
116     + if(nd.mnt->user != current->fsuid || (flags & MNT_FORCE))
117     + goto dput_and_out;
118     + }
119    
120     retval = do_umount(nd.mnt, flags);
121     dput_and_out:
122     @@ -409,20 +446,15 @@ asmlinkage long sys_oldumount(char __use
123    
124     static int mount_is_safe(struct nameidata *nd)
125     {
126     - if (capable(CAP_SYS_ADMIN))
127     - return 0;
128     - return -EPERM;
129     -#ifdef notyet
130     - if (S_ISLNK(nd->dentry->d_inode->i_mode))
131     - return -EPERM;
132     - if (nd->dentry->d_inode->i_mode & S_ISVTX) {
133     - if (current->uid != nd->dentry->d_inode->i_uid)
134     + if (!capable(CAP_SYS_ADMIN)) {
135     + if (!S_ISDIR(nd->dentry->d_inode->i_mode) &&
136     + !S_ISREG(nd->dentry->d_inode->i_mode))
137     + return -EPERM;
138     + if (current->fsuid != nd->dentry->d_inode->i_uid ||
139     + permission(nd->dentry->d_inode, MAY_WRITE, nd))
140     return -EPERM;
141     }
142     - if (permission(nd->dentry->d_inode, MAY_WRITE, nd))
143     - return -EPERM;
144     return 0;
145     -#endif
146     }
147    
148     static int
149     @@ -444,8 +476,8 @@ static struct vfsmount *copy_tree(struct
150     struct nameidata nd;
151    
152     res = q = clone_mnt(mnt, dentry);
153     - if (!q)
154     - goto Enomem;
155     + if (IS_ERR(q))
156     + goto out_error;
157     q->mnt_mountpoint = mnt->mnt_mountpoint;
158    
159     p = mnt;
160     @@ -463,8 +495,8 @@ static struct vfsmount *copy_tree(struct
161     nd.mnt = q;
162     nd.dentry = p->mnt_mountpoint;
163     q = clone_mnt(p, p->mnt_root);
164     - if (!q)
165     - goto Enomem;
166     + if (IS_ERR(q))
167     + goto out_error;
168     spin_lock(&vfsmount_lock);
169     list_add_tail(&q->mnt_list, &res->mnt_list);
170     attach_mnt(q, &nd);
171     @@ -472,13 +504,13 @@ static struct vfsmount *copy_tree(struct
172     }
173     }
174     return res;
175     - Enomem:
176     + out_error:
177     if (res) {
178     spin_lock(&vfsmount_lock);
179     umount_tree(res);
180     spin_unlock(&vfsmount_lock);
181     }
182     - return NULL;
183     + return q;
184     }
185    
186     static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
187     @@ -538,11 +570,14 @@ static int do_loopback(struct nameidata
188     down_write(&current->namespace->sem);
189     err = -EINVAL;
190     if (check_mnt(nd->mnt) && (!recurse || check_mnt(old_nd.mnt))) {
191     - err = -ENOMEM;
192     if (recurse)
193     mnt = copy_tree(old_nd.mnt, old_nd.dentry);
194     else
195     mnt = clone_mnt(old_nd.mnt, old_nd.dentry);
196     + if (IS_ERR(mnt)) {
197     + err = PTR_ERR(mnt);
198     + goto out;
199     + }
200     }
201    
202     if (mnt) {
203     @@ -555,6 +590,7 @@ static int do_loopback(struct nameidata
204     mntput(mnt);
205     }
206    
207     + out:
208     up_write(&current->namespace->sem);
209     path_release(&old_nd);
210     return err;
211     @@ -654,14 +690,28 @@ static int do_add_mount(struct nameidata
212     int mnt_flags, char *name, void *data)
213     {
214     struct vfsmount *mnt;
215     - int err;
216     + int err = mount_is_safe(nd);
217     + if(err)
218     + return err;
219    
220     if (!type || !memchr(type, 0, PAGE_SIZE))
221     return -EINVAL;
222    
223     /* we need capabilities... */
224     - if (!capable(CAP_SYS_ADMIN))
225     - return -EPERM;
226     + if (!capable(CAP_SYS_ADMIN)) {
227     + /* but allow "safe" filesystems anyway */
228     + int issafe = 0;
229     + struct file_system_type *t = get_fs_type(type);
230     + if(t) {
231     + issafe = t->fs_flags & FS_SAFE;
232     + put_filesystem(t);
233     + }
234     + if(!issafe)
235     + return -EPERM;
236     +
237     + /* users should not have suid or dev files */
238     + mnt_flags |= (MNT_NOSUID | MNT_NODEV);
239     + }
240    
241     mnt = do_kern_mount(type, flags, name, data);
242     err = PTR_ERR(mnt);
243     @@ -801,6 +851,7 @@ int copy_namespace(int flags, struct tas
244     struct namespace *new_ns;
245     struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
246     struct fs_struct *fs = tsk->fs;
247     + int err;
248    
249     if (!namespace)
250     return 0;
251     @@ -810,11 +861,7 @@ int copy_namespace(int flags, struct tas
252     if (!(flags & CLONE_NEWNS))
253     return 0;
254    
255     - if (!capable(CAP_SYS_ADMIN)) {
256     - put_namespace(namespace);
257     - return -EPERM;
258     - }
259     -
260     + err = -ENOMEM;
261     new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
262     if (!new_ns)
263     goto out;
264     @@ -826,7 +873,8 @@ int copy_namespace(int flags, struct tas
265     down_write(&tsk->namespace->sem);
266     /* First pass: copy the tree topology */
267     new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root);
268     - if (!new_ns->root) {
269     + if (IS_ERR(new_ns->root)) {
270     + err = PTR_ERR(new_ns->root);
271     up_write(&tsk->namespace->sem);
272     kfree(new_ns);
273     goto out;
274     @@ -876,7 +924,7 @@ int copy_namespace(int flags, struct tas
275    
276     out:
277     put_namespace(namespace);
278     - return -ENOMEM;
279     + return err;
280     }
281    
282     asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
283     diff -rup linux-2.6.5.orig/fs/super.c linux-2.6.5/fs/super.c
284     --- linux-2.6.5.orig/fs/super.c 2004-04-05 10:50:46.000000000 +0200
285     +++ linux-2.6.5/fs/super.c 2004-04-05 11:02:10.000000000 +0200
286     @@ -726,7 +726,7 @@ struct vfsmount *
287     do_kern_mount(const char *fstype, int flags, const char *name, void *data)
288     {
289     struct file_system_type *type = get_fs_type(fstype);
290     - struct super_block *sb = ERR_PTR(-ENOMEM);
291     + struct super_block *sb;
292     struct vfsmount *mnt;
293     int error;
294     char *secdata = NULL;
295     @@ -735,24 +735,23 @@ do_kern_mount(const char *fstype, int fl
296     return ERR_PTR(-ENODEV);
297    
298     mnt = alloc_vfsmnt(name);
299     - if (!mnt)
300     + error = PTR_ERR(mnt);
301     + if (IS_ERR(mnt))
302     goto out;
303    
304     if (data) {
305     secdata = alloc_secdata();
306     - if (!secdata) {
307     - sb = ERR_PTR(-ENOMEM);
308     + error = -ENOMEM;
309     + if (!secdata)
310     goto out_mnt;
311     - }
312    
313     error = security_sb_copy_data(type, data, secdata);
314     - if (error) {
315     - sb = ERR_PTR(error);
316     + if (error)
317     goto out_free_secdata;
318     - }
319     }
320    
321     sb = type->get_sb(type, flags, name, data);
322     + error = PTR_ERR(sb);
323     if (IS_ERR(sb))
324     goto out_free_secdata;
325     error = security_sb_kern_mount(sb, secdata);
326     @@ -762,20 +761,20 @@ do_kern_mount(const char *fstype, int fl
327     mnt->mnt_root = dget(sb->s_root);
328     mnt->mnt_mountpoint = sb->s_root;
329     mnt->mnt_parent = mnt;
330     + mnt->user = capable(CAP_SYS_ADMIN) ? 0 : current->fsuid;
331     up_write(&sb->s_umount);
332     put_filesystem(type);
333     return mnt;
334     out_sb:
335     up_write(&sb->s_umount);
336     deactivate_super(sb);
337     - sb = ERR_PTR(error);
338     out_free_secdata:
339     free_secdata(secdata);
340     out_mnt:
341     free_vfsmnt(mnt);
342     out:
343     put_filesystem(type);
344     - return (struct vfsmount *)sb;
345     + return ERR_PTR(error);
346     }
347    
348     struct vfsmount *kern_mount(struct file_system_type *type)
349     diff -rup linux-2.6.5.orig/include/linux/fs.h linux-2.6.5/include/linux/fs.h
350     --- linux-2.6.5.orig/include/linux/fs.h 2004-04-05 10:50:50.000000000 +0200
351     +++ linux-2.6.5/include/linux/fs.h 2004-04-05 11:03:55.000000000 +0200
352     @@ -55,6 +55,12 @@ struct files_stat_struct {
353     };
354     extern struct files_stat_struct files_stat;
355    
356     +struct mounts_stat_struct {
357     + int nr_mounts;
358     + int max_mounts;
359     +};
360     +extern struct mounts_stat_struct mounts_stat;
361     +
362     struct inodes_stat_t {
363     int nr_inodes;
364     int nr_unused;
365     @@ -90,6 +96,7 @@ extern int leases_enable, dir_notify_ena
366     /* public flags for file_system_type */
367     #define FS_REQUIRES_DEV 1
368     #define FS_BINARY_MOUNTDATA 2
369     +#define FS_SAFE 4 /* Safe to mount by user */
370     #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
371     #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
372     * as nfs_rename() will be cleaned up
373     diff -rup linux-2.6.5.orig/include/linux/mount.h linux-2.6.5/include/linux/mount.h
374     --- linux-2.6.5.orig/include/linux/mount.h 2003-12-18 03:58:08.000000000 +0100
375     +++ linux-2.6.5/include/linux/mount.h 2004-04-05 10:54:37.000000000 +0200
376     @@ -30,6 +30,7 @@ struct vfsmount
377     atomic_t mnt_count;
378     int mnt_flags;
379     char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
380     + uid_t user;
381     struct list_head mnt_list;
382     };
383    
384     diff -rup linux-2.6.5.orig/include/linux/sysctl.h linux-2.6.5/include/linux/sysctl.h
385     --- linux-2.6.5.orig/include/linux/sysctl.h 2004-04-05 10:50:50.000000000 +0200
386     +++ linux-2.6.5/include/linux/sysctl.h 2004-04-05 10:54:37.000000000 +0200
387     @@ -624,8 +624,8 @@ enum
388     FS_NRFILE=6, /* int:current number of allocated filedescriptors */
389     FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated */
390     FS_DENTRY=8,
391     - FS_NRSUPER=9, /* int:current number of allocated super_blocks */
392     - FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
393     + FS_NRMOUNT=9, /* int:current number of mounts */
394     + FS_MAXMOUNT=10, /* int:maximum number of mounts allowed */
395     FS_OVERFLOWUID=11, /* int: overflow UID */
396     FS_OVERFLOWGID=12, /* int: overflow GID */
397     FS_LEASES=13, /* int: leases enabled */
398     diff -rup linux-2.6.5.orig/kernel/sysctl.c linux-2.6.5/kernel/sysctl.c
399     --- linux-2.6.5.orig/kernel/sysctl.c 2004-04-05 10:50:51.000000000 +0200
400     +++ linux-2.6.5/kernel/sysctl.c 2004-04-05 10:54:37.000000000 +0200
401     @@ -793,6 +793,22 @@ static ctl_table fs_table[] = {
402     .proc_handler = &proc_dointvec,
403     },
404     {
405     + .ctl_name = FS_NRMOUNT,
406     + .procname = "mount-nr",
407     + .data = &mounts_stat.nr_mounts,
408     + .maxlen = sizeof(int),
409     + .mode = 0444,
410     + .proc_handler = &proc_dointvec,
411     + },
412     + {
413     + .ctl_name = FS_MAXMOUNT,
414     + .procname = "mount-max",
415     + .data = &mounts_stat.max_mounts,
416     + .maxlen = sizeof(int),
417     + .mode = 0644,
418     + .proc_handler = &proc_dointvec,
419     + },
420     + {
421     .ctl_name = FS_OVERFLOWUID,
422     .procname = "overflowuid",
423     .data = &fs_overflowuid,

  ViewVC Help
Powered by ViewVC 1.1.26