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        if (count < 0)
  27                BUG();
  28
  29        p = dst;
  30
  31#ifndef CONFIG_MMU
  32        if ((unsigned long) src < memory_start)
  33                goto error;
  34#endif
  35
  36        if ((unsigned long) src >= get_addr_limit())
  37                goto error;
  38
  39        max = get_addr_limit() - (unsigned long) src;
  40        if ((unsigned long) count > max) {
  41                memset(dst + max, 0, count - max);
  42                count = max;
  43        }
  44
  45        err = 0;
  46        for (; count > 0; count--, p++, src++) {
  47                __get_user_asm(err, ch, src, "ub", "=r");
  48                if (err < 0)
  49                        goto error;
  50                if (!ch)
  51                        break;
  52                *p = ch;
  53        }
  54
  55        err = p - dst; /* return length excluding NUL */
  56
  57 error:
  58        if (count > 0)
  59                memset(p, 0, count); /* clear remainder of buffer [security] */
  60
  61        return err;
  62
  63} /* end strncpy_from_user() */
  64
  65EXPORT_SYMBOL(strncpy_from_user);
  66
  67/*****************************************************************************/
  68/*
  69 * Return the size of a string (including the ending 0)
  70 *
  71 * Return 0 on exception, a value greater than N if too long
  72 */
  73long strnlen_user(const char __user *src, long count)
  74{
  75        const char __user *p;
  76        long err = 0;
  77        char ch;
  78
  79        if (count < 0)
  80                BUG();
  81
  82#ifndef CONFIG_MMU
  83        if ((unsigned long) src < memory_start)
  84                return 0;
  85#endif
  86
  87        if ((unsigned long) src >= get_addr_limit())
  88                return 0;
  89
  90        for (p = src; count > 0; count--, p++) {
  91                __get_user_asm(err, ch, p, "ub", "=r");
  92                if (err < 0)
  93                        return 0;
  94                if (!ch)
  95                        break;
  96        }
  97
  98        return p - src + 1; /* return length including NUL */
  99
 100} /* end strnlen_user() */
 101
 102EXPORT_SYMBOL(strnlen_user);
 103