~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to modules/linux/vmblock/linux/control.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
253
253
 
254
254
/* procfs file operations */
255
255
 
 
256
 
 
257
/*
 
258
 *----------------------------------------------------------------------------
 
259
 *
 
260
 * ExecuteBlockOp --
 
261
 *
 
262
 *    Copy block name from user buffer into kernel space, canonicalize it
 
263
 *    by removing all trailing path separators, and execute desired block
 
264
 *    operation.
 
265
 *
 
266
 * Results:
 
267
 *    0 on success, negative error code on failure.
 
268
 *
 
269
 * Side effects:
 
270
 *    None.
 
271
 *
 
272
 *----------------------------------------------------------------------------
 
273
 */
 
274
 
 
275
static int
 
276
ExecuteBlockOp(const char __user *buf,                // IN: buffer with name
 
277
               const os_blocker_id_t blocker,         // IN: blocker ID (file)
 
278
               int (*blockOp)(const char *filename,   // IN: block operation
 
279
                              const os_blocker_id_t blocker))
 
280
{
 
281
   char *name;
 
282
   int i;
 
283
   int retval;
 
284
 
 
285
   name = getname(buf);
 
286
   if (IS_ERR(name)) {
 
287
      return PTR_ERR(name);
 
288
   }
 
289
 
 
290
   for (i = strlen(name) - 1; i >= 0 && name[i] == '/'; i--) {
 
291
      name[i] = '\0';
 
292
   }
 
293
 
 
294
   retval = i < 0 ? -EINVAL : blockOp(name, blocker);
 
295
 
 
296
   putname(name);
 
297
 
 
298
   return retval;
 
299
}
 
300
 
256
301
/*
257
302
 *----------------------------------------------------------------------------
258
303
 *
277
322
                   loff_t *ppos)            // IN/OUT: File offset (unused)
278
323
{
279
324
   int ret;
280
 
   ssize_t i;
281
 
   char *filename;
282
 
 
283
 
#ifdef VMX86_DEVEL
284
 
   if (cmd == VMBLOCK_LIST_FILEBLOCKS) {
285
 
      BlockListFileBlocks();
286
 
      return 0;
287
 
   }
288
 
#endif
289
 
 
290
 
   /*
291
 
    * XXX: Can we GPL our modules already?  This is gross.  On kernels 2.6.6
292
 
    * through 2.6.12 when CONFIG_AUDITSYSCALL is defined, putname() turns into
293
 
    * a macro that calls audit_putname(), which happens to only be exported to
294
 
    * GPL modules (until 2.6.9).  Here we work around this by calling
295
 
    * __getname() and __putname() to get our path buffer directly,
296
 
    * side-stepping the syscall auditing and doing the copy from user space
297
 
    * ourself.  Change this back once we GPL the module.
298
 
    */
299
 
   filename = __getname();
300
 
   if (!filename) {
301
 
      Warning("ControlFileOpWrite: Could not obtain memory for filename.\n");
302
 
      return -ENOMEM;
303
 
   }
304
 
 
305
 
   /*
306
 
    * XXX: __getname() returns a pointer to a PATH_MAX-sized buffer.
307
 
    * Hard-coding this size is also gross, but it's our only option here and
308
 
    * InodeOpLookup() already set a bad example by doing this.
309
 
    */
310
 
   ret = strncpy_from_user(filename, buf, PATH_MAX);
311
 
   if (ret < 0 || ret >= PATH_MAX) {
312
 
      Warning("ControlFileOpWrite: Could not access provided user buffer.\n");
313
 
      ret = ret < 0 ? ret : -ENAMETOOLONG;
314
 
      goto exit;
315
 
   }
316
 
 
317
 
   /* Remove all trailing path separators. */
318
 
   for (i = ret - 1; i >= 0 && filename[i] == '/'; i--) {
319
 
      filename[i] = '\0';
320
 
   }
321
 
 
322
 
   if (i < 0) {
323
 
      ret = -EINVAL;
324
 
      goto exit;
325
 
   }
326
325
 
327
326
   switch (cmd) {
328
327
   case VMBLOCK_ADD_FILEBLOCK:
329
 
      ret = BlockAddFileBlock(filename, file);
 
328
      ret = ExecuteBlockOp(buf, file, BlockAddFileBlock);
330
329
      break;
 
330
 
331
331
   case VMBLOCK_DEL_FILEBLOCK:
332
 
      ret = BlockRemoveFileBlock(filename, file);
333
 
      break;
 
332
      ret = ExecuteBlockOp(buf, file, BlockRemoveFileBlock);
 
333
      break;
 
334
 
 
335
#ifdef VMX86_DEVEL
 
336
   case VMBLOCK_LIST_FILEBLOCKS:
 
337
      BlockListFileBlocks();
 
338
      ret = 0;
 
339
      break;
 
340
#endif
 
341
 
334
342
   default:
335
343
      Warning("ControlFileOpWrite: unrecognized command (%u) recieved\n",
336
344
              (unsigned)cmd);
338
346
      break;
339
347
   }
340
348
 
341
 
exit:
342
 
   __putname(filename);
343
349
   return ret;
344
350
}
345
351