Skip to content

Commit

Permalink
Revert r360944 and r360946 until reported issues can be resolved
Browse files Browse the repository at this point in the history
Reported by:	cy
  • Loading branch information
cemeyer committed May 12, 2020
1 parent 43f12c5 commit 051fc58
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 75 deletions.
37 changes: 37 additions & 0 deletions sys/amd64/amd64/support.S
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,43 @@ copyinstr_toolong:
movl $ENAMETOOLONG,%eax
jmp cpystrflt_x

/*
* copystr(from, to, maxlen, int *lencopied)
* %rdi, %rsi, %rdx, %rcx
*/
ENTRY(copystr)
PUSH_FRAME_POINTER
movq %rdx,%r8 /* %r8 = maxlen */

incq %rdx
1:
decq %rdx
jz 4f
movb (%rdi),%al
movb %al,(%rsi)
incq %rsi
incq %rdi
testb %al,%al
jnz 1b

/* Success -- 0 byte reached */
decq %rdx
xorl %eax,%eax
2:
testq %rcx,%rcx
jz 3f
/* set *lencopied and return %rax */
subq %rdx,%r8
movq %r8,(%rcx)
3:
POP_FRAME_POINTER
ret
4:
/* rdx is zero -- return ENAMETOOLONG */
movl $ENAMETOOLONG,%eax
jmp 2b
END(copystr)

/*
* Handling of special amd64 registers and descriptor tables etc
*/
Expand Down
33 changes: 33 additions & 0 deletions sys/arm/arm/copystr.S
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,39 @@ __FBSDID("$FreeBSD$");
ldr tmp, .Lpcb
#endif

/*
* r0 - from
* r1 - to
* r2 - maxlens
* r3 - lencopied
*
* Copy string from r0 to r1
*/
ENTRY(copystr)
stmfd sp!, {r4-r5} /* stack is 8 byte aligned */
teq r2, #0x00000000
mov r5, #0x00000000
moveq r0, #ENAMETOOLONG
beq 2f

1: ldrb r4, [r0], #0x0001
add r5, r5, #0x00000001
teq r4, #0x00000000
strb r4, [r1], #0x0001
teqne r5, r2
bne 1b

teq r4, #0x00000000
moveq r0, #0x00000000
movne r0, #ENAMETOOLONG

2: teq r3, #0x00000000
strne r5, [r3]

ldmfd sp!, {r4-r5} /* stack is 8 byte aligned */
RET
END(copystr)

#define SAVE_REGS stmfd sp!, {r4-r6}
#define RESTORE_REGS ldmfd sp!, {r4-r6}

Expand Down
61 changes: 61 additions & 0 deletions sys/arm64/arm64/copystr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*-
* Copyright (c) 2014 Andrew Turner
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/systm.h>

int
(copystr)(const void * __restrict kfaddr, void * __restrict kdaddr, size_t len,
size_t * __restrict lencopied)
{
const char *src;
size_t pos;
char *dst;
int error;

error = ENAMETOOLONG;
src = kfaddr;
dst = kdaddr;
for (pos = 0; pos < len; pos++) {
dst[pos] = src[pos];
if (src[pos] == '\0') {
/* Increment pos to hold the number of bytes copied */
pos++;
error = 0;
break;
}
}

if (lencopied != NULL)
*lencopied = pos;

return (error);
}

1 change: 1 addition & 0 deletions sys/conf/files.arm64
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ arm64/arm64/busdma_machdep.c standard
arm64/arm64/bzero.S standard
arm64/arm64/clock.c standard
arm64/arm64/copyinout.S standard
arm64/arm64/copystr.c standard
arm64/arm64/cpu_errata.c standard
arm64/arm64/cpufunc_asm.S standard
arm64/arm64/db_disasm.c optional ddb
Expand Down
1 change: 1 addition & 0 deletions sys/conf/files.powerpc
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ powerpc/powerpc/bus_machdep.c standard
powerpc/powerpc/busdma_machdep.c standard
powerpc/powerpc/clock.c standard
powerpc/powerpc/copyinout.c standard
powerpc/powerpc/copystr.c standard
powerpc/powerpc/cpu.c standard
powerpc/powerpc/cpu_subr64.S optional powerpc64
powerpc/powerpc/db_disasm.c optional ddb
Expand Down
1 change: 1 addition & 0 deletions sys/conf/files.riscv
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ riscv/riscv/busdma_bounce.c standard
riscv/riscv/busdma_machdep.c standard
riscv/riscv/clock.c standard
riscv/riscv/copyinout.S standard
riscv/riscv/copystr.c standard
riscv/riscv/cpufunc_asm.S standard
riscv/riscv/db_disasm.c optional ddb
riscv/riscv/db_interface.c optional ddb
Expand Down
6 changes: 4 additions & 2 deletions sys/fs/fuse/fuse_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ fuse_vfsop_mount(struct mount *mp)
int daemon_timeout;
int fd;

size_t len;

struct cdev *fdev;
struct fuse_data *data = NULL;
struct thread *td;
Expand Down Expand Up @@ -430,8 +432,8 @@ fuse_vfsop_mount(struct mount *mp)
strlcat(mp->mnt_stat.f_fstypename, ".", MFSNAMELEN);
strlcat(mp->mnt_stat.f_fstypename, subtype, MFSNAMELEN);
}
memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &len);
bzero(mp->mnt_stat.f_mntfromname + len, MNAMELEN - len);
mp->mnt_iosize_max = MAXPHYS;

