From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F213C02183 for ; Fri, 17 Jan 2025 02:22:52 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A34676B0082; Thu, 16 Jan 2025 21:22:51 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 9E4906B0085; Thu, 16 Jan 2025 21:22:51 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 884E26B0088; Thu, 16 Jan 2025 21:22:51 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 61DD26B0082 for ; Thu, 16 Jan 2025 21:22:51 -0500 (EST) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 1470045B81 for ; Fri, 17 Jan 2025 02:22:51 +0000 (UTC) X-FDA: 83015345742.04.C58DE85 Received: from mout.perfora.net (mout.perfora.net [74.208.4.197]) by imf30.hostedemail.com (Postfix) with ESMTP id C39948000E for ; Fri, 17 Jan 2025 02:22:48 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=jordanrome.com header.s=s1-ionos header.b=Pb5EU2Ty; dmarc=none; spf=pass (imf30.hostedemail.com: domain of linux@jordanrome.com designates 74.208.4.197 as permitted sender) smtp.mailfrom=linux@jordanrome.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1737080569; a=rsa-sha256; cv=none; b=ejUrZ/kUmWHxKQbBpiLIDKx3UpotpZ/rY+nwYwO3bbyasWGVDnRk2y3cfz+N0s/YyvWCUf hrAv7niACpsr0wZKw+aR36Wh1K3ww82R8ahRze4oQGrBwJhJUC90kSAbcNTvphj189gpvJ MNBg0yk8mYAbP+R4gBzh3S6Ql/dJiQY= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=jordanrome.com header.s=s1-ionos header.b=Pb5EU2Ty; dmarc=none; spf=pass (imf30.hostedemail.com: domain of linux@jordanrome.com designates 74.208.4.197 as permitted sender) smtp.mailfrom=linux@jordanrome.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1737080569; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=NHUkJ8oujQfDsLiTqMkqHozkrDqVm9z4cONZsMp0oKQ=; b=MnyOc9iML9fNCBcAwRZxj2I2YElMuGksS9KpKBJaeZB5/XAaRfCWDtuDNdh/6Q01CY13+d ScjhTNJcuEHyylAWfKwInQfoqkcUqjpHk0cw7EKes+ID4nUBZdpsREEipHiMkbOzdNDREU W5Ug6JMgg8FYQqfF7/YNMvCZgJkEeUo= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jordanrome.com; s=s1-ionos; t=1737080567; x=1737685367; i=linux@jordanrome.com; bh=NHUkJ8oujQfDsLiTqMkqHozkrDqVm9z4cONZsMp0oKQ=; h=X-UI-Sender-Class:MIME-Version:References:In-Reply-To:From:Date: Message-ID:Subject:To:Cc:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=Pb5EU2TyByUohbL29h8zH5RRK11VFD5y0tc+xeyDA1ynGmoAQSp3FiIuVX/urvHn z9XkIQmrhNJ6PQOCaEJlt3uQW8C+sd1ohsNyXs50bPpTcb1PGPKkIRXNzbFifjruX l2fAmxKwoW7ZrhcUXlXic+OYG+oZqv6XEMTCX1dT87JCFOuwCH3Og/EwqKeemNQkb zJFNe+NRli6uNgVDN7sgPfkYDXYPwZGjDGs9cMuiMJnTi+9GzHsvyBNwMI/Zw957f NUkFXwefA6cuhQCyEIXO3T+9KF6l6aBxllwHTdZwG68/XOaEEdSxlMu9wS8XZ1rt0 qA5SeFmwy0wCEjMEEA== X-UI-Sender-Class: 55c96926-9e95-11ee-ae09-1f7a4046a0f6 Received: from mail-il1-f182.google.com ([209.85.166.182]) by mrelay.perfora.net (mreueus003 [74.208.5.2]) with ESMTPSA (Nemesis) id 0MhBR9-1tuO742jVh-00PTym for ; Fri, 17 Jan 2025 03:22:47 +0100 Received: by mail-il1-f182.google.com with SMTP id e9e14a558f8ab-3a9cdcec53fso11870285ab.1 for ; Thu, 16 Jan 2025 18:22:47 -0800 (PST) X-Forwarded-Encrypted: i=1; AJvYcCWva+RwSokBYqFdg9HhOXep63eyT3Rp1vjj9uByg3NpnvKJt+kwVxR31or992iJbdc81gzdrKfTkQ==@kvack.org X-Gm-Message-State: AOJu0YzvaA+FjxWnR5ydC3kBKv3E3NREkwWS1yV4GUwLHvizlXkktIcN h1/r0qLgqCB56BSjs4Eijdq3J8vz86IoaL1xO8ESnYZzaAolV+UktvpOMydciqH03IavTSvDVVo 3oOcKyvHDFi85Jt9c3dvrWbNXHLM= X-Google-Smtp-Source: AGHT+IFR6OFCfJDQjdZa6E7btS+SmM2Bxrw66M2hQBWc0WwX3iQMf1l/RH+4TO4aiKndHBYN/PzfkruidkFQX8LStc8= X-Received: by 2002:a92:c26b:0:b0:3a7:d792:d6c4 with SMTP id e9e14a558f8ab-3cf744beabemr8436275ab.21.1737080567015; Thu, 16 Jan 2025 18:22:47 -0800 (PST) MIME-Version: 1.0 References: <20250107020632.170883-1-linux@jordanrome.com> In-Reply-To: From: Jordan Rome Date: Thu, 16 Jan 2025 21:22:35 -0500 X-Gmail-Original-Message-ID: X-Gm-Features: AbW1kvbzbH3vxkrpR0D8T85lIaZiMOhkJFI82AceJSQrSPxAX5QHB4LaBRdqclA Message-ID: Subject: Re: [bpf-next v2 1/2] bpf: Add bpf_copy_from_user_task_str kfunc To: Andrii Nakryiko Cc: bpf@vger.kernel.org, linux-mm@kvack.org, Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Kernel Team , Andrew Morton , Shakeel Butt Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:CmHvd5yYLIzDKZ0CHzEn5Rm4Yzv4WsDiJDBGLo0kZDBK6MDyHEL v+UHWURH87CRqdZ2XRFZLTb4jildQSaoIilcD2AKhKzE3x/maE6La80fAXuAkhf1nzyfp99 cgfRhQShWVLPKMkUD2Od8HSierBFzZF0J/CtszqPIGxTNPtQShRIZVva0C6n1wgPHJQ7MpI MlR8MPCuyfV/GNbjyBHIg== UI-OutboundReport: notjunk:1;M01:P0:w20puGy9s6w=;wf3cJ8UE358QHum3KcMjGTTTqOB 0rnNMubWigNj53w0hT/3Uf1xEokPNwJF3lc738zCZyLP4Tkyghvkil3RRAWHUWPyIgMX63AH4 Cl38bC6i39K7DVDf6LyqPJLGheWyjnlVrcT/yZfF9+O9YivP0jftiSAWtGziAHe22h/j3ijTp WizafVkt9Ne/8kmt4YqdBe2AIB5UWgBhfPw+C8eszHW8oqU4GznemIYJLhLc8sCosXVHm/DZK Wkkx46HcRztyk4baLGXRTVwx+xeA5gXfI57s7t/Bnx834bWlWZlm0Sv9iU3rdJA22APEN58x8 h/p8FKW+OGXn57JrG8GyOqmIwrXjjjU6TgnLpf49V+Fh9eQI//1MEeVEJmvfE7oy95LH7HlUp 2VPkMOaWp/8rlelZqXEbagMUe6LOcZqngqpmjd45C2CcJDKFfIQrtgZnvE6Ofo6fEVpLV8F7H r6TBnsRb8rtB+l6AhRSZzeDmviALqsFkPf50wxHfoWhabR0apjSZBj8S5m4Uj6UA4Y/V9cz0i 60MoLgc27f2fnV5GolR1L3dWPey4I/4DWpQ0s0cz/mfaAZR0AciMIE38N/OCo0m+Apt4V6sVh eqDlrTJZl22ZtP+/vQieJPh1uCtuJ5xPjl8CWV/zUA/+TBTtK6nsTpJsBZsvMV4NARhefiZfL P/jV35AcYGn4Lk0jsFxgwP+wBgwtavdcllbWuvMHNvryfUqjBw2P+GOb81VkvXhn/M5O5gZqS WiD5zAHqVik4HM1tKWG1U5npdZDkm4SzfC22ZIRmJeDefqSKDaCOvPDGNJotdLw0WO7pJ8Bej K1keX24TwrTIZseFySQdVA1IBOlKWlkjkCtcJDWs0lopnNYwFPipdIh+Gb+AF/Othi8LU778l okmWcIG++fKfReVpCdaC3jpZYMk419Zr/++AXWFUzyLzapicIrffZC0/OTAB95dQU/lRlsaek 3l4NUXUTBwsPh0BgndR7nxmrQ49P+rmq3PDek5LDpkE0vChjKG7HZmiw78opySoHYxCm5x2ZG MzTJzbPqLfewJUHO+etMTvv1vW555n8VFf4v3ogl93IUZhfpTLaDttN35sVaU1mFJJ1boGKYb fb44CPGsK53RaQ+JVbqSHpL2FCMd2om1yadMS20lc2yawBQkmCl9/k4/+w6pH/FZHsMNT7Ofc = X-Rspam-User: X-Rspamd-Queue-Id: C39948000E X-Rspamd-Server: rspam10 X-Stat-Signature: pkidgushqs4g1uzhtiadtxfy3coh5s3b X-HE-Tag: 1737080568-153575 X-HE-Meta: U2FsdGVkX18OZi8B8btZyq/VHnToXt3wbJrM8ge0gxpYAJ5HZeHvIo/ly6P32CDXbNk5Y7mD52HbrJzoguaFvc4Qaoywiwuat1vBZ5Y5rwMUzPZTv99+eCUnhEXEbvibYtK1tD6qnu0wwZ6Q3fnYWN0LXknoI21G43zgXvawq047syt72R4qSx1BUteaYYfERZRstwinOD+hr2I6jkXVQShATqerIVIvgBHckmfoZ9RqRDDRb0itf4qFejkOf5EITWnf86F2sIG1M71djQfUEHeGIP1mQdmbBgftcDVbcCVzjqDyrcMw8L5Gtr4wk4JioWZtJIL33WjmApSXzYwXS2DvlXjy+FxQKhWB/7/Yktv3K3cG2a8xQrLacJwNOD/YIPCSgfXEyNq3T+5scxmj5pWPEvg7kstMtJXBNnu/PBSIAK1wwiGt1AiGrd1OnSDaVm7Bz8zQ2QG/8bAKmroaPNlOfFNvPpZgGb74Q2TSUo4Dfmc2E3S12ZTp6Czet5WNjxsuZtJHnd13QCRkXYIuXktZ1wiqb9w2fP6QwptWMZo/ex8nROnWTmn+OFKWnVaZTEsmTavWj2s3cS/2ddchcc7njp0Uno1QYX35JkoZLgKZAkDsFmxE682jmrkijP6U83ptfWNLh0zodURyaKys6M4cHHtvRDrmhFHQTyTt+dephC0BYHzun5FFPtIB3JdT3YLykyDMHmezfsknTptXgYDiqf6Gl9CWJTxX8Ld9wTVN7aURELgsvEVb58lXj7QVayfa9rnIoD5qzbNVOqlsz3XUgY3A8hb1+qTIVQ42z5G4510iQmKvE7Q6tfUAMl352d1YnVn7qC9lOv6LQg6cNjpnQqElutAp1xN8nGPW7CGs2WXus0/2xsbmy4wOdMoDOZQjVkLOd2hWDra8hbGu5zr5PnMGgGXsLB5zs+94h9FWVRvE3S3BSIfRmb5OqwjxuGNapPexF9uUjwY6wTo pODaMLIk CNw2P6bz58i3oJksS6BvK8B+pXPXGw9nnzR80gIwL28CjmFx/bnKiadO8HdVfpoZ+rPixd6kA7pnMKgyzVxFKDBRHOeuCsfVAzrbL9ahSqdG7r5UR5HSS4NQ7vaBZGX7MU18xvYr3v8hEBwp3WuQrAQ5FJ1bKZXLg6btqyO9Oe5ihHqXYRbUhbOkCsqEHCBICUUC1ttJUaZU8GILi7yUdtk9FJFDyy3BNuWqXoWn453RldqqVGKLmyzaKp0d1pFkC4YuzfbiH9iO45QMt9f+qnDWpphULC1j3nTjiONZeLM8HmyTJeBLj4OG5/pQ20f+QO5MSwHXHwS2UNfEhmsPMUrYlgGQDZceZn/ZC5NPty4HxECqcM4qEMNnmF/w1eNLTAYFhx1tSStVj5ygUv/2PSRsX3qA8zYC+jI+14u3Oq++4ABU= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: On Fri, Jan 10, 2025 at 4:50=E2=80=AFPM Andrii Nakryiko wrote: > > On Mon, Jan 6, 2025 at 6:12=E2=80=AFPM Jordan Rome = wrote: > > > > This new kfunc will be able to copy a string > > from another process's/task's address space. > > nit: this is kernel code, task is unambiguous, so I'd drop the > "process" reference here > > > This is similar to `bpf_copy_from_user_str` > > but accepts a `struct task_struct*` argument. > > > > This required adding an additional function > > in memory.c, namely `copy_str_from_process_vm`, > > which works similar to `access_process_vm` > > but utilizes the `strncpy_from_user` helper > > and only supports reading/copying and not writing. > > > > Signed-off-by: Jordan Rome > > --- > > include/linux/mm.h | 3 ++ > > kernel/bpf/helpers.c | 46 ++++++++++++++++++++ > > mm/memory.c | 101 +++++++++++++++++++++++++++++++++++++++++++ > > 3 files changed, 150 insertions(+) > > > > please check kernel test bot's complains as well Maybe I need an entry in nommu.c as well for 'copy_remote_vm_str'? > > > diff --git a/include/linux/mm.h b/include/linux/mm.h > > index c39c4945946c..52b304b20630 100644 > > --- a/include/linux/mm.h > > +++ b/include/linux/mm.h > > @@ -2484,6 +2484,9 @@ extern int access_process_vm(struct task_struct *= tsk, unsigned long addr, > > extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, > > void *buf, int len, unsigned int gup_flags); > > > > +extern int copy_str_from_process_vm(struct task_struct *tsk, unsigned = long addr, > > + void *buf, int len, unsigned int gup_flags); > > nit: curious what mm folks think about naming, I'd go with a slightly > less verbose naming: "copy_remote_vm_str" (copy vs access, _str suffix > for non fixed-sized semantics marking) Ack. > > for the next revision, let's split out mm parts from helpers parts, I > don't think we lose much as this new internal API is self-contained, > and it will be easier for mm folks to review Ack. > > > + > > long get_user_pages_remote(struct mm_struct *mm, > > unsigned long start, unsigned long nr_pages, > > unsigned int gup_flags, struct page **pages, > > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > > index cd5f9884d85b..45d41b7a9906 100644 > > --- a/kernel/bpf/helpers.c > > +++ b/kernel/bpf/helpers.c > > @@ -3072,6 +3072,51 @@ __bpf_kfunc void bpf_local_irq_restore(unsigned = long *flags__irq_flag) > > local_irq_restore(*flags__irq_flag); > > } > > > > +/** > > + * bpf_copy_from_user_task_str() - Copy a string from an task's addres= s space > > + * @dst: Destination address, in kernel space. This buffe= r must be > > + * at least @dst__sz bytes long. > > + * @dst__sz: Maximum number of bytes to copy, includes the tra= iling NUL. > > + * @unsafe_ptr__ign: Source address in the task's address space. > > + * @tsk: The task whose address space will be used > > + * @flags: The only supported flag is BPF_F_PAD_ZEROS > > + * > > + * Copies a NULL-terminated string from a task's address space to BPF = space. > > there is no "BPF space", really... maybe "copies string into *dst* buffer= " Ack. > > > + * If user string is too long this will still ensure zero termination = in the > > + * dst buffer unless buffer size is 0. > > + * > > + * If BPF_F_PAD_ZEROS flag is set, memset the tail of @dst to 0 on suc= cess and > > + * memset all of @dst on failure. > > + */ > > +__bpf_kfunc int bpf_copy_from_user_task_str(void *dst, u32 dst__sz, co= nst void __user *unsafe_ptr__ign, struct task_struct *tsk, u64 flags) > > this looks like a long line, does it fit under 100 characters? I'll fix it in the next revision. > > > +{ > > + int count =3D dst__sz - 1; > > + int ret =3D 0; > > + > > + if (unlikely(flags & ~BPF_F_PAD_ZEROS)) > > + return -EINVAL; > > + > > + if (unlikely(!dst__sz)) > > + return 0; > > + > > + ret =3D copy_str_from_process_vm(tsk, (unsigned long)unsafe_ptr= __ign, dst, count, 0); > > + > > + if (ret <=3D 0) { > > + if (flags & BPF_F_PAD_ZEROS) > > + memset((char *)dst, 0, dst__sz); > > nit: no need for (char *) cast? memset takes void *, I think > > > + return ret; > > if ret =3D=3D 0, is that an error? If so, `return ret ?: -EINVAL;` or > something along those lines? Good catch. > > pw-bot: cr > > > + } > > + > > + if (ret < count) { > > + if (flags & BPF_F_PAD_ZEROS) > > + memset((char *)dst + ret, 0, dst__sz - ret); > > + } else { > > + ((char *)dst)[count] =3D '\0'; > > + } > > + > > + return ret + 1; > > +} > > + > > __bpf_kfunc_end_defs(); > > > > BTF_KFUNCS_START(generic_btf_ids) > > @@ -3164,6 +3209,7 @@ BTF_ID_FLAGS(func, bpf_iter_bits_new, KF_ITER_NEW= ) > > BTF_ID_FLAGS(func, bpf_iter_bits_next, KF_ITER_NEXT | KF_RET_NULL) > > BTF_ID_FLAGS(func, bpf_iter_bits_destroy, KF_ITER_DESTROY) > > BTF_ID_FLAGS(func, bpf_copy_from_user_str, KF_SLEEPABLE) > > +BTF_ID_FLAGS(func, bpf_copy_from_user_task_str, KF_SLEEPABLE) > > BTF_ID_FLAGS(func, bpf_get_kmem_cache) > > BTF_ID_FLAGS(func, bpf_iter_kmem_cache_new, KF_ITER_NEW | KF_SLEEPABLE= ) > > BTF_ID_FLAGS(func, bpf_iter_kmem_cache_next, KF_ITER_NEXT | KF_RET_NUL= L | KF_SLEEPABLE) > > diff --git a/mm/memory.c b/mm/memory.c > > index 75c2dfd04f72..514490bd7d6d 100644 > > --- a/mm/memory.c > > +++ b/mm/memory.c > > @@ -6673,6 +6673,75 @@ static int __access_remote_vm(struct mm_struct *= mm, unsigned long addr, > > return buf - old_buf; > > } > > > > +/* > > + * Copy a string from another process's address space as given in mm. > > + * Don't return partial results. If there is any error return -EFAULT. > > What does "don't return partial results" mean? What happens if we read > part of a string and then fail to read the rest? As per the last sentence, if we fail to read the rest of the string then an -EFAULT is returned. > > > + */ > > +static int __copy_str_from_remote_vm(struct mm_struct *mm, unsigned lo= ng addr, > > + void *buf, int len, unsigned int gup_flag= s) > > +{ > > + void *old_buf =3D buf; > > + int err =3D 0; > > + > > + if (mmap_read_lock_killable(mm)) > > + return -EFAULT; > > + > > + /* Untag the address before looking up the VMA */ > > + addr =3D untagged_addr_remote(mm, addr); > > + > > + /* Avoid triggering the temporary warning in __get_user_pages *= / > > + if (!vma_lookup(mm, addr)) { > > + mmap_read_unlock(mm); > > + return -EFAULT; > > maybe let's do (so that we do mmap_read_unlock in just one place) Ack. > > err =3D -EFAULT; > goto err_out; > > and then see below > > > + } > > + > > + while (len) { > > + int bytes, offset, retval; > > + void *maddr; > > + struct vm_area_struct *vma =3D NULL; > > + struct page *page =3D get_user_page_vma_remote(mm, addr= , > > + gup_flags,= &vma); > > + > > nit: I'd split page declaration and assignment and kept > get_user_page_vma_remote() invocation on a single line Ack. > > > + if (IS_ERR(page)) { > > + /* > > + * Treat as a total failure for now until we de= cide how > > + * to handle the CONFIG_HAVE_IOREMAP_PROT case = and > > + * stack expansion. > > + */ > > + err =3D -EFAULT; > > + break; > > + } > > + > > + bytes =3D len; > > + offset =3D addr & (PAGE_SIZE - 1); > > + if (bytes > PAGE_SIZE - offset) > > + bytes =3D PAGE_SIZE - offset; > > + > > + maddr =3D kmap_local_page(page); > > + retval =3D strncpy_from_user(buf, (const char __user *)= addr, bytes); > > you are not using maddr... that seems wrong (even if it works due to > how kmap_local_page is currently implemented) How do you think we should handle it then? > > > + unmap_and_put_page(page, maddr); > > + > > + if (retval < 0) { > > + err =3D retval; > > + break; > > + } > > + > > + len -=3D retval; > > + buf +=3D retval; > > + addr +=3D retval; > > + > > + /* Found the end of the string */ > > + if (retval < bytes) > > + break; > > + } > > err_out: here > > > + mmap_read_unlock(mm); > > + > > + if (err) > > + return err; > > + > > + return buf - old_buf; > > +} > > + > > /** > > * access_remote_vm - access another process' address space > > * @mm: the mm_struct of the target address space > > @@ -6714,6 +6783,38 @@ int access_process_vm(struct task_struct *tsk, u= nsigned long addr, > > } > > EXPORT_SYMBOL_GPL(access_process_vm); > > > > +/** > > + * copy_str_from_process_vm - copy a string from another process's add= ress space. > > + * @tsk: the task of the target address space > > + * @addr: start address to access > > access -> read from Ack. > > > + * @buf: source or destination buffer > > for this api it's always the destination, right? Right. Will fix. > > > + * @len: number of bytes to transfer > > + * @gup_flags: flags modifying lookup behaviour > > + * > > + * The caller must hold a reference on @mm. > > + * > > + * Return: number of bytes copied from source to destination. If the s= tring > > + * is shorter than @len then return the length of the string. > > and if the string is longer than @len, then what happens? we should > either specify or drop the "if string is shorter bit" and make it > unambiguous whether terminating zero is included or not I'll make it clearer. > > > + * On any error, return -EFAULT. > > + */ > > +int copy_str_from_process_vm(struct task_struct *tsk, unsigned long ad= dr, > > + void *buf, int len, unsigned int gup_flags) > > +{ > > + struct mm_struct *mm; > > + int ret; > > + > > + mm =3D get_task_mm(tsk); > > + if (!mm) > > + return -EFAULT; > > + > > + ret =3D __copy_str_from_remote_vm(mm, addr, buf, len, gup_flags= ); > > + > > + mmput(mm); > > + > > + return ret; > > +} > > +EXPORT_SYMBOL_GPL(copy_str_from_process_vm); > > + > > /* > > * Print the name of a VMA. > > */ > > -- > > 2.43.5 > >