From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id A881F3985463 for ; Sun, 27 Sep 2020 14:04:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A881F3985463 Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-88-BLt23zNzN_WQiLC6N9cEyQ-1; Sun, 27 Sep 2020 10:04:16 -0400 X-MC-Unique: BLt23zNzN_WQiLC6N9cEyQ-1 Received: by mail-qt1-f199.google.com with SMTP id b54so6254285qtk.17 for ; Sun, 27 Sep 2020 07:04:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:organization :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=tAnNtqmDyDv30sHmgONjqcOr7xcnJxuy3bhz2gvNFts=; b=VSQTZ1MSrfs3CuKT3t3lMHNXkkZN6juryfJl4hUGg8wU58qLhOom/DsmGLoVjgZM+p ZCDqTQddEBsReWRpV7d1+hnhIuE6Eod0jkvZfU/5wZ96LIcl6+Gk9VJPHOKQe6tuoZtI D8v4Bp1xmm3hIEyFN15eju+5Fdrw1mS4CUPWYzx50I0sU/erSOg0XOPj2wICtaMU6wVz 3tsjLrUruH9jEa1466T0KeUnhMh4aIyMGukRiCSKWVUWWc6zBHDA7Ixi8G1tLJD5Ci+K Zb0VPPS0Hhf7Iuus5ZzVNzzeKOHylksZ++P2dwbyfmnT8H8DMb1PwyEkFORdc3qewXMc dcJA== X-Gm-Message-State: AOAM532AONd61Yr1ximjZLxJOY7CdRn/G2iQNMlfXyYs5eF17+3cQHPB LAfEOAxvpLlLy4aB5CCr83MpetdicaRyVBtwPbixgYt6yfns63RwIL1wqRt6bb4Xd+1epynosQu zHrEkBy0Dr2RoeAhXyNw/ X-Received: by 2002:ac8:b8b:: with SMTP id h11mr8218425qti.28.1601215455694; Sun, 27 Sep 2020 07:04:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzFlF+E1lpCckVAy+ux1koMCEwEmGNk0vYO0wf/1pMurf0xd5dsZiDTo+u62T4NxAAUcx0KHg== X-Received: by 2002:ac8:b8b:: with SMTP id h11mr8218395qti.28.1601215455327; Sun, 27 Sep 2020 07:04:15 -0700 (PDT) Received: from [192.168.1.16] (198-84-214-74.cpe.teksavvy.com. [198.84.214.74]) by smtp.gmail.com with ESMTPSA id e26sm6510443qka.24.2020.09.27.07.04.13 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 27 Sep 2020 07:04:14 -0700 (PDT) Subject: Re: RFC: malloc and secure memory. To: Rich Felker Cc: libc-alpha References: <58adb753-aecf-d367-6dbe-bb475c4c4d2c@redhat.com> <20200926170710.GR3265@brightrain.aerifal.cx> From: Carlos O'Donell Organization: Red Hat Message-ID: <7cc72452-778a-94b5-fee5-dc5015f800b1@redhat.com> Date: Sun, 27 Sep 2020 10:04:13 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 MIME-Version: 1.0 In-Reply-To: <20200926170710.GR3265@brightrain.aerifal.cx> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-6.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Sep 2020 14:04:22 -0000 On 9/26/20 1:07 PM, Rich Felker wrote: > On Thu, Sep 24, 2020 at 04:56:59PM -0400, Carlos O'Donell via Libc-alpha wrote: >> In reviewing this discussion: >> https://github.com/systemd/systemd/pull/14213 >> >> The request is for a way to mark some allocations as "secure" >> and to give them special properties. >> >> I wonder if we can't do this in some generic way: >> >> - Make arenas a first class construct. >> >> /* Get arena with special properties. */ >> malloc_arena *secure_arena = NULL; >> /* Get a handle to an arena that has secure heaps. If glibc can make this >> kind of arena and heap then it does, otherwise it returns NULL. */ >> secure_arena = malloc_arena_get (HEAP_SECURE); >> /* Does this glibc support his kind of arena? */ >> if (secure_arena == NULL) >> abort(); >> >> - Bind the malloc call site to a specific arena with specific properties. > > I don't see any plausible motivation for why a caller would want to do > this rather than just calling mmap. It's far less portable, more > error-prone (since it doesn't look like it would catch use of one type > where you meant the other, as opposed to with direct mmap where > passing it to free or vice versa would trap at some point), and more > complex to program for. I agree with all of your points. However, if you have existing legacy APIs and by their semantics the caller can free some allocations later with free() and you want to transparently apply some kind of additional semantics, then you need: * At the call site of the allocation the extra properties need to be applied. * At the call site of the deallocation the caller may no longer be aware of the extra properties and the deallocation should proceed as expected. Don't get me wrong, applying a design like this yields problems, and you and I point them out. In summary: * New API is not as portable as mmap. * New API yields problems for interposed allocators. * New API could yield problems if down-stack callers imply that they can free/malloc (realloc might work) the allocation without loosing the additional properties. > Is the answer just "for systemd reasons"? Having a public conversation about something and coming up with valid reasons NOT to do it is just as important as having a conversation for all the things you WOULD do. The only way I see to have such a conversation is to put together an RFC, discuss it, and reject the proposal with rationale given. I might also have raised this issue on libc-coord actually, now that you mention "reasons." >> For example: >> >> /* malloc_arena takes an opaque arena pointer that is a global >> variable that the implementation provides, a function pointer >> the memory allocator routine e.g. malloc, and a size. */ >> password_storage = malloc_arena (secure_arena, malloc, size); > > Is the function pointer merely being used as a lookup key here? Or is > the intend that it would be implemented by changing some thread-local > context, calling the pointed-to function, then restoring it? I don't > see what you get by having this weird interface since the signature > has to match to make the call, and there are no other malloc-family > functions that match malloc's signature anyway. I mention the primary rationale here in the downthread post, but let me elucidate the problem a bit more: (1) glibc implements an general purpose system allocator. (2) Various APIs all use the allocator, and as such their returned pointers are compatible with the allocator's unadorned free() API. (3) Other developers implement interposed allocators and as such there may be a mix of new/old interposers and new/old glibc. (4) Users expect interposted allocators to work. It turns out that over time supporting (4) creates a strong incentive to avoid changing the implemented allocator APIs. Why? If you add any API to (1) and (3) doesn't support it, then when you add in code that uses a new allocator API and attempt (4) it will likely fail as chunks cross allocator boundaries because (3) didn't interpose the new APIs. Today it basically means we can't extend the allocator APIs anymore because of prevalent use of special-purpose allocators designed to optimize for specific workloads e.g. jemalloc, tcmalloc, new-tcmalloc. To avoid problematic scenarios we need to provide entirely new APIs that users would never mix with the original allocator APIs. One suggestion is to provide a way to bind the allocation and deallocation sides together at compile time, and I have no solutions for that today. My last idea is, as proposed above, to pass in the pointer to the expected malloc, and if the allocator can prove that this malloc does not match e.g. detect interposition, then it can declare that the free is equally unsafe and return NULL for the allocation to indicate that such memory with such properties cannot be allocated. In summary: - Supporting allocator interposition has created a composability problem with adding new allocation/deallocation APIs. - glibc is effectively unable to add new APIs easily that aren't just in the form of hints to mallopt(). - If we have composability problems then we should just use new APIs from other allocator libraries and leave glibc's malloc for applications that need those exact semantics. - New libraries can provide a superset of glibc's APIs and that would be safe because the application would require that specific library to operate. Do you agree with that summary? -- Cheers, Carlos.