linux/arch/frv/kernel/uaccess.c
<<
>>
Prefs
   1/* uaccess.c: userspace access functions
   2 *
   3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/mm.h>
  13#include <linux/module.h>
  14#include <asm/uaccess.h>
  15
  16/*****************************************************************************/
  17/*
  18 * copy a null terminated string from userspace
  19 */
  20long strncpy_from_user(char *dst, const char __user *src, long count)
  21{
  22        unsigned long max;
  23        char *p, ch;
  24        long err = -EFAULT;
  25
  26        BUG_ON(count < 0);
  27
  28        p = dst;
  29
  30#ifndef CONFIG_MMU
  31        if ((unsigned long) src < memory_start)
  32                goto error;
  33#endif
  34
  35        if ((unsigned long) src >= get_addr_limit())
  36                goto error;
  37
  38        max = get_addr_limit() - (unsigned long) src;
  39        if ((unsigned long) count > max) {
  40                memset(dst + max, 0, count - max);
  41                count = max;
  42        }
  43
  44        err = 0;
  45        for (; count > 0; count--, p++, src++) {
  46                __get_user_asm(err, ch, src, "ub", "=r");
  47                if (err < 0)
  48                        goto error;
  49                if (!ch)
  50                        break;
  51                *p = ch;
  52        }
  53
  54        err = p - dst; /* return length excluding NUL */
  55
  56 error:
  57        if (count > 0)
  58                memset(p, 0, count); /* clear remainder of buffer [security] */
  59
  60        return err;
  61
  62} /* end strncpy_from_user() */
  63
  64EXPORT_SYMBOL(strncpy_from_user);
  65
  66/*****************************************************************************/
  67/*
  68 * Return the size of a string (including the ending 0)
  69 *
  70 * Return 0 on exception, a value greater than N if too long
  71 */
  72long strnlen_user(const char __user *src, long count)
  73{
  74        const char __user *p;
  75        long err = 0;
  76        char ch;
  77
  78        BUG_ON(count < 0);
  79
  80#ifndef CONFIG_MMU
  81        if ((unsigned long) src < memory_start)
  82                return 0;
  83#endif
  84
  85        if ((unsigned long) src >= get_addr_limit())
  86                return 0;
  87
  88        for (p = src; count > 0; count--, p++) {
  89                __get_user_asm(err, ch, p, "ub", "=r");
  90                if (err < 0)
  91                        return 0;
  92                if (!ch)
  93                        break;
  94        }
  95
  96        return p - src + 1; /* return length including NUL */
  97
  98} /* end strnlen_user() */
  99
 100EXPORT_SYMBOL(strnlen_user);
 101