/* Now handshaking with daemon */
Expand Down
9 changes: 7 additions & 2 deletions sys/fs/unionfs/union_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ unionfs_domount(struct mount *mp)
char *tmp;
char *ep;
int len;
size_t done;
int below;
uid_t uid;
gid_t gid;
Expand Down Expand Up @@ -303,8 +304,12 @@ unionfs_domount(struct mount *mp)
*/
vfs_getnewfsid(mp);

snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN, "<%s>:%s",
below ? "below" : "above", target);
len = MNAMELEN - 1;
tmp = mp->mnt_stat.f_mntfromname;
copystr((below ? "<below>:" : "<above>:"), tmp, len, &done);
len -= done - 1;
tmp += done - 1;
copystr(target, tmp, len, NULL);

UNIONFSDEBUG("unionfs_mount: from %s, on %s\n",
mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
Expand Down
41 changes: 41 additions & 0 deletions sys/i386/i386/support.s
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,47 @@ ENTRY(memcpy)
ret
END(memcpy)

/*
* copystr(from, to, maxlen, int *lencopied) - MP SAFE
*/
ENTRY(copystr)
pushl %esi
pushl %edi

movl 12(%esp),%esi /* %esi = from */
movl 16(%esp),%edi /* %edi = to */
movl 20(%esp),%edx /* %edx = maxlen */
incl %edx
1:
decl %edx
jz 4f
lodsb
stosb
orb %al,%al
jnz 1b

/* Success -- 0 byte reached */
decl %edx
xorl %eax,%eax
jmp 6f
4:
/* edx is zero -- return ENAMETOOLONG */
movl $ENAMETOOLONG,%eax

6:
/* set *lencopied and return %eax */
movl 20(%esp),%ecx
subl %edx,%ecx
movl 24(%esp),%edx
testl %edx,%edx
jz 7f
movl %ecx,(%edx)
7:
popl %edi
popl %esi
ret
END(copystr)

ENTRY(bcmp)
pushl %edi
pushl %esi
Expand Down
8 changes: 8 additions & 0 deletions sys/kern/subr_csan.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,20 @@ kcsan_strlen(const char *str)
return (s - str);
}

#undef copystr
#undef copyin
#undef copyin_nofault
#undef copyinstr
#undef copyout
#undef copyout_nofault

int
kcsan_copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done)
{
kcsan_access((uintptr_t)kdaddr, len, true, false, __RET_ADDR);
return copystr(kfaddr, kdaddr, len, done);
}

int
kcsan_copyin(const void *uaddr, void *kaddr, size_t len)
{
Expand Down
55 changes: 34 additions & 21 deletions sys/mips/mips/support.S
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,12 @@
.text

/*
* Copy a null terminated string from the user address space into
* the kernel address space.
*
* copyinstr(fromaddr, toaddr, maxlength, &lencopied)
* caddr_t fromaddr;
* caddr_t toaddr;
* u_int maxlength;
* u_int *lencopied;
* int copystr(void *kfaddr, void *kdaddr, size_t maxlen, size_t *lencopied)
* Copy a NIL-terminated string, at most maxlen characters long. Return the
* number of characters copied (including the NIL) in *lencopied. If the
* string is too long, return ENAMETOOLONG; else return 0.
*/
LEAF(copyinstr)
PTR_LA v0, __copyinstr_err
blt a0, zero, __copyinstr_err # make sure address is in user space
GET_CPU_PCPU(v1)
PTR_L v1, PC_CURPCB(v1)
PTR_S v0, U_PCB_ONFAULT(v1)

LEAF(copystr)
move t0, a2
beq a2, zero, 4f
1:
Expand All @@ -138,14 +128,37 @@ LEAF(copyinstr)
PTR_SUBU a2, t0, a2 # if the 4th arg was non-NULL
PTR_S a2, 0(a3)
3:

PTR_S zero, U_PCB_ONFAULT(v1)
j ra
j ra # v0 is 0 or ENAMETOOLONG
nop
END(copystr)


__copyinstr_err:
j ra
li v0, EFAULT
/*
* Copy a null terminated string from the user address space into
* the kernel address space.
*
* copyinstr(fromaddr, toaddr, maxlength, &lencopied)
* caddr_t fromaddr;
* caddr_t toaddr;
* u_int maxlength;
* u_int *lencopied;
*/
NESTED(copyinstr, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
PTR_LA v0, copyerr
blt a0, zero, _C_LABEL(copyerr) # make sure address is in user space
REG_S ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
PTR_L v1, PC_CURPCB(v1)
jal _C_LABEL(copystr)
PTR_S v0, U_PCB_ONFAULT(v1)
REG_L ra, CALLFRAME_RA(sp)
GET_CPU_PCPU(v1)
PTR_L v1, PC_CURPCB(v1)
PTR_S zero, U_PCB_ONFAULT(v1)
j ra
PTR_ADDU sp, sp, CALLFRAME_SIZ
END(copyinstr)

/*
Expand Down
Loading

0 comments on commit 051fc58

Please sign in to comment.