root/fs/d_path.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. prepend
  2. prepend_name
  3. prepend_path
  4. __d_path
  5. d_absolute_path
  6. path_with_deleted
  7. prepend_unreachable
  8. get_fs_root_rcu
  9. d_path
  10. dynamic_dname
  11. simple_dname
  12. __dentry_path
  13. dentry_path_raw
  14. dentry_path
  15. get_fs_root_and_pwd_rcu
  16. SYSCALL_DEFINE2

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #include <linux/syscalls.h>
   3 #include <linux/export.h>
   4 #include <linux/uaccess.h>
   5 #include <linux/fs_struct.h>
   6 #include <linux/fs.h>
   7 #include <linux/slab.h>
   8 #include <linux/prefetch.h>
   9 #include "mount.h"
  10 
  11 static int prepend(char **buffer, int *buflen, const char *str, int namelen)
  12 {
  13         *buflen -= namelen;
  14         if (*buflen < 0)
  15                 return -ENAMETOOLONG;
  16         *buffer -= namelen;
  17         memcpy(*buffer, str, namelen);
  18         return 0;
  19 }
  20 
  21 /**
  22  * prepend_name - prepend a pathname in front of current buffer pointer
  23  * @buffer: buffer pointer
  24  * @buflen: allocated length of the buffer
  25  * @name:   name string and length qstr structure
  26  *
  27  * With RCU path tracing, it may race with d_move(). Use READ_ONCE() to
  28  * make sure that either the old or the new name pointer and length are
  29  * fetched. However, there may be mismatch between length and pointer.
  30  * The length cannot be trusted, we need to copy it byte-by-byte until
  31  * the length is reached or a null byte is found. It also prepends "/" at
  32  * the beginning of the name. The sequence number check at the caller will
  33  * retry it again when a d_move() does happen. So any garbage in the buffer
  34  * due to mismatched pointer and length will be discarded.
  35  *
  36  * Load acquire is needed to make sure that we see that terminating NUL.
  37  */
  38 static int prepend_name(char **buffer, int *buflen, const struct qstr *name)
  39 {
  40         const char *dname = smp_load_acquire(&name->name); /* ^^^ */
  41         u32 dlen = READ_ONCE(name->len);
  42         char *p;
  43 
  44         *buflen -= dlen + 1;
  45         if (*buflen < 0)
  46                 return -ENAMETOOLONG;
  47         p = *buffer -= dlen + 1;
  48         *p++ = '/';
  49         while (dlen--) {
  50                 char c = *dname++;
  51                 if (!c)
  52                         break;
  53                 *p++ = c;
  54         }
  55         return 0;
  56 }
  57 
  58 /**
  59  * prepend_path - Prepend path string to a buffer
  60  * @path: the dentry/vfsmount to report
  61  * @root: root vfsmnt/dentry
  62  * @buffer: pointer to the end of the buffer
  63  * @buflen: pointer to buffer length
  64  *
  65  * The function will first try to write out the pathname without taking any
  66  * lock other than the RCU read lock to make sure that dentries won't go away.
  67  * It only checks the sequence number of the global rename_lock as any change
  68  * in the dentry's d_seq will be preceded by changes in the rename_lock
  69  * sequence number. If the sequence number had been changed, it will restart
  70  * the whole pathname back-tracing sequence again by taking the rename_lock.
  71  * In this case, there is no need to take the RCU read lock as the recursive
  72  * parent pointer references will keep the dentry chain alive as long as no
  73  * rename operation is performed.
  74  */
  75 static int prepend_path(const struct path *path,
  76                         const struct path *root,
  77                         char **buffer, int *buflen)
  78 {
  79         struct dentry *dentry;
  80         struct vfsmount *vfsmnt;
  81         struct mount *mnt;
  82         int error = 0;
  83         unsigned seq, m_seq = 0;
  84         char *bptr;
  85         int blen;
  86 
  87         rcu_read_lock();
  88 restart_mnt:
  89         read_seqbegin_or_lock(&mount_lock, &m_seq);
  90         seq = 0;
  91         rcu_read_lock();
  92 restart:
  93         bptr = *buffer;
  94         blen = *buflen;
  95         error = 0;
  96         dentry = path->dentry;
  97         vfsmnt = path->mnt;
  98         mnt = real_mount(vfsmnt);
  99         read_seqbegin_or_lock(&rename_lock, &seq);
 100         while (dentry != root->dentry || vfsmnt != root->mnt) {
 101                 struct dentry * parent;
 102 
 103                 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
 104                         struct mount *parent = READ_ONCE(mnt->mnt_parent);
 105                         /* Escaped? */
 106                         if (dentry != vfsmnt->mnt_root) {
 107                                 bptr = *buffer;
 108                                 blen = *buflen;
 109                                 error = 3;
 110                                 break;
 111                         }
 112                         /* Global root? */
 113                         if (mnt != parent) {
 114                                 dentry = READ_ONCE(mnt->mnt_mountpoint);
 115                                 mnt = parent;
 116                                 vfsmnt = &mnt->mnt;
 117                                 continue;
 118                         }
 119                         if (is_mounted(vfsmnt) && !is_anon_ns(mnt->mnt_ns))
 120                                 error = 1;      // absolute root
 121                         else
 122                                 error = 2;      // detached or not attached yet
 123                         break;
 124                 }
 125                 parent = dentry->d_parent;
 126                 prefetch(parent);
 127                 error = prepend_name(&bptr, &blen, &dentry->d_name);
 128                 if (error)
 129                         break;
 130 
 131                 dentry = parent;
 132         }
 133         if (!(seq & 1))
 134                 rcu_read_unlock();
 135         if (need_seqretry(&rename_lock, seq)) {
 136                 seq = 1;
 137                 goto restart;
 138         }
 139         done_seqretry(&rename_lock, seq);
 140 
 141         if (!(m_seq & 1))
 142                 rcu_read_unlock();
 143         if (need_seqretry(&mount_lock, m_seq)) {
 144                 m_seq = 1;
 145                 goto restart_mnt;
 146         }
 147         done_seqretry(&mount_lock, m_seq);
 148 
 149         if (error >= 0 && bptr == *buffer) {
 150                 if (--blen < 0)
 151                         error = -ENAMETOOLONG;
 152                 else
 153                         *--bptr = '/';
 154         }
 155         *buffer = bptr;
 156         *buflen = blen;
 157         return error;
 158 }
 159 
 160 /**
 161  * __d_path - return the path of a dentry
 162  * @path: the dentry/vfsmount to report
 163  * @root: root vfsmnt/dentry
 164  * @buf: buffer to return value in
 165  * @buflen: buffer length
 166  *
 167  * Convert a dentry into an ASCII path name.
 168  *
 169  * Returns a pointer into the buffer or an error code if the
 170  * path was too long.
 171  *
 172  * "buflen" should be positive.
 173  *
 174  * If the path is not reachable from the supplied root, return %NULL.
 175  */
 176 char *__d_path(const struct path *path,
 177                const struct path *root,
 178                char *buf, int buflen)
 179 {
 180         char *res = buf + buflen;
 181         int error;
 182 
 183         prepend(&res, &buflen, "\0", 1);
 184         error = prepend_path(path, root, &res, &buflen);
 185 
 186         if (error < 0)
 187                 return ERR_PTR(error);
 188         if (error > 0)
 189                 return NULL;
 190         return res;
 191 }
 192 
 193 char *d_absolute_path(const struct path *path,
 194                char *buf, int buflen)
 195 {
 196         struct path root = {};
 197         char *res = buf + buflen;
 198         int error;
 199 
 200         prepend(&res, &buflen, "\0", 1);
 201         error = prepend_path(path, &root, &res, &buflen);
 202 
 203         if (error > 1)
 204                 error = -EINVAL;
 205         if (error < 0)
 206                 return ERR_PTR(error);
 207         return res;
 208 }
 209 
 210 /*
 211  * same as __d_path but appends "(deleted)" for unlinked files.
 212  */
 213 static int path_with_deleted(const struct path *path,
 214                              const struct path *root,
 215                              char **buf, int *buflen)
 216 {
 217         prepend(buf, buflen, "\0", 1);
 218         if (d_unlinked(path->dentry)) {
 219                 int error = prepend(buf, buflen, " (deleted)", 10);
 220                 if (error)
 221                         return error;
 222         }
 223 
 224         return prepend_path(path, root, buf, buflen);
 225 }
 226 
 227 static int prepend_unreachable(char **buffer, int *buflen)
 228 {
 229         return prepend(buffer, buflen, "(unreachable)", 13);
 230 }
 231 
 232 static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
 233 {
 234         unsigned seq;
 235 
 236         do {
 237                 seq = read_seqcount_begin(&fs->seq);
 238                 *root = fs->root;
 239         } while (read_seqcount_retry(&fs->seq, seq));
 240 }
 241 
 242 /**
 243  * d_path - return the path of a dentry
 244  * @path: path to report
 245  * @buf: buffer to return value in
 246  * @buflen: buffer length
 247  *
 248  * Convert a dentry into an ASCII path name. If the entry has been deleted
 249  * the string " (deleted)" is appended. Note that this is ambiguous.
 250  *
 251  * Returns a pointer into the buffer or an error code if the path was
 252  * too long. Note: Callers should use the returned pointer, not the passed
 253  * in buffer, to use the name! The implementation often starts at an offset
 254  * into the buffer, and may leave 0 bytes at the start.
 255  *
 256  * "buflen" should be positive.
 257  */
 258 char *d_path(const struct path *path, char *buf, int buflen)
 259 {
 260         char *res = buf + buflen;
 261         struct path root;
 262         int error;
 263 
 264         /*
 265          * We have various synthetic filesystems that never get mounted.  On
 266          * these filesystems dentries are never used for lookup purposes, and
 267          * thus don't need to be hashed.  They also don't need a name until a
 268          * user wants to identify the object in /proc/pid/fd/.  The little hack
 269          * below allows us to generate a name for these objects on demand:
 270          *
 271          * Some pseudo inodes are mountable.  When they are mounted
 272          * path->dentry == path->mnt->mnt_root.  In that case don't call d_dname
 273          * and instead have d_path return the mounted path.
 274          */
 275         if (path->dentry->d_op && path->dentry->d_op->d_dname &&
 276             (!IS_ROOT(path->dentry) || path->dentry != path->mnt->mnt_root))
 277                 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 278 
 279         rcu_read_lock();
 280         get_fs_root_rcu(current->fs, &root);
 281         error = path_with_deleted(path, &root, &res, &buflen);
 282         rcu_read_unlock();
 283 
 284         if (error < 0)
 285                 res = ERR_PTR(error);
 286         return res;
 287 }
 288 EXPORT_SYMBOL(d_path);
 289 
 290 /*
 291  * Helper function for dentry_operations.d_dname() members
 292  */
 293 char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
 294                         const char *fmt, ...)
 295 {
 296         va_list args;
 297         char temp[64];
 298         int sz;
 299 
 300         va_start(args, fmt);
 301         sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1;
 302         va_end(args);
 303 
 304         if (sz > sizeof(temp) || sz > buflen)
 305                 return ERR_PTR(-ENAMETOOLONG);
 306 
 307         buffer += buflen - sz;
 308         return memcpy(buffer, temp, sz);
 309 }
 310 
 311 char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
 312 {
 313         char *end = buffer + buflen;
 314         /* these dentries are never renamed, so d_lock is not needed */
 315         if (prepend(&end, &buflen, " (deleted)", 11) ||
 316             prepend(&end, &buflen, dentry->d_name.name, dentry->d_name.len) ||
 317             prepend(&end, &buflen, "/", 1))  
 318                 end = ERR_PTR(-ENAMETOOLONG);
 319         return end;
 320 }
 321 
 322 /*
 323  * Write full pathname from the root of the filesystem into the buffer.
 324  */
 325 static char *__dentry_path(struct dentry *d, char *buf, int buflen)
 326 {
 327         struct dentry *dentry;
 328         char *end, *retval;
 329         int len, seq = 0;
 330         int error = 0;
 331 
 332         if (buflen < 2)
 333                 goto Elong;
 334 
 335         rcu_read_lock();
 336 restart:
 337         dentry = d;
 338         end = buf + buflen;
 339         len = buflen;
 340         prepend(&end, &len, "\0", 1);
 341         /* Get '/' right */
 342         retval = end-1;
 343         *retval = '/';
 344         read_seqbegin_or_lock(&rename_lock, &seq);
 345         while (!IS_ROOT(dentry)) {
 346                 struct dentry *parent = dentry->d_parent;
 347 
 348                 prefetch(parent);
 349                 error = prepend_name(&end, &len, &dentry->d_name);
 350                 if (error)
 351                         break;
 352 
 353                 retval = end;
 354                 dentry = parent;
 355         }
 356         if (!(seq & 1))
 357                 rcu_read_unlock();
 358         if (need_seqretry(&rename_lock, seq)) {
 359                 seq = 1;
 360                 goto restart;
 361         }
 362         done_seqretry(&rename_lock, seq);
 363         if (error)
 364                 goto Elong;
 365         return retval;
 366 Elong:
 367         return ERR_PTR(-ENAMETOOLONG);
 368 }
 369 
 370 char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen)
 371 {
 372         return __dentry_path(dentry, buf, buflen);
 373 }
 374 EXPORT_SYMBOL(dentry_path_raw);
 375 
 376 char *dentry_path(struct dentry *dentry, char *buf, int buflen)
 377 {
 378         char *p = NULL;
 379         char *retval;
 380 
 381         if (d_unlinked(dentry)) {
 382                 p = buf + buflen;
 383                 if (prepend(&p, &buflen, "//deleted", 10) != 0)
 384                         goto Elong;
 385                 buflen++;
 386         }
 387         retval = __dentry_path(dentry, buf, buflen);
 388         if (!IS_ERR(retval) && p)
 389                 *p = '/';       /* restore '/' overriden with '\0' */
 390         return retval;
 391 Elong:
 392         return ERR_PTR(-ENAMETOOLONG);
 393 }
 394 
 395 static void get_fs_root_and_pwd_rcu(struct fs_struct *fs, struct path *root,
 396                                     struct path *pwd)
 397 {
 398         unsigned seq;
 399 
 400         do {
 401                 seq = read_seqcount_begin(&fs->seq);
 402                 *root = fs->root;
 403                 *pwd = fs->pwd;
 404         } while (read_seqcount_retry(&fs->seq, seq));
 405 }
 406 
 407 /*
 408  * NOTE! The user-level library version returns a
 409  * character pointer. The kernel system call just
 410  * returns the length of the buffer filled (which
 411  * includes the ending '\0' character), or a negative
 412  * error value. So libc would do something like
 413  *
 414  *      char *getcwd(char * buf, size_t size)
 415  *      {
 416  *              int retval;
 417  *
 418  *              retval = sys_getcwd(buf, size);
 419  *              if (retval >= 0)
 420  *                      return buf;
 421  *              errno = -retval;
 422  *              return NULL;
 423  *      }
 424  */
 425 SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
 426 {
 427         int error;
 428         struct path pwd, root;
 429         char *page = __getname();
 430 
 431         if (!page)
 432                 return -ENOMEM;
 433 
 434         rcu_read_lock();
 435         get_fs_root_and_pwd_rcu(current->fs, &root, &pwd);
 436 
 437         error = -ENOENT;
 438         if (!d_unlinked(pwd.dentry)) {
 439                 unsigned long len;
 440                 char *cwd = page + PATH_MAX;
 441                 int buflen = PATH_MAX;
 442 
 443                 prepend(&cwd, &buflen, "\0", 1);
 444                 error = prepend_path(&pwd, &root, &cwd, &buflen);
 445                 rcu_read_unlock();
 446 
 447                 if (error < 0)
 448                         goto out;
 449 
 450                 /* Unreachable from current root */
 451                 if (error > 0) {
 452                         error = prepend_unreachable(&cwd, &buflen);
 453                         if (error)
 454                                 goto out;
 455                 }
 456 
 457                 error = -ERANGE;
 458                 len = PATH_MAX + page - cwd;
 459                 if (len <= size) {
 460                         error = len;
 461                         if (copy_to_user(buf, cwd, len))
 462                                 error = -EFAULT;
 463                 }
 464         } else {
 465                 rcu_read_unlock();
 466         }
 467 
 468 out:
 469         __putname(page);
 470         return error;
 471 }

/* [<][>][^][v][top][bottom][index][help] */