vserver 1.9.3
[linux-2.6.git] / arch / sparc64 / solaris / misc.c
index 4a3db02..15b4cfe 100644 (file)
@@ -137,21 +137,34 @@ asmlinkage int solaris_brk(u32 brk)
        return sunos_brk(brk);
 }
 
-#define set_utsfield(to, from, dotchop, countfrom) {                   \
-       char *p;                                                        \
-       int i, len = (countfrom) ?                                      \
-               ((sizeof(to) > sizeof(from) ?                           \
-                       sizeof(from) : sizeof(to))) : sizeof(to);       \
-       if (copy_to_user(to, from, len))                                \
-               return -EFAULT;                                         \
-       if (dotchop)                                                    \
-               for (p=from,i=0; *p && *p != '.' && --len; p++,i++);    \
-       else                                                            \
-               i = len - 1;                                            \
-       if (__put_user('\0', (char __user *)((to)+i)))                  \
-               return -EFAULT;                                         \
+static int __set_utsfield(char __user *to, int to_size,
+                         const char *from, int from_size,
+                         int dotchop, int countfrom)
+{
+       int len = countfrom ? (to_size > from_size ?
+                              from_size : to_size) : to_size;
+       int off;
+
+       if (copy_to_user(to, from, len))
+               return -EFAULT;
+
+       off = len < to_size? len: len - 1;
+       if (dotchop) {
+               const char *p = strnchr(from, len, '.');
+               if (p) off = p - from;
+       }
+
+       if (__put_user('\0', to + off))
+               return -EFAULT;
+
+       return 0;
 }
 
+#define set_utsfield(to, from, dotchop, countfrom) \
+       __set_utsfield((to), sizeof(to), \
+                      (from), sizeof(from), \
+                      (dotchop), (countfrom))
+
 struct sol_uname {
        char sysname[9];
        char nodename[9];
@@ -219,17 +232,20 @@ static char *serial(char *buffer)
 asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
 {
        struct sol_uname __user *v = A(buf);
+       int err;
+
        switch (which) {
        case 0: /* old uname */
                /* Let's cheat */
-               set_utsfield(v->sysname, "SunOS", 1, 0);
+               err  = set_utsfield(v->sysname, "SunOS", 1, 0);
                down_read(&uts_sem);
-               set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+               err |= set_utsfield(v->nodename, system_utsname.nodename,
+                                   1, 1);
                up_read(&uts_sem);
-               set_utsfield(v->release, "2.6", 0, 0);
-               set_utsfield(v->version, "Generic", 0, 0);
-               set_utsfield(v->machine, machine(), 0, 0);
-               return 0;
+               err |= set_utsfield(v->release, "2.6", 0, 0);
+               err |= set_utsfield(v->version, "Generic", 0, 0);
+               err |= set_utsfield(v->machine, machine(), 0, 0);
+               return (err ? -EFAULT : 0);
        case 2: /* ustat */
                return -ENOSYS;
        case 3: /* fusers */
@@ -242,15 +258,18 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
 asmlinkage int solaris_utsname(u32 buf)
 {
        struct sol_utsname __user *v = A(buf);
+       int err;
+
        /* Why should we not lie a bit? */
        down_read(&uts_sem);
-       set_utsfield(v->sysname, "SunOS", 0, 0);
-       set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
-       set_utsfield(v->release, "5.6", 0, 0);
-       set_utsfield(v->version, "Generic", 0, 0);
-       set_utsfield(v->machine, machine(), 0, 0);
+       err  = set_utsfield(v->sysname, "SunOS", 0, 0);
+       err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
+       err |= set_utsfield(v->release, "5.6", 0, 0);
+       err |= set_utsfield(v->version, "Generic", 0, 0);
+       err |= set_utsfield(v->machine, machine(), 0, 0);
        up_read(&uts_sem);
-       return 0;
+
+       return (err ? -EFAULT : 0);
 }
 
 #define SI_SYSNAME             1       /* return name of operating system */