This file is indexed.

/usr/src/open-vm-tools-10.0.7/vmhgfs/link.c is in open-vm-tools-dkms 2:10.0.7-3227872-2ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/*********************************************************
 * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation version 2 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 *********************************************************/

/*
 * link.c --
 *
 * Symlink-specific inode operations for the filesystem portion of the
 * vmhgfs driver.
 */

/* Must come before any kernel header file. */
#include "driver-config.h"

#include "compat_fs.h"
#include "compat_namei.h"

#include "module.h"
#include "hgfsProto.h"
#include "fsutil.h"
#include "vm_assert.h"

/* HGFS symlink operations. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static const char *HgfsFollowlink(struct dentry *dentry,
                                  void **cookie);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
static void *HgfsFollowlink(struct dentry *dentry,
                            struct nameidata *nd);
#else
static int HgfsFollowlink(struct dentry *dentry,
                          struct nameidata *nd);
#endif
static int HgfsReadlink(struct dentry *dentry,
                        char __user *buffer,
                        int buflen);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static void HgfsPutlink(struct inode *unused,
                        void *cookie);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
static void HgfsPutlink(struct dentry *dentry,
                        struct nameidata *nd,
                        void *cookie);
#else
static void HgfsPutlink(struct dentry *dentry,
                        struct nameidata *nd);
#endif

/* HGFS inode operations structure for symlinks. */
struct inode_operations HgfsLinkInodeOperations = {
   .follow_link   = HgfsFollowlink,
   .readlink      = HgfsReadlink,
   .put_link      = HgfsPutlink,
};

/*
 * HGFS symlink operations.
 */

/*
 *----------------------------------------------------------------------
 *
 * HgfsFollowlink --
 *
 *    Modeled after nfs_follow_link from a 2.4 kernel so it'll work
 *    across all kernel revisions we care about.
 *
 * Results:
 *    Returns zero on success, negative error on failure.
 *
 *    On new kernels: The error is returned as void *.
 *    On older kernels: The error is returned as is.
 *
 * Side effects:
 *    None
 *
 *----------------------------------------------------------------------
 */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static const char *
HgfsFollowlink(struct dentry *dentry,
               void **cookie)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
static void *
HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link
               struct nameidata *nd)  // OUT: Contains target dentry
#else
static int
HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link
               struct nameidata *nd)  // OUT: Contains target dentry
#endif
{
   HgfsAttrInfo attr;
   char *fileName = NULL;
   int error;

   ASSERT(dentry);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
   ASSERT(nd);
#endif

   if (!dentry) {
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: null input\n"));
      error = -EINVAL;
      goto out;
   }

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling HgfsPrivateGetattr %s\n",
           __func__, dentry->d_name.name));
   error = HgfsPrivateGetattr(dentry, &attr, &fileName);
   LOG(6, (KERN_DEBUG "VMware hgfs: %s: HgfsPrivateGetattr %s ret %d\n",
           __func__, dentry->d_name.name, error));
   if (!error) {

      /* Let's make sure we got called on a symlink. */
      if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFollowlink: got called "
                 "on something that wasn't a symlink\n"));
         error = -EINVAL;
         kfree(fileName);
      } else {
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling nd_set_link %s\n",
                 __func__, fileName));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
         *cookie = fileName;
#else
         nd_set_link(nd, fileName);
#endif
      }
   }

out:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
   if (!error) {
      return *cookie;
   } else {
      return ERR_PTR(error);
   }
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
   return ERR_PTR(error);
#else
   return error;
#endif
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
#define HGFS_DO_READLINK(dentry,buffer,buflen,fileName) \
         readlink_copy(buffer, buflen, fileName)
#else
#define HGFS_DO_READLINK(dentry,buffer,buflen,fileName) \
         vfs_readlink(dentry, buffer, buflen, fileName)
#endif

/*
 *----------------------------------------------------------------------
 *
 * HgfsReadlink --
 *
 *    Modeled after nfs_read_link from a 2.4 kernel so it'll work
 *    across all kernel revisions we care about.
 *
 * Results:
 *    Returns zero on success, negative error on failure.
 *
 * Side effects:
 *    None
 *
 *----------------------------------------------------------------------
 */

static int
HgfsReadlink(struct dentry *dentry,  // IN:  Dentry containing link
             char __user *buffer,    // OUT: User buffer to copy link into
             int buflen)             // IN:  Length of user buffer

{
   HgfsAttrInfo attr;
   char *fileName = NULL;
   int error;

   ASSERT(dentry);
   ASSERT(buffer);

   if (!dentry) {
      LOG(4, (KERN_DEBUG "VMware hgfs: HgfsReadlink: null input\n"));
      return -EINVAL;
   }

   LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling HgfsPrivateGetattr %s\n",
           __func__, dentry->d_name.name));
   error = HgfsPrivateGetattr(dentry, &attr, &fileName);
   if (!error) {

      /* Let's make sure we got called on a symlink. */
      if (attr.type != HGFS_FILE_TYPE_SYMLINK || fileName == NULL) {
         LOG(6, (KERN_DEBUG "VMware hgfs: HgfsReadlink: got called "
                 "on something that wasn't a symlink\n"));
         error = -EINVAL;
      } else {
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling vfs_readlink %s\n",
                 __func__, fileName));
         error = HGFS_DO_READLINK(dentry, buffer, buflen, fileName);
         LOG(6, (KERN_DEBUG "VMware hgfs: %s: vfs_readlink %s ret %dn",
                 __func__, fileName, error));
      }
      kfree(fileName);
   }
   return error;
}


/*
 *----------------------------------------------------------------------
 *
 * HgfsPutlink --
 *
 *    Modeled after page_put_link from a 2.6.9 kernel so it'll work
 *    across all kernel revisions we care about.
 *
 * Results:
 *    None
 *
 * Side effects:
 *    None
 *
 *----------------------------------------------------------------------
 */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
static void
HgfsPutlink(struct inode *unused,
            void *cookie)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
static void
HgfsPutlink(struct dentry *dentry, // dentry
            struct nameidata *nd,  // lookup name information
            void *cookie)          // cookie
#else
static void
HgfsPutlink(struct dentry *dentry, // dentry
            struct nameidata *nd)  // lookup name information
#endif
{
   char *fileName = NULL;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
   fileName = cookie;
   LOG(6, (KERN_DEBUG "VMware hgfs: %s: put for %s\n",
           __func__, fileName));
#else
   LOG(6, (KERN_DEBUG "VMware hgfs: %s: put for %s\n",
           __func__, dentry->d_name.name));
   fileName = nd_get_link(nd);
#endif
   if (!IS_ERR(fileName)) {
      LOG(6, (KERN_DEBUG "VMware hgfs: %s: putting %s\n",
              __func__, fileName));
      kfree(fileName);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
      nd_set_link(nd, NULL);
#endif
   }
}