| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|---|
| 2 | /* | 
|---|
| 3 | *  Copyright 1997-1998 Transmeta Corporation - All Rights Reserved | 
|---|
| 4 | *  Copyright 2005-2006 Ian Kent <raven@themaw.net> | 
|---|
| 5 | */ | 
|---|
| 6 |  | 
|---|
| 7 | /* Internal header file for autofs */ | 
|---|
| 8 |  | 
|---|
| 9 | #include <linux/auto_fs.h> | 
|---|
| 10 | #include <linux/auto_dev-ioctl.h> | 
|---|
| 11 |  | 
|---|
| 12 | #include <linux/kernel.h> | 
|---|
| 13 | #include <linux/slab.h> | 
|---|
| 14 | #include <linux/time.h> | 
|---|
| 15 | #include <linux/string.h> | 
|---|
| 16 | #include <linux/wait.h> | 
|---|
| 17 | #include <linux/sched.h> | 
|---|
| 18 | #include <linux/sched/signal.h> | 
|---|
| 19 | #include <linux/mount.h> | 
|---|
| 20 | #include <linux/namei.h> | 
|---|
| 21 | #include <linux/uaccess.h> | 
|---|
| 22 | #include <linux/mutex.h> | 
|---|
| 23 | #include <linux/spinlock.h> | 
|---|
| 24 | #include <linux/list.h> | 
|---|
| 25 | #include <linux/completion.h> | 
|---|
| 26 | #include <linux/file.h> | 
|---|
| 27 | #include <linux/magic.h> | 
|---|
| 28 | #include <linux/fs_context.h> | 
|---|
| 29 | #include <linux/fs_parser.h> | 
|---|
| 30 |  | 
|---|
| 31 | /* This is the range of ioctl() numbers we claim as ours */ | 
|---|
| 32 | #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY | 
|---|
| 33 | #define AUTOFS_IOC_COUNT     32 | 
|---|
| 34 |  | 
|---|
| 35 | #define AUTOFS_DEV_IOCTL_IOC_FIRST	(AUTOFS_DEV_IOCTL_VERSION) | 
|---|
| 36 | #define AUTOFS_DEV_IOCTL_IOC_COUNT \ | 
|---|
| 37 | (AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD - AUTOFS_DEV_IOCTL_VERSION_CMD) | 
|---|
| 38 |  | 
|---|
| 39 | #ifdef pr_fmt | 
|---|
| 40 | #undef pr_fmt | 
|---|
| 41 | #endif | 
|---|
| 42 | #define pr_fmt(fmt) KBUILD_MODNAME ":pid:%d:%s: " fmt, current->pid, __func__ | 
|---|
| 43 |  | 
|---|
| 44 | extern struct file_system_type autofs_fs_type; | 
|---|
| 45 |  | 
|---|
| 46 | /* | 
|---|
| 47 | * Unified info structure.  This is pointed to by both the dentry and | 
|---|
| 48 | * inode structures.  Each file in the filesystem has an instance of this | 
|---|
| 49 | * structure.  It holds a reference to the dentry, so dentries are never | 
|---|
| 50 | * flushed while the file exists.  All name lookups are dealt with at the | 
|---|
| 51 | * dentry level, although the filesystem can interfere in the validation | 
|---|
| 52 | * process.  Readdir is implemented by traversing the dentry lists. | 
|---|
| 53 | */ | 
|---|
| 54 | struct autofs_info { | 
|---|
| 55 | struct dentry	*dentry; | 
|---|
| 56 | int		flags; | 
|---|
| 57 |  | 
|---|
| 58 | struct completion expire_complete; | 
|---|
| 59 |  | 
|---|
| 60 | struct list_head active; | 
|---|
| 61 |  | 
|---|
| 62 | struct list_head expiring; | 
|---|
| 63 |  | 
|---|
| 64 | struct autofs_sb_info *sbi; | 
|---|
| 65 | unsigned long exp_timeout; | 
|---|
| 66 | unsigned long last_used; | 
|---|
| 67 | int count; | 
|---|
| 68 |  | 
|---|
| 69 | kuid_t uid; | 
|---|
| 70 | kgid_t gid; | 
|---|
| 71 | struct rcu_head rcu; | 
|---|
| 72 | }; | 
|---|
| 73 |  | 
|---|
| 74 | #define AUTOFS_INF_EXPIRING	(1<<0) /* dentry in the process of expiring */ | 
|---|
| 75 | #define AUTOFS_INF_WANT_EXPIRE	(1<<1) /* the dentry is being considered | 
|---|
| 76 | * for expiry, so RCU_walk is | 
|---|
| 77 | * not permitted.  If it progresses to | 
|---|
| 78 | * actual expiry attempt, the flag is | 
|---|
| 79 | * not cleared when EXPIRING is set - | 
|---|
| 80 | * in that case it gets cleared only | 
|---|
| 81 | * when it comes to clearing EXPIRING. | 
|---|
| 82 | */ | 
|---|
| 83 | #define AUTOFS_INF_PENDING	(1<<2) /* dentry pending mount */ | 
|---|
| 84 |  | 
|---|
| 85 | #define AUTOFS_INF_EXPIRE_SET	(1<<3) /* per-dentry expire timeout set for | 
|---|
| 86 | this mount point. | 
|---|
| 87 | */ | 
|---|
| 88 | struct autofs_wait_queue { | 
|---|
| 89 | wait_queue_head_t queue; | 
|---|
| 90 | struct autofs_wait_queue *next; | 
|---|
| 91 | autofs_wqt_t wait_queue_token; | 
|---|
| 92 | /* We use the following to see what we are waiting for */ | 
|---|
| 93 | struct qstr name; | 
|---|
| 94 | u32 offset; | 
|---|
| 95 | u32 dev; | 
|---|
| 96 | u64 ino; | 
|---|
| 97 | kuid_t uid; | 
|---|
| 98 | kgid_t gid; | 
|---|
| 99 | pid_t pid; | 
|---|
| 100 | pid_t tgid; | 
|---|
| 101 | /* This is for status reporting upon return */ | 
|---|
| 102 | int status; | 
|---|
| 103 | unsigned int wait_ctr; | 
|---|
| 104 | }; | 
|---|
| 105 |  | 
|---|
| 106 | #define AUTOFS_SBI_MAGIC 0x6d4a556d | 
|---|
| 107 |  | 
|---|
| 108 | #define AUTOFS_SBI_CATATONIC	0x0001 | 
|---|
| 109 | #define AUTOFS_SBI_STRICTEXPIRE 0x0002 | 
|---|
| 110 | #define AUTOFS_SBI_IGNORE	0x0004 | 
|---|
| 111 |  | 
|---|
| 112 | struct autofs_sb_info { | 
|---|
| 113 | u32 magic; | 
|---|
| 114 | int pipefd; | 
|---|
| 115 | struct file *pipe; | 
|---|
| 116 | struct pid *oz_pgrp; | 
|---|
| 117 | int version; | 
|---|
| 118 | int sub_version; | 
|---|
| 119 | int min_proto; | 
|---|
| 120 | int max_proto; | 
|---|
| 121 | unsigned int flags; | 
|---|
| 122 | unsigned long exp_timeout; | 
|---|
| 123 | unsigned int type; | 
|---|
| 124 | struct super_block *sb; | 
|---|
| 125 | struct mutex wq_mutex; | 
|---|
| 126 | struct mutex pipe_mutex; | 
|---|
| 127 | spinlock_t fs_lock; | 
|---|
| 128 | struct autofs_wait_queue *queues; /* Wait queue pointer */ | 
|---|
| 129 | spinlock_t lookup_lock; | 
|---|
| 130 | struct list_head active_list; | 
|---|
| 131 | struct list_head expiring_list; | 
|---|
| 132 | struct rcu_head rcu; | 
|---|
| 133 | }; | 
|---|
| 134 |  | 
|---|
| 135 | static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb) | 
|---|
| 136 | { | 
|---|
| 137 | return (struct autofs_sb_info *)(sb->s_fs_info); | 
|---|
| 138 | } | 
|---|
| 139 |  | 
|---|
| 140 | static inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry) | 
|---|
| 141 | { | 
|---|
| 142 | return (struct autofs_info *)(dentry->d_fsdata); | 
|---|
| 143 | } | 
|---|
| 144 |  | 
|---|
| 145 | /* autofs_oz_mode(): do we see the man behind the curtain?  (The | 
|---|
| 146 | * processes which do manipulations for us in user space sees the raw | 
|---|
| 147 | * filesystem without "magic".) | 
|---|
| 148 | */ | 
|---|
| 149 | static inline int autofs_oz_mode(struct autofs_sb_info *sbi) | 
|---|
| 150 | { | 
|---|
| 151 | return ((sbi->flags & AUTOFS_SBI_CATATONIC) || | 
|---|
| 152 | task_pgrp(current) == sbi->oz_pgrp); | 
|---|
| 153 | } | 
|---|
| 154 |  | 
|---|
| 155 | static inline bool autofs_empty(struct autofs_info *ino) | 
|---|
| 156 | { | 
|---|
| 157 | return ino->count < 2; | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | struct inode *autofs_get_inode(struct super_block *, umode_t); | 
|---|
| 161 | void autofs_free_ino(struct autofs_info *); | 
|---|
| 162 |  | 
|---|
| 163 | /* Expiration */ | 
|---|
| 164 | int is_autofs_dentry(struct dentry *); | 
|---|
| 165 | int autofs_expire_wait(const struct path *path, int rcu_walk); | 
|---|
| 166 | int autofs_expire_run(struct super_block *, struct vfsmount *, | 
|---|
| 167 | struct autofs_sb_info *, | 
|---|
| 168 | struct autofs_packet_expire __user *); | 
|---|
| 169 | int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, | 
|---|
| 170 | struct autofs_sb_info *sbi, unsigned int how); | 
|---|
| 171 | int autofs_expire_multi(struct super_block *, struct vfsmount *, | 
|---|
| 172 | struct autofs_sb_info *, int __user *); | 
|---|
| 173 |  | 
|---|
| 174 | /* Device node initialization */ | 
|---|
| 175 |  | 
|---|
| 176 | int autofs_dev_ioctl_init(void); | 
|---|
| 177 | void autofs_dev_ioctl_exit(void); | 
|---|
| 178 |  | 
|---|
| 179 | /* Operations structures */ | 
|---|
| 180 |  | 
|---|
| 181 | extern const struct inode_operations autofs_symlink_inode_operations; | 
|---|
| 182 | extern const struct inode_operations autofs_dir_inode_operations; | 
|---|
| 183 | extern const struct file_operations autofs_dir_operations; | 
|---|
| 184 | extern const struct file_operations autofs_root_operations; | 
|---|
| 185 | extern const struct dentry_operations autofs_dentry_operations; | 
|---|
| 186 |  | 
|---|
| 187 | /* VFS automount flags management functions */ | 
|---|
| 188 | static inline void __managed_dentry_set_managed(struct dentry *dentry) | 
|---|
| 189 | { | 
|---|
| 190 | dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); | 
|---|
| 191 | } | 
|---|
| 192 |  | 
|---|
| 193 | static inline void managed_dentry_set_managed(struct dentry *dentry) | 
|---|
| 194 | { | 
|---|
| 195 | spin_lock(lock: &dentry->d_lock); | 
|---|
| 196 | __managed_dentry_set_managed(dentry); | 
|---|
| 197 | spin_unlock(lock: &dentry->d_lock); | 
|---|
| 198 | } | 
|---|
| 199 |  | 
|---|
| 200 | static inline void __managed_dentry_clear_managed(struct dentry *dentry) | 
|---|
| 201 | { | 
|---|
| 202 | dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT); | 
|---|
| 203 | } | 
|---|
| 204 |  | 
|---|
| 205 | static inline void managed_dentry_clear_managed(struct dentry *dentry) | 
|---|
| 206 | { | 
|---|
| 207 | spin_lock(lock: &dentry->d_lock); | 
|---|
| 208 | __managed_dentry_clear_managed(dentry); | 
|---|
| 209 | spin_unlock(lock: &dentry->d_lock); | 
|---|
| 210 | } | 
|---|
| 211 |  | 
|---|
| 212 | /* Initializing function */ | 
|---|
| 213 |  | 
|---|
| 214 | extern const struct fs_parameter_spec autofs_param_specs[]; | 
|---|
| 215 | int autofs_init_fs_context(struct fs_context *fc); | 
|---|
| 216 | struct autofs_info *autofs_new_ino(struct autofs_sb_info *); | 
|---|
| 217 | void autofs_clean_ino(struct autofs_info *); | 
|---|
| 218 |  | 
|---|
| 219 | static inline int autofs_check_pipe(struct file *pipe) | 
|---|
| 220 | { | 
|---|
| 221 | if (pipe->f_mode & FMODE_PATH) | 
|---|
| 222 | return -EINVAL; | 
|---|
| 223 | if (!(pipe->f_mode & FMODE_CAN_WRITE)) | 
|---|
| 224 | return -EINVAL; | 
|---|
| 225 | if (!S_ISFIFO(file_inode(pipe)->i_mode)) | 
|---|
| 226 | return -EINVAL; | 
|---|
| 227 | return 0; | 
|---|
| 228 | } | 
|---|
| 229 |  | 
|---|
| 230 | static inline void autofs_set_packet_pipe_flags(struct file *pipe) | 
|---|
| 231 | { | 
|---|
| 232 | /* We want a packet pipe */ | 
|---|
| 233 | pipe->f_flags |= O_DIRECT; | 
|---|
| 234 | /* We don't expect -EAGAIN */ | 
|---|
| 235 | pipe->f_flags &= ~O_NONBLOCK; | 
|---|
| 236 | } | 
|---|
| 237 |  | 
|---|
| 238 | static inline int autofs_prepare_pipe(struct file *pipe) | 
|---|
| 239 | { | 
|---|
| 240 | int ret = autofs_check_pipe(pipe); | 
|---|
| 241 | if (ret < 0) | 
|---|
| 242 | return ret; | 
|---|
| 243 | autofs_set_packet_pipe_flags(pipe); | 
|---|
| 244 | return 0; | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | /* Queue management functions */ | 
|---|
| 248 |  | 
|---|
| 249 | int autofs_wait(struct autofs_sb_info *, | 
|---|
| 250 | const struct path *, enum autofs_notify); | 
|---|
| 251 | int autofs_wait_release(struct autofs_sb_info *, autofs_wqt_t, int); | 
|---|
| 252 | void autofs_catatonic_mode(struct autofs_sb_info *); | 
|---|
| 253 |  | 
|---|
| 254 | static inline u32 autofs_get_dev(struct autofs_sb_info *sbi) | 
|---|
| 255 | { | 
|---|
| 256 | return new_encode_dev(dev: sbi->sb->s_dev); | 
|---|
| 257 | } | 
|---|
| 258 |  | 
|---|
| 259 | static inline u64 autofs_get_ino(struct autofs_sb_info *sbi) | 
|---|
| 260 | { | 
|---|
| 261 | return d_inode(dentry: sbi->sb->s_root)->i_ino; | 
|---|
| 262 | } | 
|---|
| 263 |  | 
|---|
| 264 | static inline void __autofs_add_expiring(struct dentry *dentry) | 
|---|
| 265 | { | 
|---|
| 266 | struct autofs_sb_info *sbi = autofs_sbi(sb: dentry->d_sb); | 
|---|
| 267 | struct autofs_info *ino = autofs_dentry_ino(dentry); | 
|---|
| 268 |  | 
|---|
| 269 | if (ino) { | 
|---|
| 270 | if (list_empty(head: &ino->expiring)) | 
|---|
| 271 | list_add(new: &ino->expiring, head: &sbi->expiring_list); | 
|---|
| 272 | } | 
|---|
| 273 | } | 
|---|
| 274 |  | 
|---|
| 275 | static inline void autofs_add_expiring(struct dentry *dentry) | 
|---|
| 276 | { | 
|---|
| 277 | struct autofs_sb_info *sbi = autofs_sbi(sb: dentry->d_sb); | 
|---|
| 278 | struct autofs_info *ino = autofs_dentry_ino(dentry); | 
|---|
| 279 |  | 
|---|
| 280 | if (ino) { | 
|---|
| 281 | spin_lock(lock: &sbi->lookup_lock); | 
|---|
| 282 | if (list_empty(head: &ino->expiring)) | 
|---|
| 283 | list_add(new: &ino->expiring, head: &sbi->expiring_list); | 
|---|
| 284 | spin_unlock(lock: &sbi->lookup_lock); | 
|---|
| 285 | } | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | static inline void autofs_del_expiring(struct dentry *dentry) | 
|---|
| 289 | { | 
|---|
| 290 | struct autofs_sb_info *sbi = autofs_sbi(sb: dentry->d_sb); | 
|---|
| 291 | struct autofs_info *ino = autofs_dentry_ino(dentry); | 
|---|
| 292 |  | 
|---|
| 293 | if (ino) { | 
|---|
| 294 | spin_lock(lock: &sbi->lookup_lock); | 
|---|
| 295 | if (!list_empty(head: &ino->expiring)) | 
|---|
| 296 | list_del_init(entry: &ino->expiring); | 
|---|
| 297 | spin_unlock(lock: &sbi->lookup_lock); | 
|---|
| 298 | } | 
|---|
| 299 | } | 
|---|
| 300 |  | 
|---|
| 301 | void autofs_kill_sb(struct super_block *); | 
|---|
| 302 |  | 
|---|