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 X-Spam-Level: X-Spam-Status: No, score=-6.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D52EFC43457 for ; Thu, 15 Oct 2020 11:27:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4FB7022250 for ; Thu, 15 Oct 2020 11:27:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SLKdxK4x" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728902AbgJOLZq (ORCPT ); Thu, 15 Oct 2020 07:25:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727972AbgJOLYt (ORCPT ); Thu, 15 Oct 2020 07:24:49 -0400 Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B437CC061755; Thu, 15 Oct 2020 04:24:48 -0700 (PDT) Received: by mail-wr1-x442.google.com with SMTP id y12so2980747wrp.6; Thu, 15 Oct 2020 04:24:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=+GsbYluG4u73BDHZLeU5QbT5MuUDYp+oqb/QiX1Syl0=; b=SLKdxK4xJ3f0UY65WuYDwOPmq8FiXCQsoHFIAEDjY/8fRXghl9pW/mmrLFle8mJ0Ea aWzOwGaLTbr05PdcAjHdASzr5w3A3mX1D3vyq4zXPQEistjoQmgPXDQUSwA2OAiyEtwv HstV4YdLQU5+/tQRVgJKpiKI23jjUegxDeAS4yVYGG5CgvLcSYVKFHE5GFEym292a5OL cwsGfPeWMrGzPsAdMCdjBG1XN+IvtfmJByG8QOpVp/bNrrHHpfDY4AsNbXtXq2luxE6v /HiB+9bhXRdNxn0R+wh9kPvNhKzNtvuUHUJ1NxpZKysLmqf8KbSDv7mzhpWu/4XIGpdG uVTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=+GsbYluG4u73BDHZLeU5QbT5MuUDYp+oqb/QiX1Syl0=; b=AuDixC13eC3NXx58HmDtaL+TE7Dx/omlGL3xqywcT/Y+trCozxqeWABQbMer0pN4uI aDruesC7rMmsWLz+OI0v9lTCfSAl8xEjqi4H9vV7JAFWp1MlDZRWiYjy/Y5+O+k3bLaw yy++vQ2NmYHmzoQHQw1Gs7HNwEqO2sAjZEoBgkJeohk61UcXO6/ibPIxe8TGgIqnzgyu Mxr9nGK4oxLUoiFPJU08jB4aLddDNndlSXZHalaVlxENGi+3Vi1+u/rQO6GgsFSYmgsR yO97H+Y98nNC1DrcuQSACFeRawfhxhWDpM/tp+Vzr09o3+tAK9lgk4WF4IpcApmuzZFp 9gPQ== X-Gm-Message-State: AOAM530qGaq/0doQXmUa652zKUyDj8vx7gCEcrBw7PL2OYNQioY1J43f SSHn54o/POV0jGfHp00CMXU= X-Google-Smtp-Source: ABdhPJyLzb1oNdIf3dcQDnEybL8jAcn6eVv8vhtqU7+wnrvHk69L6GlDUHCHaX6ML2cLfRBMpXcwIQ== X-Received: by 2002:a05:6000:12c2:: with SMTP id l2mr3744783wrx.76.1602761086653; Thu, 15 Oct 2020 04:24:46 -0700 (PDT) Received: from [192.168.1.10] (static-176-175-73-29.ftth.abo.bbox.fr. [176.175.73.29]) by smtp.gmail.com with ESMTPSA id z191sm3999995wme.30.2020.10.15.04.24.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Oct 2020 04:24:45 -0700 (PDT) From: "Michael Kerrisk (man-pages)" Subject: Re: For review: seccomp_user_notif(2) manual page To: Jann Horn Cc: mtk.manpages@gmail.com, Tycho Andersen , Sargun Dhillon , Kees Cook , Christian Brauner , linux-man , lkml , Aleksa Sarai , Alexei Starovoitov , Will Drewry , bpf , Song Liu , Daniel Borkmann , Andy Lutomirski , Linux Containers , Giuseppe Scrivano , Robert Sesek References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> Message-ID: <5647b94a-4693-dad0-6e0d-ed178b495d65@gmail.com> Date: Thu, 15 Oct 2020 13:24:44 +0200 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: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Jann, So, first off, thank you for the detailed review. I really appreciate it! I've changed various pieces, and still have a few questions below. On 9/30/20 5:53 PM, Jann Horn wrote: > On Wed, Sep 30, 2020 at 1:07 PM Michael Kerrisk (man-pages) > wrote: >> I knew it would be a big ask, but below is kind of the manual page >> I was hoping you might write [1] for the seccomp user-space notification >> mechanism. Since you didn't (and because 5.9 adds various new pieces >> such as SECCOMP_ADDFD_FLAG_SETFD and SECCOMP_IOCTL_NOTIF_ADDFD >> that also will need documenting [2]), I did :-). But of course I may >> have made mistakes... > [...] >> NAME >> seccomp_user_notif - Seccomp user-space notification mechanism >> >> SYNOPSIS >> #include >> #include >> #include >> >> int seccomp(unsigned int operation, unsigned int flags, void *args); > > Should the ioctl() calls be listed here, similar to e.g. the SYNOPSIS > of the ioctl_* manpages? Yes, good idea. I added: int ioctl(int fd, SECCOMP_IOCTL_NOTIF_RECV, struct seccomp_notif *req); int ioctl(int fd, SECCOMP_IOCTL_NOTIF_SEND, struct seccomp_notif_resp *req); int ioctl(int fd, SECCOMP_IOCTL_NOTIF_ID_VALID, __u64 *id); > >> DESCRIPTION >> This page describes the user-space notification mechanism pro‐ >> vided by the Secure Computing (seccomp) facility. As well as the >> use of the SECCOMP_FILTER_FLAG_NEW_LISTENER flag, the SEC‐ >> COMP_RET_USER_NOTIF action value, and the SECCOMP_GET_NOTIF_SIZES >> operation described in seccomp(2), this mechanism involves the >> use of a number of related ioctl(2) operations (described below). >> >> Overview >> In conventional usage of a seccomp filter, the decision about how >> to treat a particular system call is made by the filter itself. >> The user-space notification mechanism allows the handling of the >> system call to instead be handed off to a user-space process. >> The advantages of doing this are that, by contrast with the sec‐ >> comp filter, which is running on a virtual machine inside the >> kernel, the user-space process has access to information that is >> unavailable to the seccomp filter and it can perform actions that >> can't be performed from the seccomp filter. >> >> In the discussion that follows, the process that has installed >> the seccomp filter is referred to as the target, and the process > > Technically, this definition of "target" is a bit inaccurate because: > > - seccomp filters are inherited > - seccomp filters apply to threads, not processes > - seccomp filters can be semi-remotely installed via TSYNC (Nice summary.) > (I assume that in manpages, we should try to go for the "a task is a > thread and a thread group is a process" definition, right?) Exactly. > Perhaps "the threads on which the seccomp filter is installed are > referred to as the target", or something like that would be better? Thanks. It's always hugely helpful to get a suggested wording, even if I still feel the need to rework it (which I don't in this case). The sentence now reads: In the discussion that follows, the thread(s) on which the seccomp filter is installed are referred to as the target, and the process that is notified by the user-space notification mechanism is referred to as the supervisor. >> that is notified by the user-space notification mechanism is >> referred to as the supervisor. An overview of the steps per‐ >> formed by these two processes is as follows: >> >> 1. The target process establishes a seccomp filter in the usual >> manner, but with two differences: >> >> · The seccomp(2) flags argument includes the flag SECCOMP_FIL‐ >> TER_FLAG_NEW_LISTENER. Consequently, the return value of >> the (successful) seccomp(2) call is a new "listening" file >> descriptor that can be used to receive notifications. >> >> · In cases where it is appropriate, the seccomp filter returns >> the action value SECCOMP_RET_USER_NOTIF. This return value >> will trigger a notification event. >> >> 2. In order that the supervisor process can obtain notifications >> using the listening file descriptor, (a duplicate of) that >> file descriptor must be passed from the target process to the >> supervisor process. One way in which this could be done is by >> passing the file descriptor over a UNIX domain socket connec‐ >> tion between the two processes (using the SCM_RIGHTS ancillary >> message type described in unix(7)). Another possibility is >> that the supervisor might inherit the file descriptor via >> fork(2). > > With the caveat that if the supervisor inherits the file descriptor > via fork(), that (more or less) implies that the supervisor is subject > to the same filter (although it could bypass the filter using a helper > thread that responds SECCOMP_USER_NOTIF_FLAG_CONTINUE, but I don't > expect any clean software to do that). It's a good thing no one ever writes unclean software... Thanks for catching this; Tycho did also. It was a thinko on my part to forget that if one used fork(), the supervisor would inherit the filter. I've simply removed the sentence mentioning fork(). >> 3. The supervisor process will receive notification events on the >> listening file descriptor. These events are returned as >> structures of type seccomp_notif. Because this structure and >> its size may evolve over kernel versions, the supervisor must >> first determine the size of this structure using the sec‐ >> comp(2) SECCOMP_GET_NOTIF_SIZES operation, which returns a >> structure of type seccomp_notif_sizes. The supervisor allo‐ >> cates a buffer of size seccomp_notif_sizes.seccomp_notif bytes >> to receive notification events. In addition,the supervisor >> allocates another buffer of size seccomp_notif_sizes.sec‐ >> comp_notif_resp bytes for the response (a struct sec‐ >> comp_notif_resp structure) that it will provide to the kernel >> (and thus the target process). >> >> 4. The target process then performs its workload, which includes >> system calls that will be controlled by the seccomp filter. >> Whenever one of these system calls causes the filter to return >> the SECCOMP_RET_USER_NOTIF action value, the kernel does not >> execute the system call; instead, execution of the target >> process is temporarily blocked inside the kernel and a notifi‐ > > where "blocked" refers to the interruptible, restartable kind - if the > child receives a signal with an SA_RESTART signal handler in the > meantime, it'll leave the syscall, go through the signal handler, then > restart the syscall again and send the same request to the supervisor > again. so the supervisor may see duplicate syscalls. So, I partially demonstrated what you describe here, for two example system calls (epoll_wait() and pause()). But I could not exactly demonstrate things as I understand you to be describing them. (So, I'm not sure whether I have not understood you correctly, or if things are not exactly as you describe them.) Here's a scenario (A) that I tested: 1. Target installs seccomp filters for a blocking syscall (epoll_wait() or pause(), both of which should never restart, regardless of SA_RESTART) 2. Target installs SIGINT handler with SA_RESTART 3. Supervisor is sleeping (i.e., is not blocked in SECCOMP_IOCTL_NOTIF_RECV operation). 4. Target makes a blocking system call (epoll_wait() or pause()). 5. SIGINT gets delivered to target; handler gets called; ***and syscall gets restarted by the kernel*** That last should never happen, of course, and is a result of the combination of both the user-notify filter and the SA_RESTART flag. If one or other is not present, then the system call is not restarted. So, as you note below, the UAPI gets broken a little. However, from your description above I had understood that something like the following scenario (B) could occur: 1. Target installs seccomp filters for a blocking syscall (epoll_wait() or pause(), both of which should never restart, regardless of SA_RESTART) 2. Target installs SIGINT handler with SA_RESTART 3. Supervisor performs SECCOMP_IOCTL_NOTIF_RECV operation (which blocks). 4. Target makes a blocking system call (epoll_wait() or pause()). 5. Supervisor gets seccomp user-space notification (i.e., SECCOMP_IOCTL_NOTIF_RECV ioctl() returns 6. SIGINT gets delivered to target; handler gets called; and syscall gets restarted by the kernel 7. Supervisor performs another SECCOMP_IOCTL_NOTIF_RECV operation which gets another notification for the restarted system call. However, I don't observe such behavior. In step 6, the syscall does not get restarted by the kernel, but instead returns -1/EINTR. Perhaps I have misconstructed my experiment in the second case, or perhaps I've misunderstood what you meant, or is it possibly the case that things are not quite as you said? > What's really gross here is that signal(7) promises that some syscalls > like epoll_wait(2) never restart, but seccomp doesn't know about that; > if userspace installs a filter that uses SECCOMP_RET_USER_NOTIF for a > non-restartable syscall, the result is that UAPI gets broken a little > bit. Luckily normal users of seccomp probably won't use > SECCOMP_RET_USER_NOTIF for restartable syscalls, but if someone does > want to do that, we might have to add some "suppress syscall > restarting" flag into the seccomp action value, or something like > that... yuck. Yes, the UAPI breakage is a bit sad (although, likely to be rarely encountered, as you note). I'm inclined to add a note about this in in BUGS, but beforehand I'm interested in hearing your thoughts on scenario B above. >> cation event is generated on the listening file descriptor. >> >> 5. The supervisor process can now repeatedly monitor the listen‐ >> ing file descriptor for SECCOMP_RET_USER_NOTIF-triggered >> events. To do this, the supervisor uses the SEC‐ >> COMP_IOCTL_NOTIF_RECV ioctl(2) operation to read information >> about a notification event; this operation blocks until an > > (interruptably - but I guess that maybe doesn't have to be said > explicitly here?) Yes, I think so. The general assumption is that syscalls block interruptibly, unless text in a manual page that says "uninterruptible". (Postscript: Christian made a similar comment, so I decided to explicitly note that it's an interruptible sleep.) >> event is available. > > Maybe we should note here that you can use the multi-fd-polling APIs > (select/poll/epoll) instead, and that if the notification goes away > before you call SECCOMP_IOCTL_NOTIF_RECV, the ioctl will return > -ENOENT instead of blocking, and therefore as long as nobody else > reads from the same fd, you can assume that after the fd reports as > readable, you can call SECCOMP_IOCTL_NOTIF_RECV once without blocking. I'd rather not add this info in the overview section, which is already longer than I would like. But I did add some details in NOTES: [[ The file descriptor returned when seccomp(2) is employed with the SECCOMP_FILTER_FLAG_NEW_LISTENER flag can be monitored using poll(2), epoll(7), and select(2). When a notification is pending, these interfaces indicate that the file descriptor is readable. Following such an indication, a subsequent SEC‐ COMP_IOCTL_NOTIF_RECV ioctl(2) will not block, returning either information about a notification or else failing with the error EINTR if the target process has been killed by a signal or its system call has been interrupted by a signal handler. ]] Okay? > Exceeeeept that this part looks broken: > > if (mutex_lock_interruptible(&filter->notify_lock) < 0) > return EPOLLERR; > > which I think means that we can have a race where a signal arrives > while poll() is trying to add itself to the waitqueue of the seccomp > fd, and then we'll get a spurious error condition reported on the fd. > That's a kernel bug, I'd say. Sigh... Writing documentation helps find bugs. Who knew? >> The operation returns a seccomp_notif >> structure containing information about the system call that is >> being attempted by the target process. >> >> 6. The seccomp_notif structure returned by the SEC‐ >> COMP_IOCTL_NOTIF_RECV operation includes the same information >> (a seccomp_data structure) that was passed to the seccomp fil‐ >> ter. This information allows the supervisor to discover the >> system call number and the arguments for the target process's >> system call. In addition, the notification event contains the >> PID of the target process. > > That's a PIDTYPE_PID, which the manpages call a "thread ID". Yes. Fixed now. More generally, I've swept through the page replacing various instances of "target process" with either "target thread", or often just "target". >> The information in the notification can be used to discover >> the values of pointer arguments for the target process's sys‐ >> tem call. (This is something that can't be done from within a >> seccomp filter.) To do this (and assuming it has suitable >> permissions), the supervisor opens the corresponding >> /proc/[pid]/mem file, > > ... which means that here we might have to get into the weeds of how > actually /proc has invisible directories for every TID, even though > only the ones for PIDs are visible, and therefore you can just open > /proc/[tid]/mem and it'll work fine? I myself was unaware of this for years until I *accidentally* made use of the feature in one of my test programs and then a while later got to asking myself "how come that worked?". About two years ago, I added some text (@) to explain this in proc(5) near the start of the page: Overview Underneath /proc, there are the following general groups of files and subdirectories: /proc/[pid] subdirectories [...] Underneath each of the /proc/[pid] directories, a task sub‐ directory contains subdirectories of the form task/[tid], [...] The /proc/[pid] subdirectories are visible when iterating through /proc with getdents(2) (and thus are visible when one uses ls(1) to view the contents of /proc). /proc/[tid] subdirectories @ Each one of these subdirectories contains files and subdi‐ @ rectories exposing information about the thread with the @ corresponding thread ID. The contents of these directories @ are the same as the corresponding /proc/[pid]/task/[tid] @ directories. @ The /proc/[tid] subdirectories are not visible when iterat‐ @ ing through /proc with getdents(2) (and thus are not visi‐ @ ble when one uses ls(1) to view the contents of /proc). I think I'll just drop a cross reference to proc(5) into the text in seccomp_user_notif. >> seeks to the memory location that corre‐ >> sponds to one of the pointer arguments whose value is supplied >> in the notification event, and reads bytes from that location. >> (The supervisor must be careful to avoid a race condition that >> can occur when doing this; see the description of the SEC‐ >> COMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation below.) In addi‐ >> tion, the supervisor can access other system information that >> is visible in user space but which is not accessible from a >> seccomp filter. >> >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │Suppose we are reading a pathname from /proc/PID/mem │ >> │for a system call such as mkdir(). The pathname can │ >> │be an arbitrary length. How do we know how much (how │ >> │many pages) to read from /proc/PID/mem? │ >> └─────────────────────────────────────────────────────┘ > > It can't be an arbitrary length. While pathnames *returned* from the > kernel in some places can have different limits, strings supplied as > path arguments *to* the kernel AFAIK always have an upper limit of > PATH_MAX, else you get -ENAMETOOLONG. See getname_flags(). Yes, another thinko on my part. I removed this FIXME. >> 7. Having obtained information as per the previous step, the >> supervisor may then choose to perform an action in response to >> the target process's system call (which, as noted above, is >> not executed when the seccomp filter returns the SEC‐ >> COMP_RET_USER_NOTIF action value). > > (unless SECCOMP_USER_NOTIF_FLAG_CONTINUE is used) As you probably saw, I give SECCOMP_USER_NOTIF_FLAG_CONTINUE a brief mention a couple of paragraphs later, and then go into rather more detail later in the page. (Or do you still think something needs fixing?) >> One example use case here relates to containers. The target >> process may be located inside a container where it does not >> have sufficient capabilities to mount a filesystem in the con‐ >> tainer's mount namespace. However, the supervisor may be a >> more privileged process that that does have sufficient capa‐ > > nit: s/that that/that/ Thanks. Fixed. >> bilities to perform the mount operation. >> >> 8. The supervisor then sends a response to the notification. The >> information in this response is used by the kernel to con‐ >> struct a return value for the target process's system call and >> provide a value that will be assigned to the errno variable of >> the target process. >> >> The response is sent using the SECCOMP_IOCTL_NOTIF_RECV >> ioctl(2) operation, which is used to transmit a sec‐ >> comp_notif_resp structure to the kernel. This structure >> includes a cookie value that the supervisor obtained in the >> seccomp_notif structure returned by the SEC‐ >> COMP_IOCTL_NOTIF_RECV operation. This cookie value allows the >> kernel to associate the response with the target process. > > (unless if the target thread entered a signal handler or was killed in > the meantime) Yes, but I think I have this adequately covered in the errors described later in the page for SECCOMP_IOCTL_NOTIF_RECV. (I have now added the target-process-terminated case to the orror text.) ENOENT The blocked system call in the target has been interrupted by a signal handler or the target process has terminated. Is that sufficient? >> 9. Once the notification has been sent, the system call in the >> target process unblocks, returning the information that was >> provided by the supervisor in the notification response. >> >> As a variation on the last two steps, the supervisor can send a >> response that tells the kernel that it should execute the target >> process's system call; see the discussion of SEC‐ >> COMP_USER_NOTIF_FLAG_CONTINUE, below. >> >> ioctl(2) operations >> The following ioctl(2) operations are provided to support seccomp >> user-space notification. For each of these operations, the first >> (file descriptor) argument of ioctl(2) is the listening file >> descriptor returned by a call to seccomp(2) with the SECCOMP_FIL‐ >> TER_FLAG_NEW_LISTENER flag. >> >> SECCOMP_IOCTL_NOTIF_RECV >> This operation is used to obtain a user-space notification >> event. If no such event is currently pending, the opera‐ >> tion blocks until an event occurs. > > Not necessarily; for every time a process entered a signal handler or > was killed while a notification was pending, a call to > SECCOMP_IOCTL_NOTIF_RECV will return -ENOENT. Yes, but do you not consider this sufficiently covered by the (updated) error text that appears later? (See below.) >> The third ioctl(2) >> argument is a pointer to a structure of the following form >> which contains information about the event. This struc‐ >> ture must be zeroed out before the call. >> >> struct seccomp_notif { >> __u64 id; /* Cookie */ >> __u32 pid; /* PID of target process */ > > (TID, not PID) Thanks. Fixed. >> __u32 flags; /* Currently unused (0) */ >> struct seccomp_data data; /* See seccomp(2) */ >> }; >> >> The fields in this structure are as follows: >> >> id This is a cookie for the notification. Each such >> cookie is guaranteed to be unique for the corre‐ >> sponding seccomp filter. In other words, this >> cookie is unique for each notification event from >> the target process. > > That sentence about "target process" looks wrong to me. The cookies > are unique across notifications from the filter, but there can be > multiple filters per thread, and multiple threads per filter. Thanks. I simply removed that last sentence. >> The cookie value has the fol‐ >> lowing uses: >> >> · It can be used with the SEC‐ >> COMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation to >> verify that the target process is still alive. >> >> · When returning a notification response to the >> kernel, the supervisor must include the cookie >> value in the seccomp_notif_resp structure that is >> specified as the argument of the SEC‐ >> COMP_IOCTL_NOTIF_SEND operation. >> >> pid This is the PID of the target process that trig‐ >> gered the notification event. >> >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │This is a thread ID, rather than a PID, right? │ >> └─────────────────────────────────────────────────────┘ > > Yeah. Thanks. I've made various fixes. >> flags This is a bit mask of flags providing further >> information on the event. In the current implemen‐ >> tation, this field is always zero. >> >> data This is a seccomp_data structure containing infor‐ >> mation about the system call that triggered the >> notification. This is the same structure that is >> passed to the seccomp filter. See seccomp(2) for >> details of this structure. >> >> On success, this operation returns 0; on failure, -1 is >> returned, and errno is set to indicate the cause of the >> error. This operation can fail with the following errors: >> >> EINVAL (since Linux 5.5) >> The seccomp_notif structure that was passed to the >> call contained nonzero fields. >> >> ENOENT The target process was killed by a signal as the >> notification information was being generated. > > Not just killed, interruption with a signal handler has the same effect. Ah yes! Thanks. I added that as well. [[ ENOENT The target thread was killed by a signal as the notification information was being generated, or the target's (blocked) system call was interrupted by a signal handler. ]] Okay? >> ┌─────────────────────────────────────────────────────┐ >> │FIXME │ >> ├─────────────────────────────────────────────────────┤ >> │From my experiments, it appears that if a SEC‐ │ >> │COMP_IOCTL_NOTIF_RECV is done after the target │ >> │process terminates, then the ioctl() simply blocks │ >> │(rather than returning an error to indicate that the │ >> │target process no longer exists). │ >> │ │ >> │I found that surprising, and it required some con‐ │ >> │tortions in the example program. It was not possi‐ │ >> │ble to code my SIGCHLD handler (which reaps the zom‐ │ >> │bie when the worker/target process terminates) to │ >> │simply set a flag checked in the main handleNotifi‐ │ >> │cations() loop, since this created an unavoidable │ >> │race where the child might terminate just after I │ >> │had checked the flag, but before I blocked (for‐ │ >> │ever!) in the SECCOMP_IOCTL_NOTIF_RECV operation. │ >> │Instead, I had to code the signal handler to simply │ >> │call _exit(2) in order to terminate the parent │ >> │process (the supervisor). │ >> │ │ >> │Is this expected behavior? It seems to me rather │ >> │desirable that SECCOMP_IOCTL_NOTIF_RECV should give │ >> │an error if the target process has terminated. │ >> └─────────────────────────────────────────────────────┘ > > You could poll() the fd first. But yeah, it'd probably be a good idea > to change that. Ah! It was only after reading some comments from Christian that I realized how poll() works here. I'll make some additions to the page about the poll() details. (See my reply to Christian that should land at about the same time as this mail.) >> SECCOMP_IOCTL_NOTIF_ID_VALID > [...] >> In the above scenario, the risk is that the supervisor may >> try to access the memory of a process other than the tar‐ >> get. This race can be avoided by following the call to >> open with a SECCOMP_IOCTL_NOTIF_ID_VALID operation to ver‐ >> ify that the process that generated the notification is >> still alive. (Note that if the target process subse‐ >> quently terminates, its PID won't be reused because there > > That's wrong, the PID can be reused, but the /proc/$pid directory is > internally not associated with the numeric PID, but, conceptually > speaking, with a specific incarnation of the PID, or something like > that. (Actually, it is associated with the "struct pid", which is not > reused, instead of the numeric PID.) Thanks. I simplified the last sentence of the paragraph: In the above scenario, the risk is that the supervisor may try to access the memory of a process other than the tar‐ get. This race can be avoided by following the call to open(2) with a SECCOMP_IOCTL_NOTIF_ID_VALID operation to verify that the process that generated the notification is still alive. (Note that if the target terminates after the latter step, a subsequent read(2) from the file descriptor will return 0, indicating end of file.) I think that's probably enough detail. >> remains an open reference to the /proc[pid]/mem file; in >> this case, a subsequent read(2) from the file will return >> 0, indicating end of file.) >> >> On success (i.e., the notification ID is still valid), >> this operation returns 0 On failure (i.e., the notifica‐ > > nit: s/returns 0/returns 0./ Thanks. Fixed. >> tion ID is no longer valid), -1 is returned, and errno is >> set to ENOENT. >> >> SECCOMP_IOCTL_NOTIF_SEND > [...] >> Two kinds of response are possible: >> >> · A response to the kernel telling it to execute the tar‐ >> get process's system call. In this case, the flags >> field includes SECCOMP_USER_NOTIF_FLAG_CONTINUE and the >> error and val fields must be zero. >> >> This kind of response can be useful in cases where the >> supervisor needs to do deeper analysis of the target's >> system call than is possible from a seccomp filter >> (e.g., examining the values of pointer arguments), and, >> having verified that the system call is acceptable, the >> supervisor wants to allow it to proceed. > > "allow" sounds as if this is an access control thing, but this > mechanism should usually not be used for access control (unless the > "seccomp" syscall is blocked). Yes, Kees has also raised this point. > Maybe reword as "having decided that > the system call does not require emulation by the supervisor, the > supervisor wants it to execute normally", or something like that? Great! More suggested wordings! Thank you :-). I tweaked slightly: ... having decided that the system call does not require emulation by the supervisor, the supervisor wants the system call to be executed normally in the target. > [...] >> On success, this operation returns 0; on failure, -1 is >> returned, and errno is set to indicate the cause of the >> error. This operation can fail with the following errors: >> >> EINPROGRESS >> A response to this notification has already been >> sent. >> >> EINVAL An invalid value was specified in the flags field. >> >> EINVAL The flags field contained SEC‐ >> COMP_USER_NOTIF_FLAG_CONTINUE, and the error or val >> field was not zero. >> >> ENOENT The blocked system call in the target process has >> been interrupted by a signal handler. > > (you could also get this if a response has already been sent, instead > of EINPROGRESS - the only difference is whether the target thread has > picked up the response yet) Got it. I don't think I'll try to work that detail into the page (unless you really think I should, but since you made this a parenthetical comment, perhaps you don't think it's necessary). >> NOTES >> The file descriptor returned when seccomp(2) is employed with the >> SECCOMP_FILTER_FLAG_NEW_LISTENER flag can be monitored using >> poll(2), epoll(7), and select(2). When a notification is pend‐ >> ing, these interfaces indicate that the file descriptor is read‐ >> able. > > We should probably also point out somewhere that, as > include/uapi/linux/seccomp.h says: > > * Similar precautions should be applied when stacking SECCOMP_RET_USER_NOTIF > * or SECCOMP_RET_TRACE. For SECCOMP_RET_USER_NOTIF filters acting on the > * same syscall, the most recently added filter takes precedence. This means > * that the new SECCOMP_RET_USER_NOTIF filter can override any > * SECCOMP_IOCTL_NOTIF_SEND from earlier filters, essentially allowing all My takeaway from Chritian's comments is that this comment in the kernel source is partially wrong, since it is not possible to install multiple filters with SECCOMP_RET_USER_NOTIF, right? > * such filtered syscalls to be executed by sending the response > * SECCOMP_USER_NOTIF_FLAG_CONTINUE. Note that SECCOMP_RET_TRACE can equally > * be overriden by SECCOMP_USER_NOTIF_FLAG_CONTINUE. > > In other words, from a security perspective, you must assume that the > target process can bypass any SECCOMP_RET_USER_NOTIF (or > SECCOMP_RET_TRACE) filters unless it is completely prohibited from > calling seccomp(). Drawing on text from Chrstian's comment in seccomp.h and Kees's mail, I added the following in NOTES: Design goals; use of SECCOMP_USER_NOTIF_FLAG_CONTINUE The intent of the user-space notification feature is to allow sys‐ tem calls to be performed on behalf of the target. The target's system call should either be handled by the supervisor or allowed to continue normally in the kernel (where standard security poli‐ cies will be applied). Note well: this mechanism must not be used to make security policy decisions about the system call, which would be inherently race- prone for reasons described next. The SECCOMP_USER_NOTIF_FLAG_CONTINUE flag must be used with cau‐ tion. If set by the supervisor, the target's system call will continue. However, there is a time-of-check, time-of-use race here, since an attacker could exploit the interval of time where the target is blocked waiting on the "continue" response to do things such as rewriting the system call arguments. Note furthermore that a user-space notifier can be bypassed if the existing filters allow the use of seccomp(2) or prctl(2) to install a filter that returns an action value with a higher prece‐ dence than SECCOMP_RET_USER_NOTIF (see seccomp(2)). It should thus be absolutely clear that the seccomp user-space notification mechanism can not be used to implement a security policy! It should only ever be used in scenarios where a more privileged process supervises the system calls of a lesser privi‐ leged target to get around kernel-enforced security restrictions when the supervisor deems this safe. In other words, in order to continue a system call, the supervisor should be sure that another security mechanism or the kernel itself will sufficiently block the system call if its arguments are rewritten to something unsafe. Seem okay? > This should also be noted over in the main > seccomp(2) manpage, especially the SECCOMP_RET_TRACE part. I added some words in seccomp(2) to emphasize this. >> EXAMPLES > [...] >> This program can used to demonstrate various aspects of the > > nit: "can be used to demonstrate", or alternatively just "demonstrates" Thanks. Fixed (added "to") >> behavior of the seccomp user-space notification mechanism. To >> help aid such demonstrations, the program logs various messages >> to show the operation of the target process (lines prefixed "T:") >> and the supervisor (indented lines prefixed "S:"). > [...] >> Program source > [...] >> #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ >> } while (0) > > Don't we have err() for this? I tend to avoid the use of err() because it's a nonstandard BSDism. Perhaps by this point this is as much a habit as anything rational. >> /* Send the file descriptor 'fd' over the connected UNIX domain socket >> 'sockfd'. Returns 0 on success, or -1 on error. */ >> >> static int >> sendfd(int sockfd, int fd) >> { >> struct msghdr msgh; >> struct iovec iov; >> int data; >> struct cmsghdr *cmsgp; >> >> /* Allocate a char array of suitable size to hold the ancillary data. >> However, since this buffer is in reality a 'struct cmsghdr', use a >> union to ensure that it is suitable aligned. */ > > nit: suitably Thanks. Fixed. >> union { >> char buf[CMSG_SPACE(sizeof(int))]; >> /* Space large enough to hold an 'int' */ >> struct cmsghdr align; >> } controlMsg; >> >> /* The 'msg_name' field can be used to specify the address of the >> destination socket when sending a datagram. However, we do not >> need to use this field because 'sockfd' is a connected socket. */ >> >> msgh.msg_name = NULL; >> msgh.msg_namelen = 0; >> >> /* On Linux, we must transmit at least one byte of real data in >> order to send ancillary data. We transmit an arbitrary integer >> whose value is ignored by recvfd(). */ >> >> msgh.msg_iov = &iov; >> msgh.msg_iovlen = 1; >> iov.iov_base = &data; >> iov.iov_len = sizeof(int); >> data = 12345; >> >> /* Set 'msghdr' fields that describe ancillary data */ >> >> msgh.msg_control = controlMsg.buf; >> msgh.msg_controllen = sizeof(controlMsg.buf); >> >> /* Set up ancillary data describing file descriptor to send */ >> >> cmsgp = CMSG_FIRSTHDR(&msgh); >> cmsgp->cmsg_level = SOL_SOCKET; >> cmsgp->cmsg_type = SCM_RIGHTS; >> cmsgp->cmsg_len = CMSG_LEN(sizeof(int)); >> memcpy(CMSG_DATA(cmsgp), &fd, sizeof(int)); >> >> /* Send real plus ancillary data */ >> >> if (sendmsg(sockfd, &msgh, 0) == -1) >> return -1; >> >> return 0; >> } > > Instead of using unix domain sockets to send the fd to the parent, I > think you could also use clone3() with flags==CLONE_FILES|SIGCHLD, > dup2() the seccomp fd to an fd that was reserved in the parent, call > unshare(CLONE_FILES) in the child after setting up the seccomp fd, and > wake up the parent with something like pthread_cond_signal()? I'm not > sure whether that'd look better or worse in the end though, so maybe > just ignore this comment. Ahh -- nice. That answers in detail a question I also had for Tycho. I won't make any changes to the page (since I'm not sure it would look better), but I will add that detail in a comment in the page source. Perhaps I'll do something with that in the future. > [...] >> /* Access the memory of the target process in order to discover the >> pathname that was given to mkdir() */ >> >> static void >> getTargetPathname(struct seccomp_notif *req, int notifyFd, >> char *path, size_t len) >> { >> char procMemPath[PATH_MAX]; >> snprintf(procMemPath, sizeof(procMemPath), "/proc/%d/mem", req->pid); >> >> int procMemFd = open(procMemPath, O_RDONLY); > > Should example code like this maybe use O_CLOEXEC unless the fd in > question actually has to be inheritable? I know it doesn't actually > matter here, but if this code was used in a multi-threaded context, it > might. Yes, good point. I changed this. >> if (procMemFd == -1) >> errExit("Supervisor: open"); >> >> /* Check that the process whose info we are accessing is still alive. >> If the SECCOMP_IOCTL_NOTIF_ID_VALID operation (performed >> in checkNotificationIdIsValid()) succeeds, we know that the >> /proc/PID/mem file descriptor that we opened corresponds to the >> process for which we received a notification. If that process >> subsequently terminates, then read() on that file descriptor >> will return 0 (EOF). */ >> >> checkNotificationIdIsValid(notifyFd, req->id); >> >> /* Seek to the location containing the pathname argument (i.e., the >> first argument) of the mkdir(2) call and read that pathname */ >> >> if (lseek(procMemFd, req->data.args[0], SEEK_SET) == -1) >> errExit("Supervisor: lseek"); >> >> ssize_t s = read(procMemFd, path, PATH_MAX); >> if (s == -1) >> errExit("read"); > > Why not pread() instead of lseek()+read()? No good reason! I changed it to: /* Read bytes at the location containing the pathname argument (i.e., the first argument) of the mkdir(2) call */ ssize_t s = pread(procMemFd, path, PATH_MAX, req->data.args[0]); if (s == -1) errExit("pread"); if (s == 0) { fprintf(stderr, "\tS: pread() of /proc/PID/mem " "returned 0 (EOF)\n"); exit(EXIT_FAILURE); } Thanks! >> if (s == 0) { >> fprintf(stderr, "\tS: read() of /proc/PID/mem " >> "returned 0 (EOF)\n"); >> exit(EXIT_FAILURE); >> } >> >> if (close(procMemFd) == -1) >> errExit("close-/proc/PID/mem"); > > We should probably make sure here that the value we read is actually > NUL-terminated? So, I was curious about that point also. But, (why) are we not guaranteed that it will be NUL-terminated? >> } >> >> /* Handle notifications that arrive via the SECCOMP_RET_USER_NOTIF file >> descriptor, 'notifyFd'. */ >> >> static void >> handleNotifications(int notifyFd) >> { >> struct seccomp_notif_sizes sizes; >> char path[PATH_MAX]; >> /* For simplicity, we assume that the pathname given to mkdir() >> is no more than PATH_MAX bytes; but this might not be true. */ > > No, it has to be true, otherwise the kernel would fail the syscall if > it was executing normally. Yes. I removed that comment. >> /* Discover the sizes of the structures that are used to receive >> notifications and send notification responses, and allocate >> buffers of those sizes. */ >> >> if (seccomp(SECCOMP_GET_NOTIF_SIZES, 0, &sizes) == -1) >> errExit("\tS: seccomp-SECCOMP_GET_NOTIF_SIZES"); >> >> struct seccomp_notif *req = malloc(sizes.seccomp_notif); >> if (req == NULL) >> errExit("\tS: malloc"); >> >> struct seccomp_notif_resp *resp = malloc(sizes.seccomp_notif_resp); > > This should probably do something like max(sizes.seccomp_notif_resp, > sizeof(struct seccomp_notif_resp)) in case the program was built > against new UAPI headers that make struct seccomp_notif_resp big, but > is running under an old kernel where that struct is still smaller? I'm confused. Why? I mean, if the running kernel says that it expects a buffer of a certain size, and we allocate a buffer of that size, what's the problem? >> if (resp == NULL) >> errExit("\tS: malloc"); > [...] >> } else { >> >> /* If mkdir() failed in the supervisor, pass the error >> back to the target */ >> >> resp->error = -errno; >> printf("\tS: failure! (errno = %d; %s)\n", errno, >> strerror(errno)); >> } >> } else if (strncmp(path, "./", strlen("./")) == 0) { > > nit: indent messed up Thanks. Fixed. And thanks again for the detailed review, Jann. Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ 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 X-Spam-Level: X-Spam-Status: No, score=-5.8 required=3.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01602C433E7 for ; Thu, 15 Oct 2020 11:25:01 +0000 (UTC) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6354D20878 for ; Thu, 15 Oct 2020 11:25:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SLKdxK4x" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6354D20878 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=containers-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id B9C7C88609; Thu, 15 Oct 2020 11:24:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GPWSEqPq9T3V; Thu, 15 Oct 2020 11:24:53 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id C5385885E7; Thu, 15 Oct 2020 11:24:53 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BABC8C0052; Thu, 15 Oct 2020 11:24:53 +0000 (UTC) Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id A5FE4C1AD4 for ; Thu, 15 Oct 2020 11:24:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 83CF88827E for ; Thu, 15 Oct 2020 11:24:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id p_Tkvgqh5waU for ; Thu, 15 Oct 2020 11:24:49 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 196FF87D4D for ; Thu, 15 Oct 2020 11:24:49 +0000 (UTC) Received: by mail-wr1-f68.google.com with SMTP id s9so2968543wro.8 for ; Thu, 15 Oct 2020 04:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=+GsbYluG4u73BDHZLeU5QbT5MuUDYp+oqb/QiX1Syl0=; b=SLKdxK4xJ3f0UY65WuYDwOPmq8FiXCQsoHFIAEDjY/8fRXghl9pW/mmrLFle8mJ0Ea aWzOwGaLTbr05PdcAjHdASzr5w3A3mX1D3vyq4zXPQEistjoQmgPXDQUSwA2OAiyEtwv HstV4YdLQU5+/tQRVgJKpiKI23jjUegxDeAS4yVYGG5CgvLcSYVKFHE5GFEym292a5OL cwsGfPeWMrGzPsAdMCdjBG1XN+IvtfmJByG8QOpVp/bNrrHHpfDY4AsNbXtXq2luxE6v /HiB+9bhXRdNxn0R+wh9kPvNhKzNtvuUHUJ1NxpZKysLmqf8KbSDv7mzhpWu/4XIGpdG uVTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=+GsbYluG4u73BDHZLeU5QbT5MuUDYp+oqb/QiX1Syl0=; b=Uk28XlTXQsqzWTe9RPi5KoKTwc090Skf6YtlvsO8hVtvKAN0YniOmySIOlKvw76vCw mwJgs3kUuEfOCnGgormJSfzPAELyxQ0v299SA/v1lEcv4ojNk8I05sIZCoZD9aXMXKxl IzFDmJlwyqiYA7OTgJxw8mSIPsBMz29fmvkhivf1sKDwZk78EojgicgJw2xXFzcEnWHE Z4FF6sCNdJrixG2oMxjPa4l+nRvKUg7RXAVPowm90VdMsiOKwR/BynAEtYwDm+5DCNGM d3BbtRuHLZO67jIXmigXuMOE5yw9RxQFLiHtEqF61HVzjc/jd3R2cFuJpVJBiQ22q2NQ oF6g== X-Gm-Message-State: AOAM533YJ/Rdcld8V8KFLDLykHtGPphr0fNWUsOGdDjGALOkEbfhUK8y XBeIDic9YqOCTCxibSskEeU= X-Google-Smtp-Source: ABdhPJyLzb1oNdIf3dcQDnEybL8jAcn6eVv8vhtqU7+wnrvHk69L6GlDUHCHaX6ML2cLfRBMpXcwIQ== X-Received: by 2002:a05:6000:12c2:: with SMTP id l2mr3744783wrx.76.1602761086653; Thu, 15 Oct 2020 04:24:46 -0700 (PDT) Received: from [192.168.1.10] (static-176-175-73-29.ftth.abo.bbox.fr. [176.175.73.29]) by smtp.gmail.com with ESMTPSA id z191sm3999995wme.30.2020.10.15.04.24.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Oct 2020 04:24:45 -0700 (PDT) From: "Michael Kerrisk (man-pages)" Subject: Re: For review: seccomp_user_notif(2) manual page To: Jann Horn References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> Message-ID: <5647b94a-4693-dad0-6e0d-ed178b495d65@gmail.com> Date: Thu, 15 Oct 2020 13:24:44 +0200 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: Content-Language: en-US Cc: linux-man , Song Liu , Will Drewry , Kees Cook , Daniel Borkmann , Giuseppe Scrivano , Robert Sesek , Linux Containers , lkml , Alexei Starovoitov , mtk.manpages@gmail.com, bpf , Andy Lutomirski , Christian Brauner X-BeenThere: containers@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux Containers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: containers-bounces@lists.linux-foundation.org Sender: "Containers" SGkgSmFubiwKClNvLCBmaXJzdCBvZmYsIHRoYW5rIHlvdSBmb3IgdGhlIGRldGFpbGVkIHJldmll dy4gSSByZWFsbHkgCmFwcHJlY2lhdGUgaXQhIEkndmUgY2hhbmdlZCB2YXJpb3VzIHBpZWNlcywg YW5kIHN0aWxsIGhhdmUKYSBmZXcgcXVlc3Rpb25zIGJlbG93LgoKT24gOS8zMC8yMCA1OjUzIFBN LCBKYW5uIEhvcm4gd3JvdGU6Cj4gT24gV2VkLCBTZXAgMzAsIDIwMjAgYXQgMTowNyBQTSBNaWNo YWVsIEtlcnJpc2sgKG1hbi1wYWdlcykKPiA8bXRrLm1hbnBhZ2VzQGdtYWlsLmNvbT4gd3JvdGU6 Cj4+IEkga25ldyBpdCB3b3VsZCBiZSBhIGJpZyBhc2ssIGJ1dCBiZWxvdyBpcyBraW5kIG9mIHRo ZSBtYW51YWwgcGFnZQo+PiBJIHdhcyBob3BpbmcgeW91IG1pZ2h0IHdyaXRlIFsxXSBmb3IgdGhl IHNlY2NvbXAgdXNlci1zcGFjZSBub3RpZmljYXRpb24KPj4gbWVjaGFuaXNtLiBTaW5jZSB5b3Ug ZGlkbid0IChhbmQgYmVjYXVzZSA1LjkgYWRkcyB2YXJpb3VzIG5ldyBwaWVjZXMKPj4gc3VjaCBh cyBTRUNDT01QX0FEREZEX0ZMQUdfU0VURkQgYW5kIFNFQ0NPTVBfSU9DVExfTk9USUZfQURERkQK Pj4gdGhhdCBhbHNvIHdpbGwgbmVlZCBkb2N1bWVudGluZyBbMl0pLCBJIGRpZCA6LSkuIEJ1dCBv ZiBjb3Vyc2UgSSBtYXkKPj4gaGF2ZSBtYWRlIG1pc3Rha2VzLi4uCj4gWy4uLl0KPj4gTkFNRQo+ PiAgICAgICAgc2VjY29tcF91c2VyX25vdGlmIC0gU2VjY29tcCB1c2VyLXNwYWNlIG5vdGlmaWNh dGlvbiBtZWNoYW5pc20KPj4KPj4gU1lOT1BTSVMKPj4gICAgICAgICNpbmNsdWRlIDxsaW51eC9z ZWNjb21wLmg+Cj4+ICAgICAgICAjaW5jbHVkZSA8bGludXgvZmlsdGVyLmg+Cj4+ICAgICAgICAj aW5jbHVkZSA8bGludXgvYXVkaXQuaD4KPj4KPj4gICAgICAgIGludCBzZWNjb21wKHVuc2lnbmVk IGludCBvcGVyYXRpb24sIHVuc2lnbmVkIGludCBmbGFncywgdm9pZCAqYXJncyk7Cj4gCj4gU2hv dWxkIHRoZSBpb2N0bCgpIGNhbGxzIGJlIGxpc3RlZCBoZXJlLCBzaW1pbGFyIHRvIGUuZy4gdGhl IFNZTk9QU0lTCj4gb2YgdGhlIGlvY3RsXyogbWFucGFnZXM/CgpZZXMsIGdvb2QgaWRlYS4gSSBh ZGRlZDoKCiAgICAgICBpbnQgaW9jdGwoaW50IGZkLCBTRUNDT01QX0lPQ1RMX05PVElGX1JFQ1Ys CiAgICAgICAgICAgICAgICAgc3RydWN0IHNlY2NvbXBfbm90aWYgKnJlcSk7CiAgICAgICBpbnQg aW9jdGwoaW50IGZkLCBTRUNDT01QX0lPQ1RMX05PVElGX1NFTkQsCiAgICAgICAgICAgICAgICAg c3RydWN0IHNlY2NvbXBfbm90aWZfcmVzcCAqcmVxKTsKICAgICAgIGludCBpb2N0bChpbnQgZmQs IFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFMSUQsIF9fdTY0ICppZCk7Cj4gCj4+IERFU0NSSVBU SU9OCj4+ICAgICAgICBUaGlzICBwYWdlICBkZXNjcmliZXMgIHRoZSB1c2VyLXNwYWNlIG5vdGlm aWNhdGlvbiBtZWNoYW5pc20gcHJv4oCQCj4+ICAgICAgICB2aWRlZCBieSB0aGUgU2VjdXJlIENv bXB1dGluZyAoc2VjY29tcCkgZmFjaWxpdHkuICBBcyB3ZWxsIGFzIHRoZQo+PiAgICAgICAgdXNl ICAgb2YgIHRoZSAgU0VDQ09NUF9GSUxURVJfRkxBR19ORVdfTElTVEVORVIgIGZsYWcsICB0aGUg IFNFQ+KAkAo+PiAgICAgICAgQ09NUF9SRVRfVVNFUl9OT1RJRiBhY3Rpb24gdmFsdWUsIGFuZCB0 aGUgU0VDQ09NUF9HRVRfTk9USUZfU0laRVMKPj4gICAgICAgIG9wZXJhdGlvbiAgZGVzY3JpYmVk ICBpbiAgc2VjY29tcCgyKSwgdGhpcyBtZWNoYW5pc20gaW52b2x2ZXMgdGhlCj4+ICAgICAgICB1 c2Ugb2YgYSBudW1iZXIgb2YgcmVsYXRlZCBpb2N0bCgyKSBvcGVyYXRpb25zIChkZXNjcmliZWQg YmVsb3cpLgo+Pgo+PiAgICBPdmVydmlldwo+PiAgICAgICAgSW4gY29udmVudGlvbmFsIHVzYWdl IG9mIGEgc2VjY29tcCBmaWx0ZXIsIHRoZSBkZWNpc2lvbiBhYm91dCBob3cKPj4gICAgICAgIHRv ICB0cmVhdCAgYSBwYXJ0aWN1bGFyIHN5c3RlbSBjYWxsIGlzIG1hZGUgYnkgdGhlIGZpbHRlciBp dHNlbGYuCj4+ICAgICAgICBUaGUgdXNlci1zcGFjZSBub3RpZmljYXRpb24gbWVjaGFuaXNtIGFs bG93cyB0aGUgaGFuZGxpbmcgb2YgIHRoZQo+PiAgICAgICAgc3lzdGVtICBjYWxsICB0byAgaW5z dGVhZCAgYmUgaGFuZGVkIG9mZiB0byBhIHVzZXItc3BhY2UgcHJvY2Vzcy4KPj4gICAgICAgIFRo ZSBhZHZhbnRhZ2VzIG9mIGRvaW5nIHRoaXMgYXJlIHRoYXQsIGJ5IGNvbnRyYXN0IHdpdGggdGhl ICBzZWPigJAKPj4gICAgICAgIGNvbXAgIGZpbHRlciwgIHdoaWNoICBpcyAgcnVubmluZyBvbiBh IHZpcnR1YWwgbWFjaGluZSBpbnNpZGUgdGhlCj4+ICAgICAgICBrZXJuZWwsIHRoZSB1c2VyLXNw YWNlIHByb2Nlc3MgaGFzIGFjY2VzcyB0byBpbmZvcm1hdGlvbiB0aGF0ICBpcwo+PiAgICAgICAg dW5hdmFpbGFibGUgdG8gdGhlIHNlY2NvbXAgZmlsdGVyIGFuZCBpdCBjYW4gcGVyZm9ybSBhY3Rp b25zIHRoYXQKPj4gICAgICAgIGNhbid0IGJlIHBlcmZvcm1lZCBmcm9tIHRoZSBzZWNjb21wIGZp bHRlci4KPj4KPj4gICAgICAgIEluIHRoZSBkaXNjdXNzaW9uIHRoYXQgZm9sbG93cywgdGhlIHBy b2Nlc3MgIHRoYXQgIGhhcyAgaW5zdGFsbGVkCj4+ICAgICAgICB0aGUgIHNlY2NvbXAgZmlsdGVy IGlzIHJlZmVycmVkIHRvIGFzIHRoZSB0YXJnZXQsIGFuZCB0aGUgcHJvY2Vzcwo+IAo+IFRlY2hu aWNhbGx5LCB0aGlzIGRlZmluaXRpb24gb2YgInRhcmdldCIgaXMgYSBiaXQgaW5hY2N1cmF0ZSBi ZWNhdXNlOgo+IAo+ICAtIHNlY2NvbXAgZmlsdGVycyBhcmUgaW5oZXJpdGVkCj4gIC0gc2VjY29t cCBmaWx0ZXJzIGFwcGx5IHRvIHRocmVhZHMsIG5vdCBwcm9jZXNzZXMKPiAgLSBzZWNjb21wIGZp bHRlcnMgY2FuIGJlIHNlbWktcmVtb3RlbHkgaW5zdGFsbGVkIHZpYSBUU1lOQwoKKE5pY2Ugc3Vt bWFyeS4pCgo+IChJIGFzc3VtZSB0aGF0IGluIG1hbnBhZ2VzLCB3ZSBzaG91bGQgdHJ5IHRvIGdv IGZvciB0aGUgImEgdGFzayBpcyBhCj4gdGhyZWFkIGFuZCBhIHRocmVhZCBncm91cCBpcyBhIHBy b2Nlc3MiIGRlZmluaXRpb24sIHJpZ2h0PykKCkV4YWN0bHkuCgo+IFBlcmhhcHMgInRoZSB0aHJl YWRzIG9uIHdoaWNoIHRoZSBzZWNjb21wIGZpbHRlciBpcyBpbnN0YWxsZWQgYXJlCj4gcmVmZXJy ZWQgdG8gYXMgdGhlIHRhcmdldCIsIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQgd291bGQgYmUgYmV0 dGVyPwoKVGhhbmtzLiBJdCdzIGFsd2F5cyBodWdlbHkgaGVscGZ1bCB0byBnZXQgYSBzdWdnZXN0 ZWQgd29yZGluZywgZXZlbgppZiBJIHN0aWxsIGZlZWwgdGhlIG5lZWQgdG8gcmV3b3JrIGl0ICh3 aGljaCBJIGRvbid0IGluIHRoaXMgY2FzZSkuClRoZSBzZW50ZW5jZSBub3cgcmVhZHM6CgogICAg ICAgSW4gdGhlIGRpc2N1c3Npb24gdGhhdCBmb2xsb3dzLCB0aGUgdGhyZWFkKHMpIG9uIHdoaWNo IHRoZSBzZWNjb21wCiAgICAgICBmaWx0ZXIgaXMgaW5zdGFsbGVkIGFyZSByZWZlcnJlZCB0byBh cyB0aGUgdGFyZ2V0LCBhbmQgdGhlIHByb2Nlc3MKICAgICAgIHRoYXQgaXMgbm90aWZpZWQgIGJ5 ICB0aGUgIHVzZXItc3BhY2UgIG5vdGlmaWNhdGlvbiAgbWVjaGFuaXNtICBpcwogICAgICAgcmVm ZXJyZWQgdG8gYXMgdGhlIHN1cGVydmlzb3IuCgo+PiAgICAgICAgdGhhdCBpcyBub3RpZmllZCBi eSAgdGhlICB1c2VyLXNwYWNlICBub3RpZmljYXRpb24gIG1lY2hhbmlzbSAgaXMKPj4gICAgICAg IHJlZmVycmVkICB0byAgYXMgIHRoZSAgc3VwZXJ2aXNvci4gIEFuIG92ZXJ2aWV3IG9mIHRoZSBz dGVwcyBwZXLigJAKPj4gICAgICAgIGZvcm1lZCBieSB0aGVzZSB0d28gcHJvY2Vzc2VzIGlzIGFz IGZvbGxvd3M6Cj4+Cj4+ICAgICAgICAxLiBUaGUgdGFyZ2V0IHByb2Nlc3MgZXN0YWJsaXNoZXMg YSBzZWNjb21wIGZpbHRlciBpbiAgdGhlICB1c3VhbAo+PiAgICAgICAgICAgbWFubmVyLCBidXQg d2l0aCB0d28gZGlmZmVyZW5jZXM6Cj4+Cj4+ICAgICAgICAgICDCtyBUaGUgc2VjY29tcCgyKSBm bGFncyBhcmd1bWVudCBpbmNsdWRlcyB0aGUgZmxhZyBTRUNDT01QX0ZJTOKAkAo+PiAgICAgICAg ICAgICBURVJfRkxBR19ORVdfTElTVEVORVIuICBDb25zZXF1ZW50bHksIHRoZSByZXR1cm4gIHZh bHVlICAgb2YKPj4gICAgICAgICAgICAgdGhlICAoc3VjY2Vzc2Z1bCkgIHNlY2NvbXAoMikgY2Fs bCBpcyBhIG5ldyAibGlzdGVuaW5nIiBmaWxlCj4+ICAgICAgICAgICAgIGRlc2NyaXB0b3IgdGhh dCBjYW4gYmUgdXNlZCB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMuCj4+Cj4+ICAgICAgICAgICDC tyBJbiBjYXNlcyB3aGVyZSBpdCBpcyBhcHByb3ByaWF0ZSwgdGhlIHNlY2NvbXAgZmlsdGVyIHJl dHVybnMKPj4gICAgICAgICAgICAgdGhlICBhY3Rpb24gdmFsdWUgU0VDQ09NUF9SRVRfVVNFUl9O T1RJRi4gIFRoaXMgcmV0dXJuIHZhbHVlCj4+ICAgICAgICAgICAgIHdpbGwgdHJpZ2dlciBhIG5v dGlmaWNhdGlvbiBldmVudC4KPj4KPj4gICAgICAgIDIuIEluIG9yZGVyIHRoYXQgdGhlIHN1cGVy dmlzb3IgcHJvY2VzcyBjYW4gb2J0YWluICBub3RpZmljYXRpb25zCj4+ICAgICAgICAgICB1c2lu ZyAgdGhlICBsaXN0ZW5pbmcgIGZpbGUgIGRlc2NyaXB0b3IsIChhIGR1cGxpY2F0ZSBvZikgdGhh dAo+PiAgICAgICAgICAgZmlsZSBkZXNjcmlwdG9yIG11c3QgYmUgcGFzc2VkIGZyb20gdGhlIHRh cmdldCBwcm9jZXNzIHRvICB0aGUKPj4gICAgICAgICAgIHN1cGVydmlzb3IgcHJvY2Vzcy4gIE9u ZSB3YXkgaW4gd2hpY2ggdGhpcyBjb3VsZCBiZSBkb25lIGlzIGJ5Cj4+ICAgICAgICAgICBwYXNz aW5nIHRoZSBmaWxlIGRlc2NyaXB0b3Igb3ZlciBhIFVOSVggZG9tYWluIHNvY2tldCAgY29ubmVj 4oCQCj4+ICAgICAgICAgICB0aW9uIGJldHdlZW4gdGhlIHR3byBwcm9jZXNzZXMgKHVzaW5nIHRo ZSBTQ01fUklHSFRTIGFuY2lsbGFyeQo+PiAgICAgICAgICAgbWVzc2FnZSB0eXBlIGRlc2NyaWJl ZCBpbiB1bml4KDcpKS4gICBBbm90aGVyICBwb3NzaWJpbGl0eSAgaXMKPj4gICAgICAgICAgIHRo YXQgIHRoZSAgc3VwZXJ2aXNvciAgbWlnaHQgIGluaGVyaXQgIHRoZSBmaWxlIGRlc2NyaXB0b3Ig dmlhCj4+ICAgICAgICAgICBmb3JrKDIpLgo+IAo+IFdpdGggdGhlIGNhdmVhdCB0aGF0IGlmIHRo ZSBzdXBlcnZpc29yIGluaGVyaXRzIHRoZSBmaWxlIGRlc2NyaXB0b3IKPiB2aWEgZm9yaygpLCB0 aGF0IChtb3JlIG9yIGxlc3MpIGltcGxpZXMgdGhhdCB0aGUgc3VwZXJ2aXNvciBpcyBzdWJqZWN0 Cj4gdG8gdGhlIHNhbWUgZmlsdGVyIChhbHRob3VnaCBpdCBjb3VsZCBieXBhc3MgdGhlIGZpbHRl ciB1c2luZyBhIGhlbHBlcgo+IHRocmVhZCB0aGF0IHJlc3BvbmRzIFNFQ0NPTVBfVVNFUl9OT1RJ Rl9GTEFHX0NPTlRJTlVFLCBidXQgSSBkb24ndAo+IGV4cGVjdCBhbnkgY2xlYW4gc29mdHdhcmUg dG8gZG8gdGhhdCkuCgpJdCdzIGEgZ29vZCB0aGluZyBubyBvbmUgZXZlciB3cml0ZXMgdW5jbGVh biBzb2Z0d2FyZS4uLgoKVGhhbmtzIGZvciBjYXRjaGluZyB0aGlzOyBUeWNobyBkaWQgYWxzby4g SXQgd2FzIGEgdGhpbmtvIG9uIG15IHBhcnQKdG8gZm9yZ2V0IHRoYXQgaWYgb25lIHVzZWQgZm9y aygpLCB0aGUgc3VwZXJ2aXNvciB3b3VsZCBpbmhlcml0IHRoZQpmaWx0ZXIuIEkndmUgc2ltcGx5 IHJlbW92ZWQgdGhlIHNlbnRlbmNlIG1lbnRpb25pbmcgZm9yaygpLgoKCj4+ICAgICAgICAzLiBU aGUgc3VwZXJ2aXNvciBwcm9jZXNzIHdpbGwgcmVjZWl2ZSBub3RpZmljYXRpb24gZXZlbnRzIG9u IHRoZQo+PiAgICAgICAgICAgbGlzdGVuaW5nICBmaWxlICBkZXNjcmlwdG9yLiAgIFRoZXNlICBl dmVudHMgIGFyZSAgcmV0dXJuZWQgYXMKPj4gICAgICAgICAgIHN0cnVjdHVyZXMgb2YgdHlwZSBz ZWNjb21wX25vdGlmLiAgQmVjYXVzZSB0aGlzIHN0cnVjdHVyZSAgYW5kCj4+ICAgICAgICAgICBp dHMgIHNpemUgbWF5IGV2b2x2ZSBvdmVyIGtlcm5lbCB2ZXJzaW9ucywgdGhlIHN1cGVydmlzb3Ig bXVzdAo+PiAgICAgICAgICAgZmlyc3QgZGV0ZXJtaW5lIHRoZSBzaXplIG9mICB0aGlzICBzdHJ1 Y3R1cmUgIHVzaW5nICB0aGUgIHNlY+KAkAo+PiAgICAgICAgICAgY29tcCgyKSAgU0VDQ09NUF9H RVRfTk9USUZfU0laRVMgIG9wZXJhdGlvbiwgIHdoaWNoICByZXR1cm5zIGEKPj4gICAgICAgICAg IHN0cnVjdHVyZSBvZiB0eXBlIHNlY2NvbXBfbm90aWZfc2l6ZXMuICBUaGUgIHN1cGVydmlzb3Ig IGFsbG/igJAKPj4gICAgICAgICAgIGNhdGVzIGEgYnVmZmVyIG9mIHNpemUgc2VjY29tcF9ub3Rp Zl9zaXplcy5zZWNjb21wX25vdGlmIGJ5dGVzCj4+ICAgICAgICAgICB0byByZWNlaXZlIG5vdGlm aWNhdGlvbiBldmVudHMuICAgSW4gIGFkZGl0aW9uLHRoZSAgc3VwZXJ2aXNvcgo+PiAgICAgICAg ICAgYWxsb2NhdGVzICBhbm90aGVyICBidWZmZXIgIG9mICBzaXplICBzZWNjb21wX25vdGlmX3Np emVzLnNlY+KAkAo+PiAgICAgICAgICAgY29tcF9ub3RpZl9yZXNwICBieXRlcyAgZm9yICB0aGUg IHJlc3BvbnNlICAoYSAgIHN0cnVjdCAgIHNlY+KAkAo+PiAgICAgICAgICAgY29tcF9ub3RpZl9y ZXNwICBzdHJ1Y3R1cmUpIHRoYXQgaXQgd2lsbCBwcm92aWRlIHRvIHRoZSBrZXJuZWwKPj4gICAg ICAgICAgIChhbmQgdGh1cyB0aGUgdGFyZ2V0IHByb2Nlc3MpLgo+Pgo+PiAgICAgICAgNC4gVGhl IHRhcmdldCBwcm9jZXNzIHRoZW4gcGVyZm9ybXMgaXRzIHdvcmtsb2FkLCB3aGljaCAgaW5jbHVk ZXMKPj4gICAgICAgICAgIHN5c3RlbSAgY2FsbHMgIHRoYXQgIHdpbGwgYmUgY29udHJvbGxlZCBi eSB0aGUgc2VjY29tcCBmaWx0ZXIuCj4+ICAgICAgICAgICBXaGVuZXZlciBvbmUgb2YgdGhlc2Ug c3lzdGVtIGNhbGxzIGNhdXNlcyB0aGUgZmlsdGVyIHRvIHJldHVybgo+PiAgICAgICAgICAgdGhl ICBTRUNDT01QX1JFVF9VU0VSX05PVElGICBhY3Rpb24gdmFsdWUsIHRoZSBrZXJuZWwgZG9lcyBu b3QKPj4gICAgICAgICAgIGV4ZWN1dGUgdGhlIHN5c3RlbSBjYWxsOyAgaW5zdGVhZCwgIGV4ZWN1 dGlvbiAgb2YgIHRoZSAgdGFyZ2V0Cj4+ICAgICAgICAgICBwcm9jZXNzIGlzIHRlbXBvcmFyaWx5 IGJsb2NrZWQgaW5zaWRlIHRoZSBrZXJuZWwgYW5kIGEgbm90aWZp4oCQCj4gCj4gd2hlcmUgImJs b2NrZWQiIHJlZmVycyB0byB0aGUgaW50ZXJydXB0aWJsZSwgcmVzdGFydGFibGUga2luZCAtIGlm IHRoZQo+IGNoaWxkIHJlY2VpdmVzIGEgc2lnbmFsIHdpdGggYW4gU0FfUkVTVEFSVCBzaWduYWwg aGFuZGxlciBpbiB0aGUKPiBtZWFudGltZSwgaXQnbGwgbGVhdmUgdGhlIHN5c2NhbGwsIGdvIHRo cm91Z2ggdGhlIHNpZ25hbCBoYW5kbGVyLCB0aGVuCj4gcmVzdGFydCB0aGUgc3lzY2FsbCBhZ2Fp biBhbmQgc2VuZCB0aGUgc2FtZSByZXF1ZXN0IHRvIHRoZSBzdXBlcnZpc29yCj4gYWdhaW4uIHNv IHRoZSBzdXBlcnZpc29yIG1heSBzZWUgZHVwbGljYXRlIHN5c2NhbGxzLgoKU28sIEkgcGFydGlh bGx5IGRlbW9uc3RyYXRlZCB3aGF0IHlvdSBkZXNjcmliZSBoZXJlLCBmb3IgdHdvIGV4YW1wbGUK c3lzdGVtIGNhbGxzIChlcG9sbF93YWl0KCkgYW5kIHBhdXNlKCkpLiBCdXQgSSBjb3VsZCBub3Qg ZXhhY3RseSAKZGVtb25zdHJhdGUgdGhpbmdzIGFzIEkgdW5kZXJzdGFuZCB5b3UgdG8gYmUgZGVz Y3JpYmluZyB0aGVtLiAoU28sCkknbSBub3Qgc3VyZSB3aGV0aGVyIEkgaGF2ZSBub3QgdW5kZXJz dG9vZCB5b3UgY29ycmVjdGx5LCBvcgppZiB0aGluZ3MgYXJlIG5vdCBleGFjdGx5IGFzIHlvdSBk ZXNjcmliZSB0aGVtLikKCkhlcmUncyBhIHNjZW5hcmlvIChBKSB0aGF0IEkgdGVzdGVkOgoKMS4g VGFyZ2V0IGluc3RhbGxzIHNlY2NvbXAgZmlsdGVycyBmb3IgYSBibG9ja2luZyBzeXNjYWxsCiAg IChlcG9sbF93YWl0KCkgb3IgcGF1c2UoKSwgYm90aCBvZiB3aGljaCBzaG91bGQgbmV2ZXIgcmVz dGFydCwKICAgcmVnYXJkbGVzcyBvZiBTQV9SRVNUQVJUKQoyLiBUYXJnZXQgaW5zdGFsbHMgU0lH SU5UIGhhbmRsZXIgd2l0aCBTQV9SRVNUQVJUCjMuIFN1cGVydmlzb3IgaXMgc2xlZXBpbmcgKGku ZS4sIGlzIG5vdCBibG9ja2VkIGluCiAgIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViBvcGVyYXRp b24pLgo0LiBUYXJnZXQgbWFrZXMgYSBibG9ja2luZyBzeXN0ZW0gY2FsbCAoZXBvbGxfd2FpdCgp IG9yIHBhdXNlKCkpLgo1LiBTSUdJTlQgZ2V0cyBkZWxpdmVyZWQgdG8gdGFyZ2V0OyBoYW5kbGVy IGdldHMgY2FsbGVkOwogICAqKiphbmQgc3lzY2FsbCBnZXRzIHJlc3RhcnRlZCBieSB0aGUga2Vy bmVsKioqCgpUaGF0IGxhc3Qgc2hvdWxkIG5ldmVyIGhhcHBlbiwgb2YgY291cnNlLCBhbmQgaXMg YSByZXN1bHQgb2YgdGhlCmNvbWJpbmF0aW9uIG9mIGJvdGggdGhlIHVzZXItbm90aWZ5IGZpbHRl ciBhbmQgdGhlIFNBX1JFU1RBUlQgZmxhZy4KSWYgb25lIG9yIG90aGVyIGlzIG5vdCBwcmVzZW50 LCB0aGVuIHRoZSBzeXN0ZW0gY2FsbCBpcyBub3QKcmVzdGFydGVkLgoKU28sIGFzIHlvdSBub3Rl IGJlbG93LCB0aGUgVUFQSSBnZXRzIGJyb2tlbiBhIGxpdHRsZS4KCkhvd2V2ZXIsIGZyb20geW91 ciBkZXNjcmlwdGlvbiBhYm92ZSBJIGhhZCB1bmRlcnN0b29kIHRoYXQgCnNvbWV0aGluZyBsaWtl IHRoZSBmb2xsb3dpbmcgc2NlbmFyaW8gKEIpIGNvdWxkIG9jY3VyOgoKMS4gVGFyZ2V0IGluc3Rh bGxzIHNlY2NvbXAgZmlsdGVycyBmb3IgYSBibG9ja2luZyBzeXNjYWxsCiAgIChlcG9sbF93YWl0 KCkgb3IgcGF1c2UoKSwgYm90aCBvZiB3aGljaCBzaG91bGQgbmV2ZXIgcmVzdGFydCwKICAgcmVn YXJkbGVzcyBvZiBTQV9SRVNUQVJUKQoyLiBUYXJnZXQgaW5zdGFsbHMgU0lHSU5UIGhhbmRsZXIg d2l0aCBTQV9SRVNUQVJUCjMuIFN1cGVydmlzb3IgcGVyZm9ybXMgU0VDQ09NUF9JT0NUTF9OT1RJ Rl9SRUNWIG9wZXJhdGlvbiAod2hpY2gKICAgYmxvY2tzKS4KNC4gVGFyZ2V0IG1ha2VzIGEgYmxv Y2tpbmcgc3lzdGVtIGNhbGwgKGVwb2xsX3dhaXQoKSBvciBwYXVzZSgpKS4KNS4gU3VwZXJ2aXNv ciBnZXRzIHNlY2NvbXAgdXNlci1zcGFjZSBub3RpZmljYXRpb24gKGkuZS4sCiAgIFNFQ0NPTVBf SU9DVExfTk9USUZfUkVDViBpb2N0bCgpIHJldHVybnMKNi4gU0lHSU5UIGdldHMgZGVsaXZlcmVk IHRvIHRhcmdldDsgaGFuZGxlciBnZXRzIGNhbGxlZDsKICAgYW5kIHN5c2NhbGwgZ2V0cyByZXN0 YXJ0ZWQgYnkgdGhlIGtlcm5lbAo3LiBTdXBlcnZpc29yIHBlcmZvcm1zIGFub3RoZXIgU0VDQ09N UF9JT0NUTF9OT1RJRl9SRUNWIG9wZXJhdGlvbgogICB3aGljaCBnZXRzIGFub3RoZXIgbm90aWZp Y2F0aW9uIGZvciB0aGUgcmVzdGFydGVkIHN5c3RlbSBjYWxsLgoKSG93ZXZlciwgSSBkb24ndCBv YnNlcnZlIHN1Y2ggYmVoYXZpb3IuIEluIHN0ZXAgNiwgdGhlIHN5c2NhbGwKZG9lcyBub3QgZ2V0 IHJlc3RhcnRlZCBieSB0aGUga2VybmVsLCBidXQgaW5zdGVhZCByZXR1cm5zIC0xL0VJTlRSLgpQ ZXJoYXBzIEkgaGF2ZSBtaXNjb25zdHJ1Y3RlZCBteSBleHBlcmltZW50IGluIHRoZSBzZWNvbmQg Y2FzZSwgb3IKcGVyaGFwcyBJJ3ZlIG1pc3VuZGVyc3Rvb2Qgd2hhdCB5b3UgbWVhbnQsIG9yIGlz IGl0IHBvc3NpYmx5IHRoZQpjYXNlIHRoYXQgdGhpbmdzIGFyZSBub3QgcXVpdGUgYXMgeW91IHNh aWQ/Cgo+IFdoYXQncyByZWFsbHkgZ3Jvc3MgaGVyZSBpcyB0aGF0IHNpZ25hbCg3KSBwcm9taXNl cyB0aGF0IHNvbWUgc3lzY2FsbHMKPiBsaWtlIGVwb2xsX3dhaXQoMikgbmV2ZXIgcmVzdGFydCwg YnV0IHNlY2NvbXAgZG9lc24ndCBrbm93IGFib3V0IHRoYXQ7Cj4gaWYgdXNlcnNwYWNlIGluc3Rh bGxzIGEgZmlsdGVyIHRoYXQgdXNlcyBTRUNDT01QX1JFVF9VU0VSX05PVElGIGZvciBhCj4gbm9u LXJlc3RhcnRhYmxlIHN5c2NhbGwsIHRoZSByZXN1bHQgaXMgdGhhdCBVQVBJIGdldHMgYnJva2Vu IGEgbGl0dGxlCj4gYml0LiBMdWNraWx5IG5vcm1hbCB1c2VycyBvZiBzZWNjb21wIHByb2JhYmx5 IHdvbid0IHVzZQo+IFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgZm9yIHJlc3RhcnRhYmxlIHN5c2Nh bGxzLCBidXQgaWYgc29tZW9uZSBkb2VzCj4gd2FudCB0byBkbyB0aGF0LCB3ZSBtaWdodCBoYXZl IHRvIGFkZCBzb21lICJzdXBwcmVzcyBzeXNjYWxsCj4gcmVzdGFydGluZyIgZmxhZyBpbnRvIHRo ZSBzZWNjb21wIGFjdGlvbiB2YWx1ZSwgb3Igc29tZXRoaW5nIGxpa2UKPiB0aGF0Li4uIHl1Y2su CgpZZXMsIHRoZSBVQVBJIGJyZWFrYWdlIGlzIGEgYml0IHNhZCAoYWx0aG91Z2gsIGxpa2VseSB0 byBiZSByYXJlbHkKZW5jb3VudGVyZWQsIGFzIHlvdSBub3RlKS4gSSdtIGluY2xpbmVkIHRvIGFk ZCBhIG5vdGUgYWJvdXQgdGhpcyBpbgppbiBCVUdTLCBidXQgYmVmb3JlaGFuZCBJJ20gaW50ZXJl c3RlZCBpbiBoZWFyaW5nIHlvdXIgdGhvdWdodHMgb24Kc2NlbmFyaW8gQiBhYm92ZS4KCj4+ICAg ICAgICAgICBjYXRpb24gZXZlbnQgaXMgZ2VuZXJhdGVkIG9uIHRoZSBsaXN0ZW5pbmcgZmlsZSBk ZXNjcmlwdG9yLgo+Pgo+PiAgICAgICAgNS4gVGhlIHN1cGVydmlzb3IgcHJvY2VzcyBjYW4gbm93 IHJlcGVhdGVkbHkgbW9uaXRvciB0aGUgIGxpc3RlbuKAkAo+PiAgICAgICAgICAgaW5nICAgZmls ZSAgIGRlc2NyaXB0b3IgIGZvciAgU0VDQ09NUF9SRVRfVVNFUl9OT1RJRi10cmlnZ2VyZWQKPj4g ICAgICAgICAgIGV2ZW50cy4gICBUbyAgZG8gIHRoaXMsICAgdGhlICAgc3VwZXJ2aXNvciAgIHVz ZXMgICB0aGUgICBTRUPigJAKPj4gICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfUkVDViAgaW9j dGwoMikgIG9wZXJhdGlvbiB0byByZWFkIGluZm9ybWF0aW9uCj4+ICAgICAgICAgICBhYm91dCBh IG5vdGlmaWNhdGlvbiBldmVudDsgdGhpcyAgb3BlcmF0aW9uICBibG9ja3MgIHVudGlsICBhbgo+ IAo+IChpbnRlcnJ1cHRhYmx5IC0gYnV0IEkgZ3Vlc3MgdGhhdCBtYXliZSBkb2Vzbid0IGhhdmUg dG8gYmUgc2FpZAo+IGV4cGxpY2l0bHkgaGVyZT8pCgpZZXMsIEkgdGhpbmsgc28uIFRoZSBnZW5l cmFsIGFzc3VtcHRpb24gaXMgdGhhdCBzeXNjYWxscyBibG9jawppbnRlcnJ1cHRpYmx5LCB1bmxl c3MgdGV4dCBpbiBhIG1hbnVhbCBwYWdlIHRoYXQgc2F5cwoidW5pbnRlcnJ1cHRpYmxlIi4gKFBv c3RzY3JpcHQ6IENocmlzdGlhbiBtYWRlIGEgc2ltaWxhciBjb21tZW50LApzbyBJIGRlY2lkZWQg dG8gZXhwbGljaXRseSBub3RlIHRoYXQgaXQncyBhbiBpbnRlcnJ1cHRpYmxlIHNsZWVwLikKCj4+ ICAgICAgICAgICBldmVudCAgaXMgIGF2YWlsYWJsZS4KPiAKPiBNYXliZSB3ZSBzaG91bGQgbm90 ZSBoZXJlIHRoYXQgeW91IGNhbiB1c2UgdGhlIG11bHRpLWZkLXBvbGxpbmcgQVBJcwo+IChzZWxl Y3QvcG9sbC9lcG9sbCkgaW5zdGVhZCwgYW5kIHRoYXQgaWYgdGhlIG5vdGlmaWNhdGlvbiBnb2Vz IGF3YXkKPiBiZWZvcmUgeW91IGNhbGwgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWLCB0aGUgaW9j dGwgd2lsbCByZXR1cm4KPiAtRU5PRU5UIGluc3RlYWQgb2YgYmxvY2tpbmcsIGFuZCB0aGVyZWZv cmUgYXMgbG9uZyBhcyBub2JvZHkgZWxzZQo+IHJlYWRzIGZyb20gdGhlIHNhbWUgZmQsIHlvdSBj YW4gYXNzdW1lIHRoYXQgYWZ0ZXIgdGhlIGZkIHJlcG9ydHMgYXMKPiByZWFkYWJsZSwgeW91IGNh biBjYWxsIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViBvbmNlIHdpdGhvdXQgYmxvY2tpbmcuCgpJ J2QgcmF0aGVyIG5vdCBhZGQgdGhpcyBpbmZvIGluIHRoZSBvdmVydmlldyBzZWN0aW9uLCB3aGlj aCBpcwphbHJlYWR5IGxvbmdlciB0aGFuIEkgd291bGQgbGlrZS4gQnV0IEkgZGlkIGFkZCBzb21l IGRldGFpbHMKaW4gTk9URVM6CgpbWwogICAgICAgVGhlIGZpbGUgZGVzY3JpcHRvciByZXR1cm5l ZCB3aGVuIHNlY2NvbXAoMikgaXMgZW1wbG95ZWQgd2l0aCAgdGhlCiAgICAgICBTRUNDT01QX0ZJ TFRFUl9GTEFHX05FV19MSVNURU5FUiAgIGZsYWcgIGNhbiAgYmUgIG1vbml0b3JlZCAgdXNpbmcK ICAgICAgIHBvbGwoMiksIGVwb2xsKDcpLCBhbmQgc2VsZWN0KDIpLiAgV2hlbiBhIG5vdGlmaWNh dGlvbiBpcyBwZW5kaW5nLAogICAgICAgdGhlc2UgIGludGVyZmFjZXMgIGluZGljYXRlICB0aGF0 IHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgcmVhZGFibGUuCiAgICAgICBGb2xsb3dpbmcgICAgc3Vj aCAgICBhbiAgICBpbmRpY2F0aW9uLCAgICBhICAgIHN1YnNlcXVlbnQgICAgIFNFQ+KAkAogICAg ICAgQ09NUF9JT0NUTF9OT1RJRl9SRUNWICBpb2N0bCgyKSAgd2lsbCAgbm90IGJsb2NrLCByZXR1 cm5pbmcgZWl0aGVyCiAgICAgICBpbmZvcm1hdGlvbiBhYm91dCBhIG5vdGlmaWNhdGlvbiBvciBl bHNlIGZhaWxpbmcgIHdpdGggIHRoZSAgZXJyb3IKICAgICAgIEVJTlRSICBpZiAgdGhlICB0YXJn ZXQgIHByb2Nlc3MgaGFzIGJlZW4ga2lsbGVkIGJ5IGEgc2lnbmFsIG9yIGl0cwogICAgICAgc3lz dGVtIGNhbGwgaGFzIGJlZW4gaW50ZXJydXB0ZWQgYnkgYSBzaWduYWwgaGFuZGxlci4KXV0KCk9r YXk/Cgo+IEV4Y2VlZWVlcHQgdGhhdCB0aGlzIHBhcnQgbG9va3MgYnJva2VuOgo+IAo+ICAgaWYg KG11dGV4X2xvY2tfaW50ZXJydXB0aWJsZSgmZmlsdGVyLT5ub3RpZnlfbG9jaykgPCAwKQo+ICAg ICByZXR1cm4gRVBPTExFUlI7Cj4gCj4gd2hpY2ggSSB0aGluayBtZWFucyB0aGF0IHdlIGNhbiBo YXZlIGEgcmFjZSB3aGVyZSBhIHNpZ25hbCBhcnJpdmVzCj4gd2hpbGUgcG9sbCgpIGlzIHRyeWlu ZyB0byBhZGQgaXRzZWxmIHRvIHRoZSB3YWl0cXVldWUgb2YgdGhlIHNlY2NvbXAKPiBmZCwgYW5k IHRoZW4gd2UnbGwgZ2V0IGEgc3B1cmlvdXMgZXJyb3IgY29uZGl0aW9uIHJlcG9ydGVkIG9uIHRo ZSBmZC4KPiBUaGF0J3MgYSBrZXJuZWwgYnVnLCBJJ2Qgc2F5LgoKU2lnaC4uLiBXcml0aW5nIGRv Y3VtZW50YXRpb24gaGVscHMgZmluZCBidWdzLiBXaG8ga25ldz8KCj4+IFRoZSAgb3BlcmF0aW9u IHJldHVybnMgYSBzZWNjb21wX25vdGlmCj4+ICAgICAgICAgICBzdHJ1Y3R1cmUgY29udGFpbmlu ZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3lzdGVtIGNhbGwgdGhhdCBpcwo+PiAgICAgICAgICAg YmVpbmcgYXR0ZW1wdGVkIGJ5IHRoZSB0YXJnZXQgcHJvY2Vzcy4KPj4KPj4gICAgICAgIDYuIFRo ZSAgICBzZWNjb21wX25vdGlmICAgIHN0cnVjdHVyZSAgIHJldHVybmVkICAgYnkgICB0aGUgICBT RUPigJAKPj4gICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfUkVDViBvcGVyYXRpb24gaW5jbHVk ZXMgdGhlIHNhbWUgIGluZm9ybWF0aW9uCj4+ICAgICAgICAgICAoYSBzZWNjb21wX2RhdGEgc3Ry dWN0dXJlKSB0aGF0IHdhcyBwYXNzZWQgdG8gdGhlIHNlY2NvbXAgZmls4oCQCj4+ICAgICAgICAg ICB0ZXIuICBUaGlzIGluZm9ybWF0aW9uIGFsbG93cyB0aGUgc3VwZXJ2aXNvciB0byAgZGlzY292 ZXIgIHRoZQo+PiAgICAgICAgICAgc3lzdGVtICBjYWxsIG51bWJlciBhbmQgdGhlIGFyZ3VtZW50 cyBmb3IgdGhlIHRhcmdldCBwcm9jZXNzJ3MKPj4gICAgICAgICAgIHN5c3RlbSBjYWxsLiAgSW4g YWRkaXRpb24sIHRoZSBub3RpZmljYXRpb24gZXZlbnQgY29udGFpbnMgdGhlCj4+ICAgICAgICAg ICBQSUQgb2YgdGhlIHRhcmdldCBwcm9jZXNzLgo+IAo+IFRoYXQncyBhIFBJRFRZUEVfUElELCB3 aGljaCB0aGUgbWFucGFnZXMgY2FsbCBhICJ0aHJlYWQgSUQiLgoKWWVzLiBGaXhlZCBub3cuIE1v cmUgZ2VuZXJhbGx5LCBJJ3ZlIHN3ZXB0IHRocm91Z2ggdGhlIHBhZ2UgcmVwbGFjaW5nCnZhcmlv dXMgaW5zdGFuY2VzIG9mICJ0YXJnZXQgcHJvY2VzcyIgd2l0aCBlaXRoZXIgInRhcmdldCB0aHJl YWQiLCBvcgpvZnRlbiBqdXN0ICJ0YXJnZXQiLgoKPj4gICAgICAgICAgIFRoZSAgaW5mb3JtYXRp b24gIGluICB0aGUgbm90aWZpY2F0aW9uIGNhbiBiZSB1c2VkIHRvIGRpc2NvdmVyCj4+ICAgICAg ICAgICB0aGUgdmFsdWVzIG9mIHBvaW50ZXIgYXJndW1lbnRzIGZvciB0aGUgdGFyZ2V0IHByb2Nl c3MncyAgc3lz4oCQCj4+ICAgICAgICAgICB0ZW0gY2FsbC4gIChUaGlzIGlzIHNvbWV0aGluZyB0 aGF0IGNhbid0IGJlIGRvbmUgZnJvbSB3aXRoaW4gYQo+PiAgICAgICAgICAgc2VjY29tcCBmaWx0 ZXIuKSAgVG8gZG8gdGhpcyAoYW5kICBhc3N1bWluZyAgaXQgIGhhcyAgc3VpdGFibGUKPj4gICAg ICAgICAgIHBlcm1pc3Npb25zKSwgICB0aGUgICBzdXBlcnZpc29yICAgb3BlbnMgICB0aGUgICBj b3JyZXNwb25kaW5nCj4+ICAgICAgICAgICAvcHJvYy9bcGlkXS9tZW0gZmlsZSwKPiAKPiAuLi4g d2hpY2ggbWVhbnMgdGhhdCBoZXJlIHdlIG1pZ2h0IGhhdmUgdG8gZ2V0IGludG8gdGhlIHdlZWRz IG9mIGhvdwo+IGFjdHVhbGx5IC9wcm9jIGhhcyBpbnZpc2libGUgZGlyZWN0b3JpZXMgZm9yIGV2 ZXJ5IFRJRCwgZXZlbiB0aG91Z2gKPiBvbmx5IHRoZSBvbmVzIGZvciBQSURzIGFyZSB2aXNpYmxl LCBhbmQgdGhlcmVmb3JlIHlvdSBjYW4ganVzdCBvcGVuCj4gL3Byb2MvW3RpZF0vbWVtIGFuZCBp dCdsbCB3b3JrIGZpbmU/CgpJIG15c2VsZiB3YXMgdW5hd2FyZSBvZiB0aGlzIGZvciB5ZWFycyB1 bnRpbCBJICphY2NpZGVudGFsbHkqIG1hZGUgdXNlCm9mIHRoZSBmZWF0dXJlIGluIG9uZSBvZiBt eSB0ZXN0IHByb2dyYW1zIGFuZCB0aGVuIGEgd2hpbGUgbGF0ZXIgZ290IHRvCmFza2luZyBteXNl bGYgImhvdyBjb21lIHRoYXQgd29ya2VkPyIuCgpBYm91dCB0d28geWVhcnMgYWdvLCBJIGFkZGVk IHNvbWUgdGV4dCAoQCkgdG8gZXhwbGFpbiB0aGlzIGluIHByb2MoNSkKbmVhciB0aGUgc3RhcnQg b2YgdGhlIHBhZ2U6CgogICBPdmVydmlldwogICAgICAgVW5kZXJuZWF0aCAvcHJvYywgdGhlcmUg YXJlIHRoZSBmb2xsb3dpbmcgZ2VuZXJhbCBncm91cHMgb2YgIGZpbGVzCiAgICAgICBhbmQgc3Vi ZGlyZWN0b3JpZXM6CgogICAgICAgL3Byb2MvW3BpZF0gc3ViZGlyZWN0b3JpZXMKICAgICAgICAg ICAgICBbLi4uXQogICAgICAgICAgICAgIFVuZGVybmVhdGggZWFjaCBvZiB0aGUgL3Byb2MvW3Bp ZF0gZGlyZWN0b3JpZXMsIGEgdGFzayBzdWLigJAKICAgICAgICAgICAgICBkaXJlY3RvcnkgY29u dGFpbnMgc3ViZGlyZWN0b3JpZXMgb2YgdGhlICBmb3JtICB0YXNrL1t0aWRdLAogICAgICAgICAg ICAgIFsuLi5dCgogICAgICAgICAgICAgIFRoZSAgL3Byb2MvW3BpZF0gIHN1YmRpcmVjdG9yaWVz IGFyZSB2aXNpYmxlIHdoZW4gaXRlcmF0aW5nCiAgICAgICAgICAgICAgdGhyb3VnaCAvcHJvYyB3 aXRoIGdldGRlbnRzKDIpIChhbmQgdGh1cyBhcmUgIHZpc2libGUgIHdoZW4KICAgICAgICAgICAg ICBvbmUgdXNlcyBscygxKSB0byB2aWV3IHRoZSBjb250ZW50cyBvZiAvcHJvYykuCgogICAgICAg L3Byb2MvW3RpZF0gc3ViZGlyZWN0b3JpZXMKQCAgICAgICAgICAgICBFYWNoICBvbmUgb2YgdGhl c2Ugc3ViZGlyZWN0b3JpZXMgY29udGFpbnMgZmlsZXMgYW5kIHN1YmRp4oCQCkAgICAgICAgICAg ICAgcmVjdG9yaWVzIGV4cG9zaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSAgdGhyZWFkICB3aXRo ICB0aGUKQCAgICAgICAgICAgICBjb3JyZXNwb25kaW5nIHRocmVhZCBJRC4gIFRoZSBjb250ZW50 cyBvZiB0aGVzZSBkaXJlY3RvcmllcwpAICAgICAgICAgICAgIGFyZSB0aGUgc2FtZSBhcyAgdGhl ICBjb3JyZXNwb25kaW5nICAvcHJvYy9bcGlkXS90YXNrL1t0aWRdCkAgICAgICAgICAgICAgZGly ZWN0b3JpZXMuCgpAICAgICAgICAgICAgIFRoZSAvcHJvYy9bdGlkXSBzdWJkaXJlY3RvcmllcyBh cmUgbm90IHZpc2libGUgd2hlbiBpdGVyYXTigJAKQCAgICAgICAgICAgICBpbmcgdGhyb3VnaCAv cHJvYyB3aXRoIGdldGRlbnRzKDIpIChhbmQgdGh1cyBhcmUgbm90ICB2aXNp4oCQCkAgICAgICAg ICAgICAgYmxlIHdoZW4gb25lIHVzZXMgbHMoMSkgdG8gdmlldyB0aGUgY29udGVudHMgb2YgL3By b2MpLgoKSSB0aGluayBJJ2xsIGp1c3QgZHJvcCBhIGNyb3NzIHJlZmVyZW5jZSB0byBwcm9jKDUp IGludG8gdGhlIHRleHQgaW4Kc2VjY29tcF91c2VyX25vdGlmLgoKPj4gc2Vla3MgdG8gdGhlIG1l bW9yeSBsb2NhdGlvbiB0aGF0IGNvcnJl4oCQCj4+ICAgICAgICAgICBzcG9uZHMgdG8gb25lIG9m IHRoZSBwb2ludGVyIGFyZ3VtZW50cyB3aG9zZSB2YWx1ZSBpcyBzdXBwbGllZAo+PiAgICAgICAg ICAgaW4gdGhlIG5vdGlmaWNhdGlvbiBldmVudCwgYW5kIHJlYWRzIGJ5dGVzIGZyb20gdGhhdCBs b2NhdGlvbi4KPj4gICAgICAgICAgIChUaGUgc3VwZXJ2aXNvciBtdXN0IGJlIGNhcmVmdWwgdG8g YXZvaWQgYSByYWNlIGNvbmRpdGlvbiB0aGF0Cj4+ICAgICAgICAgICBjYW4gb2NjdXIgd2hlbiBk b2luZyB0aGlzOyBzZWUgdGhlICBkZXNjcmlwdGlvbiAgb2YgIHRoZSAgU0VD4oCQCj4+ICAgICAg ICAgICBDT01QX0lPQ1RMX05PVElGX0lEX1ZBTElEIGlvY3RsKDIpIG9wZXJhdGlvbiBiZWxvdy4p ICBJbiBhZGRp4oCQCj4+ICAgICAgICAgICB0aW9uLCB0aGUgc3VwZXJ2aXNvciBjYW4gYWNjZXNz IG90aGVyIHN5c3RlbSBpbmZvcm1hdGlvbiAgdGhhdAo+PiAgICAgICAgICAgaXMgIHZpc2libGUg IGluICB1c2VyIHNwYWNlIGJ1dCB3aGljaCBpcyBub3QgYWNjZXNzaWJsZSBmcm9tIGEKPj4gICAg ICAgICAgIHNlY2NvbXAgZmlsdGVyLgo+Pgo+PiAgICAgICAgICAg4pSM4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQCj4+ICAgICAgICAgICDilIJGSVhNRSAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggo+PiAgICAg ICAgICAg4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSk Cj4+ICAgICAgICAgICDilIJTdXBwb3NlIHdlIGFyZSByZWFkaW5nIGEgcGF0aG5hbWUgZnJvbSAv cHJvYy9QSUQvbWVtIOKUggo+PiAgICAgICAgICAg4pSCZm9yICBhIHN5c3RlbSBjYWxsIHN1Y2gg YXMgbWtkaXIoKS4gVGhlIHBhdGhuYW1lIGNhbiDilIIKPj4gICAgICAgICAgIOKUgmJlIGFuIGFy Yml0cmFyeSBsZW5ndGguIEhvdyBkbyB3ZSBrbm93IGhvdyBtdWNoIChob3cg4pSCCj4+ICAgICAg ICAgICDilIJtYW55IHBhZ2VzKSB0byByZWFkIGZyb20gL3Byb2MvUElEL21lbT8gICAgICAgICAg ICAgIOKUggo+PiAgICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSYCj4gCj4gSXQgY2FuJ3QgYmUgYW4gYXJiaXRyYXJ5IGxlbmd0aC4gV2hp bGUgcGF0aG5hbWVzICpyZXR1cm5lZCogZnJvbSB0aGUKPiBrZXJuZWwgaW4gc29tZSBwbGFjZXMg Y2FuIGhhdmUgZGlmZmVyZW50IGxpbWl0cywgc3RyaW5ncyBzdXBwbGllZCBhcwo+IHBhdGggYXJn dW1lbnRzICp0byogdGhlIGtlcm5lbCBBRkFJSyBhbHdheXMgaGF2ZSBhbiB1cHBlciBsaW1pdCBv Zgo+IFBBVEhfTUFYLCBlbHNlIHlvdSBnZXQgLUVOQU1FVE9PTE9ORy4gU2VlIGdldG5hbWVfZmxh Z3MoKS4KClllcywgYW5vdGhlciB0aGlua28gb24gbXkgcGFydC4gSSByZW1vdmVkIHRoaXMgRklY TUUuCgo+PiAgICAgICAgNy4gSGF2aW5nICBvYnRhaW5lZCAgaW5mb3JtYXRpb24gIGFzICBwZXIg IHRoZSBwcmV2aW91cyBzdGVwLCB0aGUKPj4gICAgICAgICAgIHN1cGVydmlzb3IgbWF5IHRoZW4g Y2hvb3NlIHRvIHBlcmZvcm0gYW4gYWN0aW9uIGluIHJlc3BvbnNlIHRvCj4+ICAgICAgICAgICB0 aGUgIHRhcmdldCAgcHJvY2VzcydzICBzeXN0ZW0gY2FsbCAod2hpY2gsIGFzIG5vdGVkIGFib3Zl LCBpcwo+PiAgICAgICAgICAgbm90ICBleGVjdXRlZCAgd2hlbiAgdGhlICBzZWNjb21wICBmaWx0 ZXIgIHJldHVybnMgIHRoZSAgIFNFQ+KAkAo+PiAgICAgICAgICAgQ09NUF9SRVRfVVNFUl9OT1RJ RiBhY3Rpb24gdmFsdWUpLgo+IAo+ICh1bmxlc3MgU0VDQ09NUF9VU0VSX05PVElGX0ZMQUdfQ09O VElOVUUgaXMgdXNlZCkKCkFzIHlvdSBwcm9iYWJseSBzYXcsIEkgZ2l2ZSBTRUNDT01QX1VTRVJf Tk9USUZfRkxBR19DT05USU5VRSBhIGJyaWVmIAptZW50aW9uIGEgY291cGxlIG9mIHBhcmFncmFw aHMgbGF0ZXIsIGFuZCB0aGVuIGdvIGludG8gcmF0aGVyIG1vcmUKZGV0YWlsIGxhdGVyIGluIHRo ZSBwYWdlLiAoT3IgZG8geW91IHN0aWxsIHRoaW5rIHNvbWV0aGluZyBuZWVkcwpmaXhpbmc/KQoK Pj4gICAgICAgICAgIE9uZSAgZXhhbXBsZSAgdXNlIGNhc2UgaGVyZSByZWxhdGVzIHRvIGNvbnRh aW5lcnMuICBUaGUgdGFyZ2V0Cj4+ICAgICAgICAgICBwcm9jZXNzIG1heSBiZSBsb2NhdGVkIGlu c2lkZSBhIGNvbnRhaW5lciB3aGVyZSAgaXQgIGRvZXMgIG5vdAo+PiAgICAgICAgICAgaGF2ZSBz dWZmaWNpZW50IGNhcGFiaWxpdGllcyB0byBtb3VudCBhIGZpbGVzeXN0ZW0gaW4gdGhlIGNvbuKA kAo+PiAgICAgICAgICAgdGFpbmVyJ3MgbW91bnQgbmFtZXNwYWNlLiAgSG93ZXZlciwgdGhlIHN1 cGVydmlzb3IgIG1heSAgYmUgIGEKPj4gICAgICAgICAgIG1vcmUgIHByaXZpbGVnZWQgIHByb2Nl c3MgdGhhdCB0aGF0IGRvZXMgaGF2ZSBzdWZmaWNpZW50IGNhcGHigJAKPiAKPiBuaXQ6IHMvdGhh dCB0aGF0L3RoYXQvCgpUaGFua3MuIEZpeGVkLgoKPj4gICAgICAgICAgIGJpbGl0aWVzIHRvIHBl cmZvcm0gdGhlIG1vdW50IG9wZXJhdGlvbi4KPj4KPj4gICAgICAgIDguIFRoZSBzdXBlcnZpc29y IHRoZW4gc2VuZHMgYSByZXNwb25zZSB0byB0aGUgbm90aWZpY2F0aW9uLiAgVGhlCj4+ICAgICAg ICAgICBpbmZvcm1hdGlvbiAgaW4gIHRoaXMgIHJlc3BvbnNlICBpcyB1c2VkIGJ5IHRoZSBrZXJu ZWwgdG8gY29u4oCQCj4+ICAgICAgICAgICBzdHJ1Y3QgYSByZXR1cm4gdmFsdWUgZm9yIHRoZSB0 YXJnZXQgcHJvY2VzcydzIHN5c3RlbSBjYWxsIGFuZAo+PiAgICAgICAgICAgcHJvdmlkZSBhIHZh bHVlIHRoYXQgd2lsbCBiZSBhc3NpZ25lZCB0byB0aGUgZXJybm8gdmFyaWFibGUgb2YKPj4gICAg ICAgICAgIHRoZSB0YXJnZXQgcHJvY2Vzcy4KPj4KPj4gICAgICAgICAgIFRoZSAgcmVzcG9uc2Ug IGlzICBzZW50ICB1c2luZyAgdGhlICAgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWCj4+ICAgICAg ICAgICBpb2N0bCgyKSAgIG9wZXJhdGlvbiwgICB3aGljaCAgaXMgIHVzZWQgIHRvICB0cmFuc21p dCAgYSAgc2Vj4oCQCj4+ICAgICAgICAgICBjb21wX25vdGlmX3Jlc3AgIHN0cnVjdHVyZSAgdG8g IHRoZSAga2VybmVsLiAgIFRoaXMgIHN0cnVjdHVyZQo+PiAgICAgICAgICAgaW5jbHVkZXMgIGEg IGNvb2tpZSAgdmFsdWUgdGhhdCB0aGUgc3VwZXJ2aXNvciBvYnRhaW5lZCBpbiB0aGUKPj4gICAg ICAgICAgIHNlY2NvbXBfbm90aWYgICAgc3RydWN0dXJlICAgIHJldHVybmVkICAgICBieSAgICAg dGhlICAgICBTRUPigJAKPj4gICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfUkVDViBvcGVyYXRp b24uICBUaGlzIGNvb2tpZSB2YWx1ZSBhbGxvd3MgdGhlCj4+ICAgICAgICAgICBrZXJuZWwgdG8g YXNzb2NpYXRlIHRoZSByZXNwb25zZSB3aXRoIHRoZSB0YXJnZXQgcHJvY2Vzcy4KPiAKPiAodW5s ZXNzIGlmIHRoZSB0YXJnZXQgdGhyZWFkIGVudGVyZWQgYSBzaWduYWwgaGFuZGxlciBvciB3YXMg a2lsbGVkIGluCj4gdGhlIG1lYW50aW1lKQoKWWVzLCBidXQgSSB0aGluayBJIGhhdmUgdGhpcyBh ZGVxdWF0ZWx5IGNvdmVyZWQgaW4gdGhlIGVycm9ycyBkZXNjcmliZWQKbGF0ZXIgaW4gdGhlIHBh Z2UgZm9yIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDVi4gKEkgaGF2ZSBub3cgYWRkZWQgdGhlCnRh cmdldC1wcm9jZXNzLXRlcm1pbmF0ZWQgY2FzZSB0byB0aGUgb3Jyb3IgdGV4dC4pCgogICAgICAg ICAgICAgIEVOT0VOVCBUaGUgYmxvY2tlZCBzeXN0ZW0gIGNhbGwgIGluICB0aGUgIHRhcmdldCAg aGFzICBiZWVuCiAgICAgICAgICAgICAgICAgICAgIGludGVycnVwdGVkICBieSAgYSAgc2lnbmFs ICBoYW5kbGVyICBvciAgdGhlICB0YXJnZXQKICAgICAgICAgICAgICAgICAgICAgcHJvY2VzcyBo YXMgdGVybWluYXRlZC4KCklzIHRoYXQgc3VmZmljaWVudD8KCj4+ICAgICAgICA5LiBPbmNlIHRo ZSBub3RpZmljYXRpb24gaGFzIGJlZW4gc2VudCwgdGhlIHN5c3RlbSAgY2FsbCAgaW4gIHRoZQo+ PiAgICAgICAgICAgdGFyZ2V0ICBwcm9jZXNzICB1bmJsb2NrcywgIHJldHVybmluZyB0aGUgaW5m b3JtYXRpb24gdGhhdCB3YXMKPj4gICAgICAgICAgIHByb3ZpZGVkIGJ5IHRoZSBzdXBlcnZpc29y IGluIHRoZSBub3RpZmljYXRpb24gcmVzcG9uc2UuCj4+Cj4+ICAgICAgICBBcyBhIHZhcmlhdGlv biBvbiB0aGUgbGFzdCB0d28gc3RlcHMsIHRoZSBzdXBlcnZpc29yIGNhbiAgc2VuZCAgYQo+PiAg ICAgICAgcmVzcG9uc2UgIHRoYXQgdGVsbHMgdGhlIGtlcm5lbCB0aGF0IGl0IHNob3VsZCBleGVj dXRlIHRoZSB0YXJnZXQKPj4gICAgICAgIHByb2Nlc3MncyAgIHN5c3RlbSAgIGNhbGw7ICAgc2Vl ICAgdGhlICAgZGlzY3Vzc2lvbiAgICBvZiAgICBTRUPigJAKPj4gICAgICAgIENPTVBfVVNFUl9O T1RJRl9GTEFHX0NPTlRJTlVFLCBiZWxvdy4KPj4KPj4gICAgaW9jdGwoMikgb3BlcmF0aW9ucwo+ PiAgICAgICAgVGhlIGZvbGxvd2luZyBpb2N0bCgyKSBvcGVyYXRpb25zIGFyZSBwcm92aWRlZCB0 byBzdXBwb3J0IHNlY2NvbXAKPj4gICAgICAgIHVzZXItc3BhY2Ugbm90aWZpY2F0aW9uLiAgRm9y IGVhY2ggb2YgdGhlc2Ugb3BlcmF0aW9ucywgdGhlIGZpcnN0Cj4+ICAgICAgICAoZmlsZSAgZGVz Y3JpcHRvcikgIGFyZ3VtZW50ICBvZiAgaW9jdGwoMikgIGlzIHRoZSBsaXN0ZW5pbmcgZmlsZQo+ PiAgICAgICAgZGVzY3JpcHRvciByZXR1cm5lZCBieSBhIGNhbGwgdG8gc2VjY29tcCgyKSB3aXRo IHRoZSBTRUNDT01QX0ZJTOKAkAo+PiAgICAgICAgVEVSX0ZMQUdfTkVXX0xJU1RFTkVSIGZsYWcu Cj4+Cj4+ICAgICAgICBTRUNDT01QX0lPQ1RMX05PVElGX1JFQ1YKPj4gICAgICAgICAgICAgICBU aGlzIG9wZXJhdGlvbiBpcyB1c2VkIHRvIG9idGFpbiBhIHVzZXItc3BhY2Ugbm90aWZpY2F0aW9u Cj4+ICAgICAgICAgICAgICAgZXZlbnQuICBJZiBubyBzdWNoIGV2ZW50IGlzIGN1cnJlbnRseSBw ZW5kaW5nLCB0aGUgIG9wZXJh4oCQCj4+ICAgICAgICAgICAgICAgdGlvbiAgYmxvY2tzICB1bnRp bCAgYW4gIGV2ZW50IG9jY3Vycy4KPiAKPiBOb3QgbmVjZXNzYXJpbHk7IGZvciBldmVyeSB0aW1l IGEgcHJvY2VzcyBlbnRlcmVkIGEgc2lnbmFsIGhhbmRsZXIgb3IKPiB3YXMga2lsbGVkIHdoaWxl IGEgbm90aWZpY2F0aW9uIHdhcyBwZW5kaW5nLCBhIGNhbGwgdG8KPiBTRUNDT01QX0lPQ1RMX05P VElGX1JFQ1Ygd2lsbCByZXR1cm4gLUVOT0VOVC4KClllcywgYnV0IGRvIHlvdSBub3QgY29uc2lk ZXIgdGhpcyBzdWZmaWNpZW50bHkgY292ZXJlZCBieSB0aGUKKHVwZGF0ZWQpIGVycm9yIHRleHQg dGhhdCBhcHBlYXJzIGxhdGVyPyAoU2VlIGJlbG93LikKCj4+IFRoZSB0aGlyZCBpb2N0bCgyKQo+ PiAgICAgICAgICAgICAgIGFyZ3VtZW50IGlzIGEgcG9pbnRlciB0byBhIHN0cnVjdHVyZSBvZiB0 aGUgZm9sbG93aW5nIGZvcm0KPj4gICAgICAgICAgICAgICB3aGljaCAgY29udGFpbnMgIGluZm9y bWF0aW9uIGFib3V0IHRoZSBldmVudC4gIFRoaXMgc3RydWPigJAKPj4gICAgICAgICAgICAgICB0 dXJlIG11c3QgYmUgemVyb2VkIG91dCBiZWZvcmUgdGhlIGNhbGwuCj4+Cj4+ICAgICAgICAgICAg ICAgICAgIHN0cnVjdCBzZWNjb21wX25vdGlmIHsKPj4gICAgICAgICAgICAgICAgICAgICAgIF9f dTY0ICBpZDsgICAgICAgICAgICAgIC8qIENvb2tpZSAqLwo+PiAgICAgICAgICAgICAgICAgICAg ICAgX191MzIgIHBpZDsgICAgICAgICAgICAgLyogUElEIG9mIHRhcmdldCBwcm9jZXNzICovCj4g Cj4gKFRJRCwgbm90IFBJRCkKClRoYW5rcy4gRml4ZWQuCgo+PiAgICAgICAgICAgICAgICAgICAg ICAgX191MzIgIGZsYWdzOyAgICAgICAgICAgLyogQ3VycmVudGx5IHVudXNlZCAoMCkgKi8KPj4g ICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzZWNjb21wX2RhdGEgZGF0YTsgICAvKiBTZWUg c2VjY29tcCgyKSAqLwo+PiAgICAgICAgICAgICAgICAgICB9Owo+Pgo+PiAgICAgICAgICAgICAg IFRoZSBmaWVsZHMgaW4gdGhpcyBzdHJ1Y3R1cmUgYXJlIGFzIGZvbGxvd3M6Cj4+Cj4+ICAgICAg ICAgICAgICAgaWQgICAgIFRoaXMgaXMgYSBjb29raWUgZm9yIHRoZSBub3RpZmljYXRpb24uICAg RWFjaCAgc3VjaAo+PiAgICAgICAgICAgICAgICAgICAgICBjb29raWUgIGlzICBndWFyYW50ZWVk ICB0byBiZSB1bmlxdWUgZm9yIHRoZSBjb3JyZeKAkAo+PiAgICAgICAgICAgICAgICAgICAgICBz cG9uZGluZyBzZWNjb21wICBmaWx0ZXIuICAgSW4gIG90aGVyICB3b3JkcywgIHRoaXMKPj4gICAg ICAgICAgICAgICAgICAgICAgY29va2llICBpcyAgdW5pcXVlIGZvciBlYWNoIG5vdGlmaWNhdGlv biBldmVudCBmcm9tCj4+ICAgICAgICAgICAgICAgICAgICAgIHRoZSB0YXJnZXQgcHJvY2Vzcy4K PiAKPiBUaGF0IHNlbnRlbmNlIGFib3V0ICJ0YXJnZXQgcHJvY2VzcyIgbG9va3Mgd3JvbmcgdG8g bWUuIFRoZSBjb29raWVzCj4gYXJlIHVuaXF1ZSBhY3Jvc3Mgbm90aWZpY2F0aW9ucyBmcm9tIHRo ZSBmaWx0ZXIsIGJ1dCB0aGVyZSBjYW4gYmUKPiBtdWx0aXBsZSBmaWx0ZXJzIHBlciB0aHJlYWQs IGFuZCBtdWx0aXBsZSB0aHJlYWRzIHBlciBmaWx0ZXIuCgpUaGFua3MuIEkgc2ltcGx5IHJlbW92 ZWQgdGhhdCBsYXN0IHNlbnRlbmNlLgoKPj4gVGhlIGNvb2tpZSB2YWx1ZSBoYXMgdGhlICBmb2zi gJAKPj4gICAgICAgICAgICAgICAgICAgICAgbG93aW5nIHVzZXM6Cj4+Cj4+ICAgICAgICAgICAg ICAgICAgICAgIMK3IEl0ICAgICBjYW4gICAgIGJlICAgICB1c2VkICAgIHdpdGggICAgdGhlICAg IFNFQ+KAkAo+PiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfSURfVkFM SUQgaW9jdGwoMikgIG9wZXJhdGlvbiAgdG8KPj4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJp ZnkgdGhhdCB0aGUgdGFyZ2V0IHByb2Nlc3MgaXMgc3RpbGwgYWxpdmUuCj4+Cj4+ICAgICAgICAg ICAgICAgICAgICAgIMK3IFdoZW4gIHJldHVybmluZyAgYSAgbm90aWZpY2F0aW9uICByZXNwb25z ZSB0byB0aGUKPj4gICAgICAgICAgICAgICAgICAgICAgICBrZXJuZWwsIHRoZSBzdXBlcnZpc29y IG11c3QgIGluY2x1ZGUgIHRoZSAgY29va2llCj4+ICAgICAgICAgICAgICAgICAgICAgICAgdmFs dWUgaW4gdGhlIHNlY2NvbXBfbm90aWZfcmVzcCBzdHJ1Y3R1cmUgdGhhdCBpcwo+PiAgICAgICAg ICAgICAgICAgICAgICAgIHNwZWNpZmllZCAgIGFzICAgdGhlICAgYXJndW1lbnQgICBvZiAgIHRo ZSAgIFNFQ+KAkAo+PiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBfSU9DVExfTk9USUZfU0VO RCBvcGVyYXRpb24uCj4+Cj4+ICAgICAgICAgICAgICAgcGlkICAgIFRoaXMgIGlzICB0aGUgIFBJ RCBvZiB0aGUgdGFyZ2V0IHByb2Nlc3MgdGhhdCB0cmln4oCQCj4+ICAgICAgICAgICAgICAgICAg ICAgIGdlcmVkIHRoZSBub3RpZmljYXRpb24gZXZlbnQuCj4+Cj4+ICAgICAgICAgICAgICAgICAg ICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkAo+ PiAgICAgICAgICAgICAgICAgICAgICDilIJGSVhNRSAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIOKUggo+PiAgICAgICAgICAgICAgICAgICAgICDilJzilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKQKPj4gICAgICAgICAg ICAgICAgICAgICAg4pSCVGhpcyBpcyBhIHRocmVhZCBJRCwgcmF0aGVyIHRoYW4gYSBQSUQsIHJp Z2h0PyAgICAgICDilIIKPj4gICAgICAgICAgICAgICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYCj4gCj4gWWVhaC4KClRoYW5rcy4gSSd2 ZSBtYWRlIHZhcmlvdXMgZml4ZXMuCgo+PiAgICAgICAgICAgICAgIGZsYWdzICBUaGlzIGlzIGEg IGJpdCAgbWFzayAgb2YgIGZsYWdzICBwcm92aWRpbmcgIGZ1cnRoZXIKPj4gICAgICAgICAgICAg ICAgICAgICAgaW5mb3JtYXRpb24gb24gdGhlIGV2ZW50LiAgSW4gdGhlIGN1cnJlbnQgaW1wbGVt ZW7igJAKPj4gICAgICAgICAgICAgICAgICAgICAgdGF0aW9uLCB0aGlzIGZpZWxkIGlzIGFsd2F5 cyB6ZXJvLgo+Pgo+PiAgICAgICAgICAgICAgIGRhdGEgICBUaGlzIGlzIGEgc2VjY29tcF9kYXRh IHN0cnVjdHVyZSBjb250YWluaW5nICBpbmZvcuKAkAo+PiAgICAgICAgICAgICAgICAgICAgICBt YXRpb24gIGFib3V0ICB0aGUgIHN5c3RlbSAgY2FsbCB0aGF0IHRyaWdnZXJlZCB0aGUKPj4gICAg ICAgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uLiAgVGhpcyBpcyB0aGUgc2FtZSBzdHJ1Y3R1 cmUgIHRoYXQgIGlzCj4+ICAgICAgICAgICAgICAgICAgICAgIHBhc3NlZCAgdG8gIHRoZSBzZWNj b21wIGZpbHRlci4gIFNlZSBzZWNjb21wKDIpIGZvcgo+PiAgICAgICAgICAgICAgICAgICAgICBk ZXRhaWxzIG9mIHRoaXMgc3RydWN0dXJlLgo+Pgo+PiAgICAgICAgICAgICAgIE9uIHN1Y2Nlc3Ms IHRoaXMgb3BlcmF0aW9uIHJldHVybnMgMDsgb24gIGZhaWx1cmUsICAtMSAgaXMKPj4gICAgICAg ICAgICAgICByZXR1cm5lZCwgIGFuZCAgZXJybm8gIGlzIHNldCB0byBpbmRpY2F0ZSB0aGUgY2F1 c2Ugb2YgdGhlCj4+ICAgICAgICAgICAgICAgZXJyb3IuICBUaGlzIG9wZXJhdGlvbiBjYW4gZmFp bCB3aXRoIHRoZSBmb2xsb3dpbmcgZXJyb3JzOgo+Pgo+PiAgICAgICAgICAgICAgIEVJTlZBTCAo c2luY2UgTGludXggNS41KQo+PiAgICAgICAgICAgICAgICAgICAgICBUaGUgc2VjY29tcF9ub3Rp ZiBzdHJ1Y3R1cmUgdGhhdCB3YXMgcGFzc2VkIHRvICB0aGUKPj4gICAgICAgICAgICAgICAgICAg ICAgY2FsbCBjb250YWluZWQgbm9uemVybyBmaWVsZHMuCj4+Cj4+ICAgICAgICAgICAgICAgRU5P RU5UIFRoZSAgdGFyZ2V0ICBwcm9jZXNzICB3YXMga2lsbGVkIGJ5IGEgc2lnbmFsIGFzIHRoZQo+ PiAgICAgICAgICAgICAgICAgICAgICBub3RpZmljYXRpb24gaW5mb3JtYXRpb24gd2FzIGJlaW5n IGdlbmVyYXRlZC4KPiAKPiBOb3QganVzdCBraWxsZWQsIGludGVycnVwdGlvbiB3aXRoIGEgc2ln bmFsIGhhbmRsZXIgaGFzIHRoZSBzYW1lIGVmZmVjdC4KCkFoIHllcyEgVGhhbmtzLiBJIGFkZGVk IHRoYXQgYXMgd2VsbC4KCltbCiAgICAgICAgICAgICAgRU5PRU5UIFRoZSB0YXJnZXQgdGhyZWFk IHdhcyBraWxsZWQgIGJ5ICBhICBzaWduYWwgIGFzICB0aGUKICAgICAgICAgICAgICAgICAgICAg bm90aWZpY2F0aW9uIGluZm9ybWF0aW9uIHdhcyBiZWluZyBnZW5lcmF0ZWQsIG9yIHRoZQogICAg ICAgICAgICAgICAgICAgICB0YXJnZXQncyAoYmxvY2tlZCkgc3lzdGVtIGNhbGwgd2FzIGludGVy cnVwdGVkIGJ5ICBhCiAgICAgICAgICAgICAgICAgICAgIHNpZ25hbCBoYW5kbGVyLgpdXQoKT2th eT8KCj4+ICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilJAKPj4gICAgICAgIOKUgkZJWE1FICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilJzilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilKQKPj4gICAgICAgIOKUgkZyb20gbXkgZXhwZXJpbWVu dHMsICBpdCAgYXBwZWFycyAgdGhhdCAgaWYgIGEgIFNFQ+KAkCDilIIKPj4gICAgICAgIOKUgkNP TVBfSU9DVExfTk9USUZfUkVDViAgIGlzICBkb25lICBhZnRlciAgdGhlICB0YXJnZXQg4pSCCj4+ ICAgICAgICDilIJwcm9jZXNzIHRlcm1pbmF0ZXMsIHRoZW4gdGhlIGlvY3RsKCkgIHNpbXBseSAg YmxvY2tzIOKUggo+PiAgICAgICAg4pSCKHJhdGhlciB0aGFuIHJldHVybmluZyBhbiBlcnJvciB0 byBpbmRpY2F0ZSB0aGF0IHRoZSDilIIKPj4gICAgICAgIOKUgnRhcmdldCBwcm9jZXNzIG5vIGxv bmdlciBleGlzdHMpLiAgICAgICAgICAgICAgICAgICAg4pSCCj4+ICAgICAgICDilIIgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUggo+PiAgICAg ICAg4pSCSSBmb3VuZCB0aGF0IHN1cnByaXNpbmcsIGFuZCBpdCByZXF1aXJlZCAgc29tZSAgY29u 4oCQIOKUggo+PiAgICAgICAg4pSCdG9ydGlvbnMgIGluIHRoZSBleGFtcGxlIHByb2dyYW0uICBJ dCB3YXMgbm90IHBvc3Np4oCQIOKUggo+PiAgICAgICAg4pSCYmxlIHRvIGNvZGUgbXkgU0lHQ0hM RCBoYW5kbGVyICh3aGljaCByZWFwcyB0aGUgem9t4oCQIOKUggo+PiAgICAgICAg4pSCYmllICB3 aGVuICB0aGUgIHdvcmtlci90YXJnZXQgcHJvY2VzcyB0ZXJtaW5hdGVzKSB0byDilIIKPj4gICAg ICAgIOKUgnNpbXBseSBzZXQgYSBmbGFnIGNoZWNrZWQgaW4gdGhlIG1haW4gIGhhbmRsZU5vdGlm aeKAkCDilIIKPj4gICAgICAgIOKUgmNhdGlvbnMoKSAgbG9vcCwgIHNpbmNlICB0aGlzIGNyZWF0 ZWQgYW4gdW5hdm9pZGFibGUg4pSCCj4+ICAgICAgICDilIJyYWNlIHdoZXJlIHRoZSBjaGlsZCBt aWdodCB0ZXJtaW5hdGUgIGp1c3QgIGFmdGVyICBJIOKUggo+PiAgICAgICAg4pSCaGFkICBjaGVj a2VkICB0aGUgIGZsYWcsICBidXQgYmVmb3JlIEkgYmxvY2tlZCAoZm9y4oCQIOKUggo+PiAgICAg ICAg4pSCZXZlciEpIGluICB0aGUgIFNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViAgb3BlcmF0aW9u LiDilIIKPj4gICAgICAgIOKUgkluc3RlYWQsICBJIGhhZCB0byBjb2RlIHRoZSBzaWduYWwgaGFu ZGxlciB0byBzaW1wbHkg4pSCCj4+ICAgICAgICDilIJjYWxsIF9leGl0KDIpICBpbiAgb3JkZXIg IHRvICB0ZXJtaW5hdGUgIHRoZSAgcGFyZW50IOKUggo+PiAgICAgICAg4pSCcHJvY2VzcyAodGhl IHN1cGVydmlzb3IpLiAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIKPj4gICAgICAgIOKU giAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSC Cj4+ICAgICAgICDilIJJcyAgdGhpcyAgZXhwZWN0ZWQgIGJlaGF2aW9yPyAgSXQgc2VlbXMgdG8g bWUgcmF0aGVyIOKUggo+PiAgICAgICAg4pSCZGVzaXJhYmxlIHRoYXQgU0VDQ09NUF9JT0NUTF9O T1RJRl9SRUNWIHNob3VsZCAgZ2l2ZSDilIIKPj4gICAgICAgIOKUgmFuIGVycm9yIGlmIHRoZSB0 YXJnZXQgcHJvY2VzcyBoYXMgdGVybWluYXRlZC4gICAgICAg4pSCCj4+ICAgICAgICDilJTilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJgKPiAKPiBZb3UgY291 bGQgcG9sbCgpIHRoZSBmZCBmaXJzdC4gQnV0IHllYWgsIGl0J2QgcHJvYmFibHkgYmUgYSBnb29k IGlkZWEKPiB0byBjaGFuZ2UgdGhhdC4KCkFoISBJdCB3YXMgb25seSBhZnRlciByZWFkaW5nIHNv bWUgY29tbWVudHMgZnJvbSBDaHJpc3RpYW4gdGhhdCBJCnJlYWxpemVkIGhvdyBwb2xsKCkgd29y a3MgaGVyZS4gSSdsbCBtYWtlIHNvbWUgYWRkaXRpb25zIHRvIHRoZQpwYWdlIGFib3V0IHRoZSBw b2xsKCkgZGV0YWlscy4gKFNlZSBteSByZXBseSB0byBDaHJpc3RpYW4gdGhhdCBzaG91bGQKbGFu ZCBhdCBhYm91dCB0aGUgc2FtZSB0aW1lIGFzIHRoaXMgbWFpbC4pCiAgCj4+ICAgICAgICBTRUND T01QX0lPQ1RMX05PVElGX0lEX1ZBTElECj4gWy4uLl0KPj4gICAgICAgICAgICAgICBJbiB0aGUg YWJvdmUgc2NlbmFyaW8sIHRoZSByaXNrIGlzIHRoYXQgdGhlIHN1cGVydmlzb3IgbWF5Cj4+ICAg ICAgICAgICAgICAgdHJ5IHRvIGFjY2VzcyB0aGUgbWVtb3J5IG9mIGEgcHJvY2VzcyBvdGhlciB0 aGFuIHRoZSAgdGFy4oCQCj4+ICAgICAgICAgICAgICAgZ2V0LiAgIFRoaXMgIHJhY2UgIGNhbiBi ZSBhdm9pZGVkIGJ5IGZvbGxvd2luZyB0aGUgY2FsbCB0bwo+PiAgICAgICAgICAgICAgIG9wZW4g d2l0aCBhIFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFMSUQgb3BlcmF0aW9uIHRvIHZlcuKAkAo+ PiAgICAgICAgICAgICAgIGlmeSAgdGhhdCAgdGhlICBwcm9jZXNzIHRoYXQgZ2VuZXJhdGVkIHRo ZSBub3RpZmljYXRpb24gaXMKPj4gICAgICAgICAgICAgICBzdGlsbCBhbGl2ZS4gIChOb3RlIHRo YXQgIGlmICB0aGUgIHRhcmdldCAgcHJvY2VzcyAgc3Vic2XigJAKPj4gICAgICAgICAgICAgICBx dWVudGx5ICB0ZXJtaW5hdGVzLCBpdHMgUElEIHdvbid0IGJlIHJldXNlZCBiZWNhdXNlIHRoZXJl Cj4gCj4gVGhhdCdzIHdyb25nLCB0aGUgUElEIGNhbiBiZSByZXVzZWQsIGJ1dCB0aGUgL3Byb2Mv JHBpZCBkaXJlY3RvcnkgaXMKPiBpbnRlcm5hbGx5IG5vdCBhc3NvY2lhdGVkIHdpdGggdGhlIG51 bWVyaWMgUElELCBidXQsIGNvbmNlcHR1YWxseQo+IHNwZWFraW5nLCB3aXRoIGEgc3BlY2lmaWMg aW5jYXJuYXRpb24gb2YgdGhlIFBJRCwgb3Igc29tZXRoaW5nIGxpa2UKPiB0aGF0LiAoQWN0dWFs bHksIGl0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgInN0cnVjdCBwaWQiLCB3aGljaCBpcyBub3QK PiByZXVzZWQsIGluc3RlYWQgb2YgdGhlIG51bWVyaWMgUElELikKClRoYW5rcy4gSSBzaW1wbGlm aWVkIHRoZSBsYXN0IHNlbnRlbmNlIG9mIHRoZSBwYXJhZ3JhcGg6CgogICAgICAgICAgICAgIElu ICB0aGUgYWJvdmUgc2NlbmFyaW8sIHRoZSByaXNrIGlzIHRoYXQgdGhlIHN1cGVydmlzb3IgbWF5 CiAgICAgICAgICAgICAgdHJ5IHRvIGFjY2VzcyB0aGUgbWVtb3J5IG9mIGEgcHJvY2VzcyBvdGhl ciB0aGFuICB0aGUgIHRhcuKAkAogICAgICAgICAgICAgIGdldC4gICBUaGlzICByYWNlICBjYW4g IGJlIGF2b2lkZWQgYnkgZm9sbG93aW5nIHRoZSBjYWxsIHRvCiAgICAgICAgICAgICAgb3Blbigy KSB3aXRoIGEgIFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFMSUQgIG9wZXJhdGlvbiAgdG8KICAg ICAgICAgICAgICB2ZXJpZnkgIHRoYXQgdGhlIHByb2Nlc3MgdGhhdCBnZW5lcmF0ZWQgdGhlIG5v dGlmaWNhdGlvbiBpcwogICAgICAgICAgICAgIHN0aWxsIGFsaXZlLiAgKE5vdGUgdGhhdCBpZiB0 aGUgdGFyZ2V0IHRlcm1pbmF0ZXMgYWZ0ZXIgdGhlCiAgICAgICAgICAgICAgbGF0dGVyICBzdGVw LCBhIHN1YnNlcXVlbnQgcmVhZCgyKSBmcm9tIHRoZSBmaWxlIGRlc2NyaXB0b3IKICAgICAgICAg ICAgICB3aWxsIHJldHVybiAwLCBpbmRpY2F0aW5nIGVuZCBvZiBmaWxlLikKCkkgdGhpbmsgdGhh dCdzIHByb2JhYmx5IGVub3VnaCBkZXRhaWwuCgo+PiAgICAgICAgICAgICAgIHJlbWFpbnMgYW4g b3BlbiByZWZlcmVuY2UgdG8gdGhlIC9wcm9jW3BpZF0vbWVtICBmaWxlOyAgaW4KPj4gICAgICAg ICAgICAgICB0aGlzICBjYXNlLCBhIHN1YnNlcXVlbnQgcmVhZCgyKSBmcm9tIHRoZSBmaWxlIHdp bGwgcmV0dXJuCj4+ICAgICAgICAgICAgICAgMCwgaW5kaWNhdGluZyBlbmQgb2YgZmlsZS4pCj4+ Cj4+ICAgICAgICAgICAgICAgT24gc3VjY2VzcyAoaS5lLiwgdGhlIG5vdGlmaWNhdGlvbiAgSUQg IGlzICBzdGlsbCAgdmFsaWQpLAo+PiAgICAgICAgICAgICAgIHRoaXMgIG9wZXJhdGlvbiAgcmV0 dXJucyAwIE9uIGZhaWx1cmUgKGkuZS4sIHRoZSBub3RpZmljYeKAkAo+IAo+IG5pdDogcy9yZXR1 cm5zIDAvcmV0dXJucyAwLi8KClRoYW5rcy4gRml4ZWQuCgo+PiAgICAgICAgICAgICAgIHRpb24g SUQgaXMgbm8gbG9uZ2VyIHZhbGlkKSwgLTEgaXMgcmV0dXJuZWQsIGFuZCBlcnJubyAgaXMKPj4g ICAgICAgICAgICAgICBzZXQgdG8gRU5PRU5ULgo+Pgo+PiAgICAgICAgU0VDQ09NUF9JT0NUTF9O T1RJRl9TRU5ECj4gWy4uLl0KPj4gICAgICAgICAgICAgICBUd28ga2luZHMgb2YgcmVzcG9uc2Ug YXJlIHBvc3NpYmxlOgo+Pgo+PiAgICAgICAgICAgICAgIMK3IEEgcmVzcG9uc2UgdG8gdGhlIGtl cm5lbCB0ZWxsaW5nIGl0IHRvIGV4ZWN1dGUgdGhlICB0YXLigJAKPj4gICAgICAgICAgICAgICAg IGdldCAgcHJvY2VzcydzICBzeXN0ZW0gIGNhbGwuICAgSW4gIHRoaXMgY2FzZSwgdGhlIGZsYWdz Cj4+ICAgICAgICAgICAgICAgICBmaWVsZCBpbmNsdWRlcyBTRUNDT01QX1VTRVJfTk9USUZfRkxB R19DT05USU5VRSBhbmQgIHRoZQo+PiAgICAgICAgICAgICAgICAgZXJyb3IgYW5kIHZhbCBmaWVs ZHMgbXVzdCBiZSB6ZXJvLgo+Pgo+PiAgICAgICAgICAgICAgICAgVGhpcyAga2luZCAgb2YgcmVz cG9uc2UgY2FuIGJlIHVzZWZ1bCBpbiBjYXNlcyB3aGVyZSB0aGUKPj4gICAgICAgICAgICAgICAg IHN1cGVydmlzb3IgbmVlZHMgdG8gZG8gZGVlcGVyIGFuYWx5c2lzIG9mICB0aGUgIHRhcmdldCdz Cj4+ICAgICAgICAgICAgICAgICBzeXN0ZW0gIGNhbGwgIHRoYW4gIGlzICBwb3NzaWJsZSAgZnJv bSAgYSBzZWNjb21wIGZpbHRlcgo+PiAgICAgICAgICAgICAgICAgKGUuZy4sIGV4YW1pbmluZyB0 aGUgdmFsdWVzIG9mIHBvaW50ZXIgYXJndW1lbnRzKSwgIGFuZCwKPj4gICAgICAgICAgICAgICAg IGhhdmluZyAgdmVyaWZpZWQgdGhhdCB0aGUgc3lzdGVtIGNhbGwgaXMgYWNjZXB0YWJsZSwgdGhl Cj4+ICAgICAgICAgICAgICAgICBzdXBlcnZpc29yIHdhbnRzIHRvIGFsbG93IGl0IHRvIHByb2Nl ZWQuCj4gCj4gImFsbG93IiBzb3VuZHMgYXMgaWYgdGhpcyBpcyBhbiBhY2Nlc3MgY29udHJvbCB0 aGluZywgYnV0IHRoaXMKPiBtZWNoYW5pc20gc2hvdWxkIHVzdWFsbHkgbm90IGJlIHVzZWQgZm9y IGFjY2VzcyBjb250cm9sICh1bmxlc3MgdGhlCj4gInNlY2NvbXAiIHN5c2NhbGwgaXMgYmxvY2tl ZCkuCgpZZXMsIEtlZXMgaGFzIGFsc28gcmFpc2VkIHRoaXMgcG9pbnQuCgo+IE1heWJlIHJld29y ZCBhcyAiaGF2aW5nIGRlY2lkZWQgdGhhdAo+IHRoZSBzeXN0ZW0gY2FsbCBkb2VzIG5vdCByZXF1 aXJlIGVtdWxhdGlvbiBieSB0aGUgc3VwZXJ2aXNvciwgdGhlCj4gc3VwZXJ2aXNvciB3YW50cyBp dCB0byBleGVjdXRlIG5vcm1hbGx5Iiwgb3Igc29tZXRoaW5nIGxpa2UgdGhhdD8KCkdyZWF0ISBN b3JlIHN1Z2dlc3RlZCB3b3JkaW5ncyEgVGhhbmsgeW91IDotKS4KCkkgdHdlYWtlZCBzbGlnaHRs eToKCiAgICAuLi4gaGF2aW5nIGRlY2lkZWQgdGhhdCB0aGUgc3lzdGVtIGNhbGwgZG9lcyBub3Qg cmVxdWlyZSBlbXVsYXRpb24KICAgIGJ5IHRoZSBzdXBlcnZpc29yLCB0aGUgc3VwZXJ2aXNvciB3 YW50cyB0aGUgc3lzdGVtIGNhbGwgdG8gCiAgICBiZSBleGVjdXRlZCBub3JtYWxseSBpbiB0aGUg dGFyZ2V0LgoKPiBbLi4uXQo+PiAgICAgICAgICAgICAgIE9uIHN1Y2Nlc3MsIHRoaXMgb3BlcmF0 aW9uIHJldHVybnMgMDsgb24gIGZhaWx1cmUsICAtMSAgaXMKPj4gICAgICAgICAgICAgICByZXR1 cm5lZCwgIGFuZCAgZXJybm8gIGlzIHNldCB0byBpbmRpY2F0ZSB0aGUgY2F1c2Ugb2YgdGhlCj4+ ICAgICAgICAgICAgICAgZXJyb3IuICBUaGlzIG9wZXJhdGlvbiBjYW4gZmFpbCB3aXRoIHRoZSBm b2xsb3dpbmcgZXJyb3JzOgo+Pgo+PiAgICAgICAgICAgICAgIEVJTlBST0dSRVNTCj4+ICAgICAg ICAgICAgICAgICAgICAgIEEgcmVzcG9uc2UgdG8gdGhpcyBub3RpZmljYXRpb24gIGhhcyAgYWxy ZWFkeSAgYmVlbgo+PiAgICAgICAgICAgICAgICAgICAgICBzZW50Lgo+Pgo+PiAgICAgICAgICAg ICAgIEVJTlZBTCBBbiBpbnZhbGlkIHZhbHVlIHdhcyBzcGVjaWZpZWQgaW4gdGhlIGZsYWdzIGZp ZWxkLgo+Pgo+PiAgICAgICAgICAgICAgIEVJTlZBTCBUaGUgICAgICAgZmxhZ3MgICAgICBmaWVs ZCAgICAgIGNvbnRhaW5lZCAgICAgIFNFQ+KAkAo+PiAgICAgICAgICAgICAgICAgICAgICBDT01Q X1VTRVJfTk9USUZfRkxBR19DT05USU5VRSwgYW5kIHRoZSBlcnJvciBvciB2YWwKPj4gICAgICAg ICAgICAgICAgICAgICAgZmllbGQgd2FzIG5vdCB6ZXJvLgo+Pgo+PiAgICAgICAgICAgICAgIEVO T0VOVCBUaGUgIGJsb2NrZWQgIHN5c3RlbSBjYWxsIGluIHRoZSB0YXJnZXQgcHJvY2VzcyBoYXMK Pj4gICAgICAgICAgICAgICAgICAgICAgYmVlbiBpbnRlcnJ1cHRlZCBieSBhIHNpZ25hbCBoYW5k bGVyLgo+IAo+ICh5b3UgY291bGQgYWxzbyBnZXQgdGhpcyBpZiBhIHJlc3BvbnNlIGhhcyBhbHJl YWR5IGJlZW4gc2VudCwgaW5zdGVhZAo+IG9mIEVJTlBST0dSRVNTIC0gdGhlIG9ubHkgZGlmZmVy ZW5jZSBpcyB3aGV0aGVyIHRoZSB0YXJnZXQgdGhyZWFkIGhhcwo+IHBpY2tlZCB1cCB0aGUgcmVz cG9uc2UgeWV0KQoKR290IGl0LiBJIGRvbid0IHRoaW5rIEknbGwgdHJ5IHRvIHdvcmsgdGhhdCBk ZXRhaWwgaW50byB0aGUgcGFnZQoodW5sZXNzIHlvdSByZWFsbHkgdGhpbmsgSSBzaG91bGQsIGJ1 dCBzaW5jZSB5b3UgbWFkZSB0aGlzIGEKcGFyZW50aGV0aWNhbCBjb21tZW50LCBwZXJoYXBzIHlv dSBkb24ndCB0aGluayBpdCdzIG5lY2Vzc2FyeSkuCgo+PiBOT1RFUwo+PiAgICAgICAgVGhlIGZp bGUgZGVzY3JpcHRvciByZXR1cm5lZCB3aGVuIHNlY2NvbXAoMikgaXMgZW1wbG95ZWQgd2l0aCB0 aGUKPj4gICAgICAgIFNFQ0NPTVBfRklMVEVSX0ZMQUdfTkVXX0xJU1RFTkVSICBmbGFnICBjYW4g IGJlICBtb25pdG9yZWQgIHVzaW5nCj4+ICAgICAgICBwb2xsKDIpLCBlcG9sbCg3KSwgYW5kIHNl bGVjdCgyKS4gIFdoZW4gYSBub3RpZmljYXRpb24gIGlzICBwZW5k4oCQCj4+ICAgICAgICBpbmcs ICB0aGVzZSBpbnRlcmZhY2VzIGluZGljYXRlIHRoYXQgdGhlIGZpbGUgZGVzY3JpcHRvciBpcyBy ZWFk4oCQCj4+ICAgICAgICBhYmxlLgo+IAo+IFdlIHNob3VsZCBwcm9iYWJseSBhbHNvIHBvaW50 IG91dCBzb21ld2hlcmUgdGhhdCwgYXMKPiBpbmNsdWRlL3VhcGkvbGludXgvc2VjY29tcC5oIHNh eXM6Cj4gCj4gICogU2ltaWxhciBwcmVjYXV0aW9ucyBzaG91bGQgYmUgYXBwbGllZCB3aGVuIHN0 YWNraW5nIFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYKPiAgKiBvciBTRUNDT01QX1JFVF9UUkFDRS4g Rm9yIFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgZmlsdGVycyBhY3Rpbmcgb24gdGhlCj4gICogc2Ft ZSBzeXNjYWxsLCB0aGUgbW9zdCByZWNlbnRseSBhZGRlZCBmaWx0ZXIgdGFrZXMgcHJlY2VkZW5j ZS4gVGhpcyBtZWFucwo+ICAqIHRoYXQgdGhlIG5ldyBTRUNDT01QX1JFVF9VU0VSX05PVElGIGZp bHRlciBjYW4gb3ZlcnJpZGUgYW55Cj4gICogU0VDQ09NUF9JT0NUTF9OT1RJRl9TRU5EIGZyb20g ZWFybGllciBmaWx0ZXJzLCBlc3NlbnRpYWxseSBhbGxvd2luZyBhbGwKCk15IHRha2Vhd2F5IGZy b20gQ2hyaXRpYW4ncyBjb21tZW50cyBpcyB0aGF0IHRoaXMgY29tbWVudCBpbiB0aGUga2VybmVs IApzb3VyY2UgaXMgcGFydGlhbGx5IHdyb25nLCBzaW5jZSBpdCBpcyBub3QgcG9zc2libGUgdG8g aW5zdGFsbCBtdWx0aXBsZQpmaWx0ZXJzIHdpdGggU0VDQ09NUF9SRVRfVVNFUl9OT1RJRiwgcmln aHQ/Cgo+ICAqIHN1Y2ggZmlsdGVyZWQgc3lzY2FsbHMgdG8gYmUgZXhlY3V0ZWQgYnkgc2VuZGlu ZyB0aGUgcmVzcG9uc2UKPiAgKiBTRUNDT01QX1VTRVJfTk9USUZfRkxBR19DT05USU5VRS4gTm90 ZSB0aGF0IFNFQ0NPTVBfUkVUX1RSQUNFIGNhbiBlcXVhbGx5Cj4gICogYmUgb3ZlcnJpZGVuIGJ5 IFNFQ0NPTVBfVVNFUl9OT1RJRl9GTEFHX0NPTlRJTlVFLgo+IAo+IEluIG90aGVyIHdvcmRzLCBm cm9tIGEgc2VjdXJpdHkgcGVyc3BlY3RpdmUsIHlvdSBtdXN0IGFzc3VtZSB0aGF0IHRoZQo+IHRh cmdldCBwcm9jZXNzIGNhbiBieXBhc3MgYW55IFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgKG9yCj4g U0VDQ09NUF9SRVRfVFJBQ0UpIGZpbHRlcnMgdW5sZXNzIGl0IGlzIGNvbXBsZXRlbHkgcHJvaGli aXRlZCBmcm9tCj4gY2FsbGluZyBzZWNjb21wKCkuIAoKRHJhd2luZyBvbiB0ZXh0IGZyb20gQ2hy c3RpYW4ncyBjb21tZW50IGluIHNlY2NvbXAuaCBhbmQgS2VlcydzIG1haWwsCkkgYWRkZWQgdGhl IGZvbGxvd2luZyBpbiBOT1RFUzoKCiAgIERlc2lnbiBnb2FsczsgdXNlIG9mIFNFQ0NPTVBfVVNF Ul9OT1RJRl9GTEFHX0NPTlRJTlVFCiAgICAgICBUaGUgaW50ZW50IG9mIHRoZSB1c2VyLXNwYWNl IG5vdGlmaWNhdGlvbiBmZWF0dXJlIGlzIHRvIGFsbG93IHN5c+KAkAogICAgICAgdGVtIGNhbGxz IHRvIGJlIHBlcmZvcm1lZCBvbiBiZWhhbGYgb2YgdGhlIHRhcmdldC4gICBUaGUgIHRhcmdldCdz CiAgICAgICBzeXN0ZW0gIGNhbGwgc2hvdWxkIGVpdGhlciBiZSBoYW5kbGVkIGJ5IHRoZSBzdXBl cnZpc29yIG9yIGFsbG93ZWQKICAgICAgIHRvIGNvbnRpbnVlIG5vcm1hbGx5IGluIHRoZSBrZXJu ZWwgKHdoZXJlIHN0YW5kYXJkIHNlY3VyaXR5ICBwb2xp4oCQCiAgICAgICBjaWVzIHdpbGwgYmUg YXBwbGllZCkuCgogICAgICAgTm90ZSB3ZWxsOiB0aGlzIG1lY2hhbmlzbSBtdXN0IG5vdCBiZSB1 c2VkIHRvIG1ha2Ugc2VjdXJpdHkgcG9saWN5CiAgICAgICBkZWNpc2lvbnMgYWJvdXQgdGhlIHN5 c3RlbSBjYWxsLCB3aGljaCB3b3VsZCBiZSAgaW5oZXJlbnRseSAgcmFjZS0KICAgICAgIHByb25l IGZvciByZWFzb25zIGRlc2NyaWJlZCBuZXh0LgoKICAgICAgIFRoZSAgU0VDQ09NUF9VU0VSX05P VElGX0ZMQUdfQ09OVElOVUUgIGZsYWcgbXVzdCBiZSB1c2VkIHdpdGggY2F14oCQCiAgICAgICB0 aW9uLiAgSWYgc2V0IGJ5IHRoZSBzdXBlcnZpc29yLCB0aGUgIHRhcmdldCdzICBzeXN0ZW0gIGNh bGwgIHdpbGwKICAgICAgIGNvbnRpbnVlLiAgIEhvd2V2ZXIsICB0aGVyZSAgaXMgIGEgdGltZS1v Zi1jaGVjaywgdGltZS1vZi11c2UgcmFjZQogICAgICAgaGVyZSwgc2luY2UgYW4gYXR0YWNrZXIg Y291bGQgZXhwbG9pdCB0aGUgaW50ZXJ2YWwgb2YgIHRpbWUgIHdoZXJlCiAgICAgICB0aGUgIHRh cmdldCAgaXMgIGJsb2NrZWQgIHdhaXRpbmcgb24gdGhlICJjb250aW51ZSIgcmVzcG9uc2UgdG8g ZG8KICAgICAgIHRoaW5ncyBzdWNoIGFzIHJld3JpdGluZyB0aGUgc3lzdGVtIGNhbGwgYXJndW1l bnRzLgoKICAgICAgIE5vdGUgZnVydGhlcm1vcmUgdGhhdCBhIHVzZXItc3BhY2Ugbm90aWZpZXIg Y2FuIGJlIGJ5cGFzc2VkIGlmIHRoZQogICAgICAgZXhpc3RpbmcgIGZpbHRlcnMgIGFsbG93ICB0 aGUgIHVzZSAgb2YgIHNlY2NvbXAoMikgIG9yIHByY3RsKDIpIHRvCiAgICAgICBpbnN0YWxsIGEg ZmlsdGVyIHRoYXQgcmV0dXJucyBhbiBhY3Rpb24gdmFsdWUgd2l0aCBhIGhpZ2hlciBwcmVjZeKA kAogICAgICAgZGVuY2UgdGhhbiBTRUNDT01QX1JFVF9VU0VSX05PVElGIChzZWUgc2VjY29tcCgy KSkuCgogICAgICAgSXQgIHNob3VsZCAgdGh1cyAgYmUgIGFic29sdXRlbHkgY2xlYXIgdGhhdCB0 aGUgc2VjY29tcCB1c2VyLXNwYWNlCiAgICAgICBub3RpZmljYXRpb24gbWVjaGFuaXNtIGNhbiBu b3QgYmUgdXNlZCAgdG8gIGltcGxlbWVudCAgYSAgc2VjdXJpdHkKICAgICAgIHBvbGljeSEgICBJ dCAgc2hvdWxkICBvbmx5ICBldmVyIGJlIHVzZWQgaW4gc2NlbmFyaW9zIHdoZXJlIGEgbW9yZQog ICAgICAgcHJpdmlsZWdlZCBwcm9jZXNzIHN1cGVydmlzZXMgdGhlIHN5c3RlbSBjYWxscyBvZiBh IGxlc3NlciAgcHJpdmnigJAKICAgICAgIGxlZ2VkICB0YXJnZXQgIHRvIGdldCBhcm91bmQga2Vy bmVsLWVuZm9yY2VkIHNlY3VyaXR5IHJlc3RyaWN0aW9ucwogICAgICAgd2hlbiB0aGUgc3VwZXJ2 aXNvciBkZWVtcyB0aGlzIHNhZmUuICBJbiBvdGhlciB3b3JkcywgaW4gb3JkZXIgIHRvCiAgICAg ICBjb250aW51ZSBhIHN5c3RlbSBjYWxsLCB0aGUgc3VwZXJ2aXNvciBzaG91bGQgYmUgc3VyZSB0 aGF0IGFub3RoZXIKICAgICAgIHNlY3VyaXR5IG1lY2hhbmlzbSBvciB0aGUga2VybmVsIGl0c2Vs ZiAgd2lsbCAgc3VmZmljaWVudGx5ICBibG9jawogICAgICAgdGhlICBzeXN0ZW0gIGNhbGwgIGlm ICBpdHMgIGFyZ3VtZW50cyAgYXJlICByZXdyaXR0ZW4gdG8gc29tZXRoaW5nCiAgICAgICB1bnNh ZmUuCgpTZWVtIG9rYXk/Cgo+IFRoaXMgc2hvdWxkIGFsc28gYmUgbm90ZWQgb3ZlciBpbiB0aGUg bWFpbgo+IHNlY2NvbXAoMikgbWFucGFnZSwgZXNwZWNpYWxseSB0aGUgU0VDQ09NUF9SRVRfVFJB Q0UgcGFydC4KCkkgYWRkZWQgc29tZSB3b3JkcyBpbiBzZWNjb21wKDIpIHRvIGVtcGhhc2l6ZSB0 aGlzLgoKPj4gRVhBTVBMRVMKPiBbLi4uXQo+PiAgICAgICAgVGhpcyAgcHJvZ3JhbSAgY2FuICB1 c2VkICB0byAgZGVtb25zdHJhdGUgIHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUKPiAKPiBuaXQ6ICJj YW4gYmUgdXNlZCB0byBkZW1vbnN0cmF0ZSIsIG9yIGFsdGVybmF0aXZlbHkganVzdCAiZGVtb25z dHJhdGVzIgoKVGhhbmtzLiBGaXhlZCAoYWRkZWQgInRvIikKCj4+ICAgICAgICBiZWhhdmlvciBv ZiB0aGUgc2VjY29tcCB1c2VyLXNwYWNlICBub3RpZmljYXRpb24gIG1lY2hhbmlzbS4gICBUbwo+ PiAgICAgICAgaGVscCAgYWlkICBzdWNoIGRlbW9uc3RyYXRpb25zLCB0aGUgcHJvZ3JhbSBsb2dz IHZhcmlvdXMgbWVzc2FnZXMKPj4gICAgICAgIHRvIHNob3cgdGhlIG9wZXJhdGlvbiBvZiB0aGUg dGFyZ2V0IHByb2Nlc3MgKGxpbmVzIHByZWZpeGVkICJUOiIpCj4+ICAgICAgICBhbmQgdGhlIHN1 cGVydmlzb3IgKGluZGVudGVkIGxpbmVzIHByZWZpeGVkICJTOiIpLgo+IFsuLi5dCj4+ICAgIFBy b2dyYW0gc291cmNlCj4gWy4uLl0KPj4gICAgICAgICNkZWZpbmUgZXJyRXhpdChtc2cpICAgIGRv IHsgcGVycm9yKG1zZyk7IGV4aXQoRVhJVF9GQUlMVVJFKTsgXAo+PiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgfSB3aGlsZSAoMCkKPiAKPiBEb24ndCB3ZSBoYXZlIGVycigpIGZvciB0 aGlzPwoKSSB0ZW5kIHRvIGF2b2lkIHRoZSB1c2Ugb2YgZXJyKCkgYmVjYXVzZSBpdCdzIGEgbm9u c3RhbmRhcmQgQlNEaXNtLgpQZXJoYXBzIGJ5IHRoaXMgcG9pbnQgdGhpcyBpcyBhcyBtdWNoIGEg aGFiaXQgYXMgYW55dGhpbmcgcmF0aW9uYWwuCgo+PiAgICAgICAgLyogU2VuZCB0aGUgZmlsZSBk ZXNjcmlwdG9yICdmZCcgb3ZlciB0aGUgY29ubmVjdGVkIFVOSVggZG9tYWluIHNvY2tldAo+PiAg ICAgICAgICAgJ3NvY2tmZCcuIFJldHVybnMgMCBvbiBzdWNjZXNzLCBvciAtMSBvbiBlcnJvci4g Ki8KPj4KPj4gICAgICAgIHN0YXRpYyBpbnQKPj4gICAgICAgIHNlbmRmZChpbnQgc29ja2ZkLCBp bnQgZmQpCj4+ICAgICAgICB7Cj4+ICAgICAgICAgICAgc3RydWN0IG1zZ2hkciBtc2doOwo+PiAg ICAgICAgICAgIHN0cnVjdCBpb3ZlYyBpb3Y7Cj4+ICAgICAgICAgICAgaW50IGRhdGE7Cj4+ICAg ICAgICAgICAgc3RydWN0IGNtc2doZHIgKmNtc2dwOwo+Pgo+PiAgICAgICAgICAgIC8qIEFsbG9j YXRlIGEgY2hhciBhcnJheSBvZiBzdWl0YWJsZSBzaXplIHRvIGhvbGQgdGhlIGFuY2lsbGFyeSBk YXRhLgo+PiAgICAgICAgICAgICAgIEhvd2V2ZXIsIHNpbmNlIHRoaXMgYnVmZmVyIGlzIGluIHJl YWxpdHkgYSAnc3RydWN0IGNtc2doZHInLCB1c2UgYQo+PiAgICAgICAgICAgICAgIHVuaW9uIHRv IGVuc3VyZSB0aGF0IGl0IGlzIHN1aXRhYmxlIGFsaWduZWQuICovCj4gCj4gbml0OiBzdWl0YWJs eQoKVGhhbmtzLiBGaXhlZC4KCj4+ICAgICAgICAgICAgdW5pb24gewo+PiAgICAgICAgICAgICAg ICBjaGFyICAgYnVmW0NNU0dfU1BBQ0Uoc2l6ZW9mKGludCkpXTsKPj4gICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIC8qIFNwYWNlIGxhcmdlIGVub3VnaCB0byBob2xkIGFuICdpbnQnICov Cj4+ICAgICAgICAgICAgICAgIHN0cnVjdCBjbXNnaGRyIGFsaWduOwo+PiAgICAgICAgICAgIH0g Y29udHJvbE1zZzsKPj4KPj4gICAgICAgICAgICAvKiBUaGUgJ21zZ19uYW1lJyBmaWVsZCBjYW4g YmUgdXNlZCB0byBzcGVjaWZ5IHRoZSBhZGRyZXNzIG9mIHRoZQo+PiAgICAgICAgICAgICAgIGRl c3RpbmF0aW9uIHNvY2tldCB3aGVuIHNlbmRpbmcgYSBkYXRhZ3JhbS4gSG93ZXZlciwgd2UgZG8g bm90Cj4+ICAgICAgICAgICAgICAgbmVlZCB0byB1c2UgdGhpcyBmaWVsZCBiZWNhdXNlICdzb2Nr ZmQnIGlzIGEgY29ubmVjdGVkIHNvY2tldC4gKi8KPj4KPj4gICAgICAgICAgICBtc2doLm1zZ19u YW1lID0gTlVMTDsKPj4gICAgICAgICAgICBtc2doLm1zZ19uYW1lbGVuID0gMDsKPj4KPj4gICAg ICAgICAgICAvKiBPbiBMaW51eCwgd2UgbXVzdCB0cmFuc21pdCBhdCBsZWFzdCBvbmUgYnl0ZSBv ZiByZWFsIGRhdGEgaW4KPj4gICAgICAgICAgICAgICBvcmRlciB0byBzZW5kIGFuY2lsbGFyeSBk YXRhLiBXZSB0cmFuc21pdCBhbiBhcmJpdHJhcnkgaW50ZWdlcgo+PiAgICAgICAgICAgICAgIHdo b3NlIHZhbHVlIGlzIGlnbm9yZWQgYnkgcmVjdmZkKCkuICovCj4+Cj4+ICAgICAgICAgICAgbXNn aC5tc2dfaW92ID0gJmlvdjsKPj4gICAgICAgICAgICBtc2doLm1zZ19pb3ZsZW4gPSAxOwo+PiAg ICAgICAgICAgIGlvdi5pb3ZfYmFzZSA9ICZkYXRhOwo+PiAgICAgICAgICAgIGlvdi5pb3ZfbGVu ID0gc2l6ZW9mKGludCk7Cj4+ICAgICAgICAgICAgZGF0YSA9IDEyMzQ1Owo+Pgo+PiAgICAgICAg ICAgIC8qIFNldCAnbXNnaGRyJyBmaWVsZHMgdGhhdCBkZXNjcmliZSBhbmNpbGxhcnkgZGF0YSAq Lwo+Pgo+PiAgICAgICAgICAgIG1zZ2gubXNnX2NvbnRyb2wgPSBjb250cm9sTXNnLmJ1ZjsKPj4g ICAgICAgICAgICBtc2doLm1zZ19jb250cm9sbGVuID0gc2l6ZW9mKGNvbnRyb2xNc2cuYnVmKTsK Pj4KPj4gICAgICAgICAgICAvKiBTZXQgdXAgYW5jaWxsYXJ5IGRhdGEgZGVzY3JpYmluZyBmaWxl IGRlc2NyaXB0b3IgdG8gc2VuZCAqLwo+Pgo+PiAgICAgICAgICAgIGNtc2dwID0gQ01TR19GSVJT VEhEUigmbXNnaCk7Cj4+ICAgICAgICAgICAgY21zZ3AtPmNtc2dfbGV2ZWwgPSBTT0xfU09DS0VU Owo+PiAgICAgICAgICAgIGNtc2dwLT5jbXNnX3R5cGUgPSBTQ01fUklHSFRTOwo+PiAgICAgICAg ICAgIGNtc2dwLT5jbXNnX2xlbiA9IENNU0dfTEVOKHNpemVvZihpbnQpKTsKPj4gICAgICAgICAg ICBtZW1jcHkoQ01TR19EQVRBKGNtc2dwKSwgJmZkLCBzaXplb2YoaW50KSk7Cj4+Cj4+ICAgICAg ICAgICAgLyogU2VuZCByZWFsIHBsdXMgYW5jaWxsYXJ5IGRhdGEgKi8KPj4KPj4gICAgICAgICAg ICBpZiAoc2VuZG1zZyhzb2NrZmQsICZtc2doLCAwKSA9PSAtMSkKPj4gICAgICAgICAgICAgICAg cmV0dXJuIC0xOwo+Pgo+PiAgICAgICAgICAgIHJldHVybiAwOwo+PiAgICAgICAgfQo+IAo+IElu c3RlYWQgb2YgdXNpbmcgdW5peCBkb21haW4gc29ja2V0cyB0byBzZW5kIHRoZSBmZCB0byB0aGUg cGFyZW50LCBJCj4gdGhpbmsgeW91IGNvdWxkIGFsc28gdXNlIGNsb25lMygpIHdpdGggZmxhZ3M9 PUNMT05FX0ZJTEVTfFNJR0NITEQsCj4gZHVwMigpIHRoZSBzZWNjb21wIGZkIHRvIGFuIGZkIHRo YXQgd2FzIHJlc2VydmVkIGluIHRoZSBwYXJlbnQsIGNhbGwKPiB1bnNoYXJlKENMT05FX0ZJTEVT KSBpbiB0aGUgY2hpbGQgYWZ0ZXIgc2V0dGluZyB1cCB0aGUgc2VjY29tcCBmZCwgYW5kCj4gd2Fr ZSB1cCB0aGUgcGFyZW50IHdpdGggc29tZXRoaW5nIGxpa2UgcHRocmVhZF9jb25kX3NpZ25hbCgp PyBJJ20gbm90Cj4gc3VyZSB3aGV0aGVyIHRoYXQnZCBsb29rIGJldHRlciBvciB3b3JzZSBpbiB0 aGUgZW5kIHRob3VnaCwgc28gbWF5YmUKPiBqdXN0IGlnbm9yZSB0aGlzIGNvbW1lbnQuCgpBaGgg LS0gbmljZS4gVGhhdCBhbnN3ZXJzIGluIGRldGFpbCBhIHF1ZXN0aW9uIEkgYWxzbyBoYWQgZm9y IFR5Y2hvLgpJIHdvbid0IG1ha2UgYW55IGNoYW5nZXMgdG8gdGhlIHBhZ2UgKHNpbmNlIEknbSBu b3Qgc3VyZSBpdCB3b3VsZCAKbG9vayBiZXR0ZXIpLCBidXQgSSB3aWxsIGFkZCB0aGF0IGRldGFp bCBpbiBhIGNvbW1lbnQgaW4gdGhlIHBhZ2UKc291cmNlLiBQZXJoYXBzIEknbGwgZG8gc29tZXRo aW5nIHdpdGggdGhhdCBpbiB0aGUgZnV0dXJlLgoKPiBbLi4uXQo+PiAgICAgICAgLyogQWNjZXNz IHRoZSBtZW1vcnkgb2YgdGhlIHRhcmdldCBwcm9jZXNzIGluIG9yZGVyIHRvIGRpc2NvdmVyIHRo ZQo+PiAgICAgICAgICAgcGF0aG5hbWUgdGhhdCB3YXMgZ2l2ZW4gdG8gbWtkaXIoKSAqLwo+Pgo+ PiAgICAgICAgc3RhdGljIHZvaWQKPj4gICAgICAgIGdldFRhcmdldFBhdGhuYW1lKHN0cnVjdCBz ZWNjb21wX25vdGlmICpyZXEsIGludCBub3RpZnlGZCwKPj4gICAgICAgICAgICAgICAgICAgICAg ICAgIGNoYXIgKnBhdGgsIHNpemVfdCBsZW4pCj4+ICAgICAgICB7Cj4+ICAgICAgICAgICAgY2hh ciBwcm9jTWVtUGF0aFtQQVRIX01BWF07Cj4+ICAgICAgICAgICAgc25wcmludGYocHJvY01lbVBh dGgsIHNpemVvZihwcm9jTWVtUGF0aCksICIvcHJvYy8lZC9tZW0iLCByZXEtPnBpZCk7Cj4+Cj4+ ICAgICAgICAgICAgaW50IHByb2NNZW1GZCA9IG9wZW4ocHJvY01lbVBhdGgsIE9fUkRPTkxZKTsK PiAKPiBTaG91bGQgZXhhbXBsZSBjb2RlIGxpa2UgdGhpcyBtYXliZSB1c2UgT19DTE9FWEVDIHVu bGVzcyB0aGUgZmQgaW4KPiBxdWVzdGlvbiBhY3R1YWxseSBoYXMgdG8gYmUgaW5oZXJpdGFibGU/ IEkga25vdyBpdCBkb2Vzbid0IGFjdHVhbGx5Cj4gbWF0dGVyIGhlcmUsIGJ1dCBpZiB0aGlzIGNv ZGUgd2FzIHVzZWQgaW4gYSBtdWx0aS10aHJlYWRlZCBjb250ZXh0LCBpdAo+IG1pZ2h0LgoKWWVz LCBnb29kIHBvaW50LiBJIGNoYW5nZWQgdGhpcy4KCj4+ICAgICAgICAgICAgaWYgKHByb2NNZW1G ZCA9PSAtMSkKPj4gICAgICAgICAgICAgICAgZXJyRXhpdCgiU3VwZXJ2aXNvcjogb3BlbiIpOwo+ Pgo+PiAgICAgICAgICAgIC8qIENoZWNrIHRoYXQgdGhlIHByb2Nlc3Mgd2hvc2UgaW5mbyB3ZSBh cmUgYWNjZXNzaW5nIGlzIHN0aWxsIGFsaXZlLgo+PiAgICAgICAgICAgICAgIElmIHRoZSBTRUND T01QX0lPQ1RMX05PVElGX0lEX1ZBTElEIG9wZXJhdGlvbiAocGVyZm9ybWVkCj4+ICAgICAgICAg ICAgICAgaW4gY2hlY2tOb3RpZmljYXRpb25JZElzVmFsaWQoKSkgc3VjY2VlZHMsIHdlIGtub3cg dGhhdCB0aGUKPj4gICAgICAgICAgICAgICAvcHJvYy9QSUQvbWVtIGZpbGUgZGVzY3JpcHRvciB0 aGF0IHdlIG9wZW5lZCBjb3JyZXNwb25kcyB0byB0aGUKPj4gICAgICAgICAgICAgICBwcm9jZXNz IGZvciB3aGljaCB3ZSByZWNlaXZlZCBhIG5vdGlmaWNhdGlvbi4gSWYgdGhhdCBwcm9jZXNzCj4+ ICAgICAgICAgICAgICAgc3Vic2VxdWVudGx5IHRlcm1pbmF0ZXMsIHRoZW4gcmVhZCgpIG9uIHRo YXQgZmlsZSBkZXNjcmlwdG9yCj4+ICAgICAgICAgICAgICAgd2lsbCByZXR1cm4gMCAoRU9GKS4g Ki8KPj4KPj4gICAgICAgICAgICBjaGVja05vdGlmaWNhdGlvbklkSXNWYWxpZChub3RpZnlGZCwg cmVxLT5pZCk7Cj4+Cj4+ICAgICAgICAgICAgLyogU2VlayB0byB0aGUgbG9jYXRpb24gY29udGFp bmluZyB0aGUgcGF0aG5hbWUgYXJndW1lbnQgKGkuZS4sIHRoZQo+PiAgICAgICAgICAgICAgIGZp cnN0IGFyZ3VtZW50KSBvZiB0aGUgbWtkaXIoMikgY2FsbCBhbmQgcmVhZCB0aGF0IHBhdGhuYW1l ICovCj4+Cj4+ICAgICAgICAgICAgaWYgKGxzZWVrKHByb2NNZW1GZCwgcmVxLT5kYXRhLmFyZ3Nb MF0sIFNFRUtfU0VUKSA9PSAtMSkKPj4gICAgICAgICAgICAgICAgZXJyRXhpdCgiU3VwZXJ2aXNv cjogbHNlZWsiKTsKPj4KPj4gICAgICAgICAgICBzc2l6ZV90IHMgPSByZWFkKHByb2NNZW1GZCwg cGF0aCwgUEFUSF9NQVgpOwo+PiAgICAgICAgICAgIGlmIChzID09IC0xKQo+PiAgICAgICAgICAg ICAgICBlcnJFeGl0KCJyZWFkIik7Cj4gCj4gV2h5IG5vdCBwcmVhZCgpIGluc3RlYWQgb2YgbHNl ZWsoKStyZWFkKCk/CgpObyBnb29kIHJlYXNvbiEgSSBjaGFuZ2VkIGl0IHRvOgoKICAgICAgICAg ICAvKiBSZWFkIGJ5dGVzIGF0IHRoZSBsb2NhdGlvbiBjb250YWluaW5nIHRoZSBwYXRobmFtZSBh cmd1bWVudAogICAgICAgICAgICAgIChpLmUuLCB0aGUgZmlyc3QgYXJndW1lbnQpIG9mIHRoZSBt a2RpcigyKSBjYWxsICovCgogICAgICAgICAgIHNzaXplX3QgcyA9IHByZWFkKHByb2NNZW1GZCwg cGF0aCwgUEFUSF9NQVgsIHJlcS0+ZGF0YS5hcmdzWzBdKTsKICAgICAgICAgICBpZiAocyA9PSAt MSkKICAgICAgICAgICAgICAgZXJyRXhpdCgicHJlYWQiKTsKCiAgICAgICAgICAgaWYgKHMgPT0g MCkgewogICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlx0UzogcHJlYWQoKSBvZiAvcHJv Yy9QSUQvbWVtICIKICAgICAgICAgICAgICAgICAgICAgICAicmV0dXJuZWQgMCAoRU9GKVxuIik7 CiAgICAgICAgICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgICAgICAgICB9CgpUaGFua3Mh Cgo+PiAgICAgICAgICAgIGlmIChzID09IDApIHsKPj4gICAgICAgICAgICAgICAgZnByaW50Zihz dGRlcnIsICJcdFM6IHJlYWQoKSBvZiAvcHJvYy9QSUQvbWVtICIKPj4gICAgICAgICAgICAgICAg ICAgICAgICAicmV0dXJuZWQgMCAoRU9GKVxuIik7Cj4+ICAgICAgICAgICAgICAgIGV4aXQoRVhJ VF9GQUlMVVJFKTsKPj4gICAgICAgICAgICB9Cj4+Cj4+ICAgICAgICAgICAgaWYgKGNsb3NlKHBy b2NNZW1GZCkgPT0gLTEpCj4+ICAgICAgICAgICAgICAgIGVyckV4aXQoImNsb3NlLS9wcm9jL1BJ RC9tZW0iKTsKPiAKPiBXZSBzaG91bGQgcHJvYmFibHkgbWFrZSBzdXJlIGhlcmUgdGhhdCB0aGUg dmFsdWUgd2UgcmVhZCBpcyBhY3R1YWxseQo+IE5VTC10ZXJtaW5hdGVkPwoKU28sIEkgd2FzIGN1 cmlvdXMgYWJvdXQgdGhhdCBwb2ludCBhbHNvLiBCdXQsICh3aHkpIGFyZSB3ZSBub3QKZ3VhcmFu dGVlZCB0aGF0IGl0IHdpbGwgYmUgTlVMLXRlcm1pbmF0ZWQ/Cgo+PiAgICAgICAgfQo+Pgo+PiAg ICAgICAgLyogSGFuZGxlIG5vdGlmaWNhdGlvbnMgdGhhdCBhcnJpdmUgdmlhIHRoZSBTRUNDT01Q X1JFVF9VU0VSX05PVElGIGZpbGUKPj4gICAgICAgICAgIGRlc2NyaXB0b3IsICdub3RpZnlGZCcu ICovCj4+Cj4+ICAgICAgICBzdGF0aWMgdm9pZAo+PiAgICAgICAgaGFuZGxlTm90aWZpY2F0aW9u cyhpbnQgbm90aWZ5RmQpCj4+ICAgICAgICB7Cj4+ICAgICAgICAgICAgc3RydWN0IHNlY2NvbXBf bm90aWZfc2l6ZXMgc2l6ZXM7Cj4+ICAgICAgICAgICAgY2hhciBwYXRoW1BBVEhfTUFYXTsKPj4g ICAgICAgICAgICAgICAgLyogRm9yIHNpbXBsaWNpdHksIHdlIGFzc3VtZSB0aGF0IHRoZSBwYXRo bmFtZSBnaXZlbiB0byBta2RpcigpCj4+ICAgICAgICAgICAgICAgICAgIGlzIG5vIG1vcmUgdGhh biBQQVRIX01BWCBieXRlczsgYnV0IHRoaXMgbWlnaHQgbm90IGJlIHRydWUuICovCj4gCj4gTm8s IGl0IGhhcyB0byBiZSB0cnVlLCBvdGhlcndpc2UgdGhlIGtlcm5lbCB3b3VsZCBmYWlsIHRoZSBz eXNjYWxsIGlmCj4gaXQgd2FzIGV4ZWN1dGluZyBub3JtYWxseS4KClllcy4gSSByZW1vdmVkIHRo YXQgY29tbWVudC4KCj4+ICAgICAgICAgICAgLyogRGlzY292ZXIgdGhlIHNpemVzIG9mIHRoZSBz dHJ1Y3R1cmVzIHRoYXQgYXJlIHVzZWQgdG8gcmVjZWl2ZQo+PiAgICAgICAgICAgICAgIG5vdGlm aWNhdGlvbnMgYW5kIHNlbmQgbm90aWZpY2F0aW9uIHJlc3BvbnNlcywgYW5kIGFsbG9jYXRlCj4+ ICAgICAgICAgICAgICAgYnVmZmVycyBvZiB0aG9zZSBzaXplcy4gKi8KPj4KPj4gICAgICAgICAg ICBpZiAoc2VjY29tcChTRUNDT01QX0dFVF9OT1RJRl9TSVpFUywgMCwgJnNpemVzKSA9PSAtMSkK Pj4gICAgICAgICAgICAgICAgZXJyRXhpdCgiXHRTOiBzZWNjb21wLVNFQ0NPTVBfR0VUX05PVElG X1NJWkVTIik7Cj4+Cj4+ICAgICAgICAgICAgc3RydWN0IHNlY2NvbXBfbm90aWYgKnJlcSA9IG1h bGxvYyhzaXplcy5zZWNjb21wX25vdGlmKTsKPj4gICAgICAgICAgICBpZiAocmVxID09IE5VTEwp Cj4+ICAgICAgICAgICAgICAgIGVyckV4aXQoIlx0UzogbWFsbG9jIik7Cj4+Cj4+ICAgICAgICAg ICAgc3RydWN0IHNlY2NvbXBfbm90aWZfcmVzcCAqcmVzcCA9IG1hbGxvYyhzaXplcy5zZWNjb21w X25vdGlmX3Jlc3ApOwo+IAo+IFRoaXMgc2hvdWxkIHByb2JhYmx5IGRvIHNvbWV0aGluZyBsaWtl IG1heChzaXplcy5zZWNjb21wX25vdGlmX3Jlc3AsCj4gc2l6ZW9mKHN0cnVjdCBzZWNjb21wX25v dGlmX3Jlc3ApKSBpbiBjYXNlIHRoZSBwcm9ncmFtIHdhcyBidWlsdAo+IGFnYWluc3QgbmV3IFVB UEkgaGVhZGVycyB0aGF0IG1ha2Ugc3RydWN0IHNlY2NvbXBfbm90aWZfcmVzcCBiaWcsIGJ1dAo+ IGlzIHJ1bm5pbmcgdW5kZXIgYW4gb2xkIGtlcm5lbCB3aGVyZSB0aGF0IHN0cnVjdCBpcyBzdGls bCBzbWFsbGVyPwoKSSdtIGNvbmZ1c2VkLiBXaHk/IEkgbWVhbiwgaWYgdGhlIHJ1bm5pbmcga2Vy bmVsIHNheXMgdGhhdCBpdCBleHBlY3RzCmEgYnVmZmVyIG9mIGEgY2VydGFpbiBzaXplLCBhbmQg d2UgYWxsb2NhdGUgYSBidWZmZXIgb2YgdGhhdCBzaXplLAp3aGF0J3MgdGhlIHByb2JsZW0/Cgo+ PiAgICAgICAgICAgIGlmIChyZXNwID09IE5VTEwpCj4+ICAgICAgICAgICAgICAgIGVyckV4aXQo Ilx0UzogbWFsbG9jIik7Cj4gWy4uLl0KPj4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7Cj4+ Cj4+ICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgbWtkaXIoKSBmYWlsZWQgaW4gdGhlIHN1 cGVydmlzb3IsIHBhc3MgdGhlIGVycm9yCj4+ICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFj ayB0byB0aGUgdGFyZ2V0ICovCj4+Cj4+ICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+ZXJy b3IgPSAtZXJybm87Cj4+ICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJcdFM6IGZhaWx1 cmUhIChlcnJubyA9ICVkOyAlcylcbiIsIGVycm5vLAo+PiAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgc3RyZXJyb3IoZXJybm8pKTsKPj4gICAgICAgICAgICAgICAgICAgIH0KPj4gICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg fSBlbHNlIGlmIChzdHJuY21wKHBhdGgsICIuLyIsIHN0cmxlbigiLi8iKSkgPT0gMCkgewo+IAo+ IG5pdDogaW5kZW50IG1lc3NlZCB1cAoKVGhhbmtzLiBGaXhlZC4KCkFuZCB0aGFua3MgYWdhaW4g Zm9yIHRoZSBkZXRhaWxlZCByZXZpZXcsIEphbm4uCgpDaGVlcnMsCgpNaWNoYWVsCgotLSAKTWlj aGFlbCBLZXJyaXNrCkxpbnV4IG1hbi1wYWdlcyBtYWludGFpbmVyOyBodHRwOi8vd3d3Lmtlcm5l bC5vcmcvZG9jL21hbi1wYWdlcy8KTGludXgvVU5JWCBTeXN0ZW0gUHJvZ3JhbW1pbmcgVHJhaW5p bmc6IGh0dHA6Ly9tYW43Lm9yZy90cmFpbmluZy8KCl9fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fCkNvbnRhaW5lcnMgbWFpbGluZyBsaXN0CkNvbnRhaW5lcnNA bGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0cy5saW51eGZvdW5kYXRpb24u b3JnL21haWxtYW4vbGlzdGluZm8vY29udGFpbmVycw==