mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-21 07:15:49 +00:00
copystr(9): Move to deprecate (attempt #2)
This reapplies logical r360944 and r360946 (reverting r360955), with fixed copystr() stand-in replacement macro. Eventually the goal is to convert consumers and kill the macro, but for a first step it helps if the macro is correct. Prior commit message: Unlike the other copy*() functions, it does not serve to copy from one address space to another or protect against potential faults. It's just an older incarnation of the now-more-common strlcpy(). Add a coccinelle script to tools/ which can be used to mechanically convert existing instances where replacement with strlcpy is trivial. In the two cases which matched, fuse_vfsops.c and union_vfsops.c, the code was further refactored manually to simplify. Replace the declaration of copystr() in systm.h with a small macro wrapper around strlcpy (with correction from brooks@ -- thanks). Remove N redundant MI implementations of copystr. For MIPS, this entailed inlining the assembler copystr into the only consumer, copyinstr, and making the latter a leaf function. Reviewed by: jhb (earlier version) Discussed with: brooks (thanks!) Differential Revision: https://reviews.freebsd.org/D24672
This commit is contained in:
parent
9085d7d6b8
commit
852c303b61
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=361466
@ -1416,43 +1416,6 @@ 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
|
||||
*/
|
||||
|
@ -60,39 +60,6 @@ __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}
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
||||
|
@ -134,7 +134,6 @@ 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
|
||||
|
@ -241,7 +241,6 @@ 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
|
||||
|
@ -37,7 +37,6 @@ 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
|
||||
|
@ -303,8 +303,6 @@ 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;
|
||||
@ -437,8 +435,8 @@ fuse_vfsop_mount(struct mount *mp)
|
||||
strlcat(mp->mnt_stat.f_fstypename, ".", MFSNAMELEN);
|
||||
strlcat(mp->mnt_stat.f_fstypename, subtype, MFSNAMELEN);
|
||||
}
|
||||
copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &len);
|
||||
bzero(mp->mnt_stat.f_mntfromname + len, MNAMELEN - len);
|
||||
memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
|
||||
strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
|
||||
mp->mnt_iosize_max = MAXPHYS;
|
||||
|
||||
/* Now handshaking with daemon */
|
||||
|
@ -83,7 +83,6 @@ unionfs_domount(struct mount *mp)
|
||||
char *tmp;
|
||||
char *ep;
|
||||
int len;
|
||||
size_t done;
|
||||
int below;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
@ -304,12 +303,8 @@ unionfs_domount(struct mount *mp)
|
||||
*/
|
||||
vfs_getnewfsid(mp);
|
||||
|
||||
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);
|
||||
snprintf(mp->mnt_stat.f_mntfromname, MNAMELEN, "<%s>:%s",
|
||||
below ? "below" : "above", target);
|
||||
|
||||
UNIONFSDEBUG("unionfs_mount: from %s, on %s\n",
|
||||
mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
|
||||
|
@ -233,47 +233,6 @@ 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
|
||||
|
@ -350,20 +350,12 @@ 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)
|
||||
{
|
||||
|
@ -105,12 +105,22 @@
|
||||
.text
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
*/
|
||||
LEAF(copystr)
|
||||
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)
|
||||
|
||||
move t0, a2
|
||||
beq a2, zero, 4f
|
||||
1:
|
||||
@ -128,37 +138,14 @@ LEAF(copystr)
|
||||
PTR_SUBU a2, t0, a2 # if the 4th arg was non-NULL
|
||||
PTR_S a2, 0(a3)
|
||||
3:
|
||||
j ra # v0 is 0 or ENAMETOOLONG
|
||||
|
||||
PTR_S zero, U_PCB_ONFAULT(v1)
|
||||
j ra
|
||||
nop
|
||||
END(copystr)
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
__copyinstr_err:
|
||||
j ra
|
||||
li v0, EFAULT
|
||||
END(copyinstr)
|
||||
|
||||
/*
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-4-Clause
|
||||
*
|
||||
* Copyright (C) 1995 Wolfgang Solfrank.
|
||||
* Copyright (C) 1995 TooLs GmbH.
|
||||
* 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.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by TooLs GmbH.
|
||||
* 4. The name of TooLs GmbH may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
|
||||
*
|
||||
* $NetBSD: copystr.c,v 1.3 2000/06/08 06:47:17 kleink Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
/*
|
||||
* Emulate copyinstr.
|
||||
*/
|
||||
int
|
||||
copystr(kfaddr, kdaddr, len, done)
|
||||
const void *kfaddr;
|
||||
void *kdaddr;
|
||||
size_t len;
|
||||
size_t *done;
|
||||
{
|
||||
const u_char *kfp = kfaddr;
|
||||
u_char *kdp = kdaddr;
|
||||
size_t l;
|
||||
int rv;
|
||||
|
||||
rv = ENAMETOOLONG;
|
||||
for (l = 0; len-- > 0; l++) {
|
||||
if (!(*kdp++ = *kfp++)) {
|
||||
l++;
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (done != NULL) {
|
||||
*done = l;
|
||||
}
|
||||
return rv;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*-
|
||||
* 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);
|
||||
}
|
@ -366,9 +366,17 @@ void *memcpy_early(void * _Nonnull to, const void * _Nonnull from, size_t len);
|
||||
void *memmove_early(void * _Nonnull dest, const void * _Nonnull src, size_t n);
|
||||
#define bcopy_early(from, to, len) memmove_early((to), (from), (len))
|
||||
|
||||
int copystr(const void * _Nonnull __restrict kfaddr,
|
||||
void * _Nonnull __restrict kdaddr, size_t len,
|
||||
size_t * __restrict lencopied);
|
||||
#define copystr(src, dst, len, outlen) ({ \
|
||||
size_t __r, __len, *__outlen; \
|
||||
\
|
||||
__len = (len); \
|
||||
__outlen = (outlen); \
|
||||
__r = strlcpy((dst), (src), __len); \
|
||||
if (__outlen != NULL) \
|
||||
*__outlen = ((__r >= __len) ? __len : __r + 1); \
|
||||
((__r >= __len) ? ENAMETOOLONG : 0); \
|
||||
})
|
||||
|
||||
int copyinstr(const void * __restrict udaddr,
|
||||
void * _Nonnull __restrict kaddr, size_t len,
|
||||
size_t * __restrict lencopied);
|
||||
@ -382,11 +390,9 @@ int copyout_nofault(const void * _Nonnull __restrict kaddr,
|
||||
void * __restrict udaddr, size_t len);
|
||||
|
||||
#ifdef KCSAN
|
||||
int kcsan_copystr(const void *, void *, size_t, size_t *);
|
||||
int kcsan_copyin(const void *, void *, size_t);
|
||||
int kcsan_copyinstr(const void *, void *, size_t, size_t *);
|
||||
int kcsan_copyout(const void *, void *, size_t);
|
||||
#define copystr(kf, k, l, lc) kcsan_copystr((kf), (k), (l), (lc))
|
||||
#define copyin(u, k, l) kcsan_copyin((u), (k), (l))
|
||||
#define copyinstr(u, k, l, lc) kcsan_copyinstr((u), (k), (l), (lc))
|
||||
#define copyout(k, u, l) kcsan_copyout((k), (u), (l))
|
||||
|
39
tools/coccinelle/copystr9.cocci
Normal file
39
tools/coccinelle/copystr9.cocci
Normal file
@ -0,0 +1,39 @@
|
||||
@ nostorederror_nostoredlen @
|
||||
expression __src, __dst, __len;
|
||||
statement S1;
|
||||
@@
|
||||
|
||||
S1
|
||||
-copystr(__src, __dst, __len, NULL);
|
||||
+strlcpy(__dst, __src, __len);
|
||||
|
||||
@ ifcondition_nostoredlen @
|
||||
expression __src, __dst, __len;
|
||||
statement S1;
|
||||
@@
|
||||
if (
|
||||
(
|
||||
-copystr(__src, __dst, __len, NULL) == ENAMETOOLONG
|
||||
|
|
||||
-copystr(__src, __dst, __len, NULL) != 0
|
||||
|
|
||||
-copystr(__src, __dst, __len, NULL)
|
||||
)
|
||||
+strlcpy(__dst, __src, __len) >= __len
|
||||
) S1
|
||||
|
||||
@ nostorederror_storedlen1 @
|
||||
expression __src, __dst, __len;
|
||||
identifier __done;
|
||||
statement S1;
|
||||
@@
|
||||
S1
|
||||
(
|
||||
-copystr(__src, __dst, __len, &__done);
|
||||
+__done = strlcpy(__dst, __src, __len);
|
||||
+__done = MIN(__done, __len);
|
||||
|
|
||||
-copystr(__src, __dst, __len, __done);
|
||||
+ *__done = strlcpy(__dst, __src, __len);
|
||||
+ *__done = MIN(*__done, __len);
|
||||
)
|
Loading…
Reference in New Issue
Block a user