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=-8.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham 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 2CA59C4363A for ; Mon, 26 Oct 2020 00:23:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC99A223BE for ; Mon, 26 Oct 2020 00:23:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="dDktHPh1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1420805AbgJZATu (ORCPT ); Sun, 25 Oct 2020 20:19:50 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:35017 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389126AbgJZATt (ORCPT ); Sun, 25 Oct 2020 20:19:49 -0400 Received: by mail-pg1-f195.google.com with SMTP id f38so5110542pgm.2 for ; Sun, 25 Oct 2020 17:19:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=ZZ2a4aOmPjyQjPWSse0Y9NGMYSnUn8G3zEmlqVOLMFc=; b=dDktHPh1RGN624IjgTdeCk991cxycw5WvnOSaWkqtnSZAjdcKDbvAP2OF3D1ECVjAl eqepqpN0AxzpG3OWPp5xHKcAeXyl4Z4ZV26WQEUl4Bra0e9/GHYQjLogFkam4oQY4xKD QSPEN+Q0tvE02IyLA0WOV0Fa4X6UQB6YWZP+w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=ZZ2a4aOmPjyQjPWSse0Y9NGMYSnUn8G3zEmlqVOLMFc=; b=fS4S4rPcAwsUiVTbZWdJtHxfLaA0pch7fc/DvPAqSsbC5mY3ES1UczTEH6wmSTPsOj wGxwQk7bR4NS0ndy2tD9Pk8qx0ljv1HgklNwhfgz8R15U/P0i+W2rCAykKOiwYRTCHzB Jn+8/rPBuoGonb/Cv4qJBtgHpKmwAO5sI6/NK65mCRdn/XRcONwEKAGgcfCHGSGQJWjy 3S5I153/GtUw4HkMf0W0xQ3l9IFgMnUyUU31a/1YUvxgNze2rOAYD0ojhWWuoskqH5o0 Um+l/KH7XHr77LLaJ4zurzeufBt/vdArjCmOsc1GmRUTxQdbmkaX/6aPh7qIzzMHeXnJ T68g== X-Gm-Message-State: AOAM531QIIj2O7+b3/urUZPQ9YoU1T5q5iYBQMoLwR1901v+dYGp4Aec IsepXum3/TeGNU5psoQK3XEquw== X-Google-Smtp-Source: ABdhPJxjlEz21at3a78MBRzgHi7GljicYmNqfcTeN3KUjQ8xXnALihf+MYh/wD7/glH3jV3TUCgP+Q== X-Received: by 2002:a62:5c06:0:b029:160:1b43:14ed with SMTP id q6-20020a625c060000b02901601b4314edmr9205604pfb.11.1603671586067; Sun, 25 Oct 2020 17:19:46 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id w17sm10041350pjq.42.2020.10.25.17.19.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Oct 2020 17:19:44 -0700 (PDT) Date: Sun, 25 Oct 2020 17:19:43 -0700 From: Kees Cook To: "Michael Kerrisk (man-pages)" Cc: Tycho Andersen , Sargun Dhillon , Christian Brauner , linux-man , lkml , Aleksa Sarai , Jann Horn , Alexei Starovoitov , wad@chromium.org, bpf@vger.kernel.org, Song Liu , Daniel Borkmann , Andy Lutomirski , Linux Containers , Giuseppe Scrivano , Robert Sesek Subject: Re: For review: seccomp_user_notif(2) manual page Message-ID: <202010250759.F9745E0B6@keescook> References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> <202009301632.9C6A850272@keescook> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Oct 15, 2020 at 01:24:03PM +0200, Michael Kerrisk (man-pages) wrote: > On 10/1/20 1:39 AM, Kees Cook wrote: > > I'll comment more later, but I've run out of time today and I didn't see > > anyone mention this detail yet in the existing threads... :) > > Later never came :-). But, I hope you may have comments for the > next draft, which I will send out soon. Later is now, and Soon approaches! I finally caught up and read through this whole thread. Thank you all for the bug fix[1], and I'm looking forward to more[2]. :) For my reply I figured I'd base it on the current draft, so here's a simulated quote based on the seccomp_user_notif branch of https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git through commit 71101158fe330af5a26552447a0bb433b69e15b7 $ COLUMNS=75 man --nh --nj man2/seccomp_user_notif.2 | sed 's/^/> /' On Sun, Oct 25, 2020 at 01:54:05PM +0100, Michael Kerrisk (man-pages) wrote: > SECCOMP_USER_NOTIF(2) Linux Programmer's Manual SECCOMP_USER_NOTIF(2) > > NAME > seccomp_user_notif - Seccomp user-space notification mechanism > > SYNOPSIS > #include > #include > #include > > int seccomp(unsigned int operation, unsigned int flags, void *args); > > #include > > int ioctl(int fd, SECCOMP_IOCTL_NOTIF_RECV, > struct seccomp_notif *req); > int ioctl(int fd, SECCOMP_IOCTL_NOTIF_SEND, > struct seccomp_notif_resp *resp); > int ioctl(int fd, SECCOMP_IOCTL_NOTIF_ID_VALID, __u64 *id); > > DESCRIPTION > This page describes the user-space notification mechanism provided > by the Secure Computing (seccomp) facility. As well as the use of > the SECCOMP_FILTER_FLAG_NEW_LISTENER flag, the > SECCOMP_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 system call is made by the filter itself. By contrast, > the user-space notification mechanism allows the seccomp filter to > delegate the handling of the system call to another user-space > process. Note that this mechanism is explicitly not intended as a > method implementing security policy; see NOTES. > > In the discussion that follows, the thread(s) on which the seccomp > filter is installed is (are) referred to as the target, and the > process that is notified by the user-space notification mechanism > is referred to as the supervisor. > > A suitably privileged supervisor can use the user-space > notification mechanism to perform actions on behalf of the target. > The advantage of the user-space notification mechanism is that the > supervisor will usually be able to retrieve information about the > target and the performed system call that the seccomp filter > itself cannot. (A seccomp filter is limited in the information it > can obtain and the actions that it can perform because it is > running on a virtual machine inside the kernel.) > > An overview of the steps performed by the target and the > supervisor is as follows: > > 1. The target establishes a seccomp filter in the usual manner, > but with two differences: > > • The seccomp(2) flags argument includes the flag > SECCOMP_FILTER_FLAG_NEW_LISTENER. Consequently, the return > value of the (successful) seccomp(2) call is a new nit: extra space > "listening" file descriptor that can be used to receive > notifications. Only one "listening" seccomp filter can be > installed for a thread. I like this limitation, but I expect that it'll need to change in the future. Even with LSMs, we see the need for arbitrary stacking, and the idea of there being only 1 supervisor will eventually break down. Right now there is only 1 because only container managers are using this feature. But if some daemon starts using it to isolate some thread, suddenly it might break if a container manager is trying to listen to it too, etc. I expect it won't be needed soon, but I do think it'll change. > > • 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 can obtain notifications using the > listening file descriptor, (a duplicate of) that file > descriptor must be passed from the target to the supervisor. Yet another reason to have an "activate on exec" mode for seccomp. With no_new_privs _not_ being delayed in such a way, I think it'd be safe to add. The supervisor would get the fd immediately, and then once it fork/execed suddenly the whole thing would activate, and no fd passing needed. The "on exec" boundary is really only needed for oblivious targets. For a coordinated target, I've thought it might be nice to have an arbitrary "go" point, where the target could call seccomp() with something like a SECCOMP_ACTIVATE_DELAYED_FILTERS operation. This lets any process initialization happen that might need to do things that would be blocked by filters, etc. Before: fork install some filters that don't block initialization exec do some initialization install more filters, maybe block exec, seccomp run After: fork install delayed filters exec do some initialization activate delayed filters run In practice, the two-stage filter application has been fine, if sometimes a bit complex (e.g. for user_notif, "do some initialization" includes figuring out how to pass the fd back to the supervisor, etc). > One way in which this could be done is by passing the file > descriptor over a UNIX domain socket connection between the > target and the supervisor (using the SCM_RIGHTS ancillary > message type described in unix(7)). > > 3. The supervisor 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 seccomp(2) > SECCOMP_GET_NOTIF_SIZES operation, which returns a structure of > type seccomp_notif_sizes. The supervisor allocates 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.seccomp_notif_resp > bytes for the response (a struct seccomp_notif_resp structure) > that it will provide to the kernel (and thus the target). > > 4. The target 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 (yet) > execute the system call; instead, execution of the target is > temporarily blocked inside the kernel (in a sleep state that is > interruptible by signals) and a notification event is generated > on the listening file descriptor. > > 5. The supervisor can now repeatedly monitor the listening file > descriptor for SECCOMP_RET_USER_NOTIF-triggered events. To do > this, the supervisor uses the SECCOMP_IOCTL_NOTIF_RECV ioctl(2) > operation to read information about a notification event; this > operation blocks until an event is available. The operation > returns a seccomp_notif structure containing information about > the system call that is being attempted by the target. > > 6. The seccomp_notif structure returned by the > SECCOMP_IOCTL_NOTIF_RECV operation includes the same > information (a seccomp_data structure) that was passed to the > seccomp filter. This information allows the supervisor to > discover the system call number and the arguments for the > target's system call. In addition, the notification event > contains the ID of the thread that triggered the notification. Should "cookie" be at least named here, just to provide a bit more context for when it is mentioned in 8 below? E.g.: ... In addition, the notification event contains the triggering thread's ID and a unique cookie to be used in subsequent SECCOMP_IOCTL_NOTIF_ID_VALID and SECCOMP_IOCTL_NOTIF_SEND operations. > > The information in the notification can be used to discover the > values of pointer arguments for the target's system call. > (This is something that can't be done from within a seccomp > filter.) One way in which the supervisor can do this is to > open the corresponding /proc/[tid]/mem file (see proc(5)) and > read bytes from the location that corresponds to one of the > pointer arguments whose value is supplied in the notification > event. (The supervisor must be careful to avoid a race > condition that can occur when doing this; see the description > of the SECCOMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation below.) > In addition, the supervisor can access other system information > that is visible in user space but which is not accessible from > a seccomp filter. > > 7. Having obtained information as per the previous step, the > supervisor may then choose to perform an action in response to > the target's system call (which, as noted above, is not > executed when the seccomp filter returns the > SECCOMP_RET_USER_NOTIF action value). > > One example use case here relates to containers. The target > may be located inside a container where it does not have > sufficient capabilities to mount a filesystem in the > container's mount namespace. However, the supervisor may be a > more privileged process that does have sufficient capabilities > 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 construct > a return value for the target's system call and provide a value > that will be assigned to the errno variable of the target. > > The response is sent using the SECCOMP_IOCTL_NOTIF_SEND > ioctl(2) operation, which is used to transmit a > seccomp_notif_resp structure to the kernel. This structure > includes a cookie value that the supervisor obtained in the > seccomp_notif structure returned by the > SECCOMP_IOCTL_NOTIF_RECV operation. This cookie value allows > the kernel to associate the response with the target. Describing where the cookie came from seems like it should live in 6 above. A reader would have to take this new info and figure out where SECCOMP_IOCTL_NOTIF_RECV was described and piece it together. With the suggestion to 6 above, maybe: ... This structure must include the cookie value that the supervisor obtained in the seccomp_notif structure returned by the SECCOMP_IOCTL_NOTIF_RECV operation, which allows the kernel to associate the response with the target. > > 9. Once the notification has been sent, the system call in the > target thread 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 > thread's system call; see the discussion of > SECCOMP_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_FILTER_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 > operation blocks until an event occurs. The third ioctl(2) > argument is a pointer to a structure of the following form > which contains information about the event. This structure > must be zeroed out before the call. > > struct seccomp_notif { > __u64 id; /* Cookie */ > __u32 pid; /* TID of target thread */ Should we rename this variable from pid to tid? Yes it's UAPI, but yay for anonymous unions: struct seccomp_notif { __u64 id; /* Cookie */ union { __u32 pid; __u32 tid; /* TID of target thread */ }; __u32 flags; /* Currently unused (0) */ struct seccomp_data data; /* See seccomp(2) */ }; > __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 > corresponding seccomp filter. > > • It can be used with the > SECCOMP_IOCTL_NOTIF_ID_VALID ioctl(2) operation to > verify that the target 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 > SECCOMP_IOCTL_NOTIF_SEND operation. > > pid This is the thread ID of the target thread that > triggered the notification event. > > flags This is a bit mask of flags providing further > information on the event. In the current > implementation, this field is always zero. > > data This is a seccomp_data structure containing > information 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 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. > > SECCOMP_IOCTL_NOTIF_ID_VALID > This operation can be used to check that a notification ID > returned by an earlier SECCOMP_IOCTL_NOTIF_RECV operation > is still valid (i.e., that the target still exists). Maybe clarify a bit more, since it's covering more than just "is the target still alive", but also "is that syscall still waiting for a response": is still valid (i.e., that the target still exists and the syscall is still blocked waiting for a response). > > The third ioctl(2) argument is a pointer to the cookie (id) > returned by the SECCOMP_IOCTL_NOTIF_RECV operation. > > This operation is necessary to avoid race conditions that > can occur when the pid returned by the > SECCOMP_IOCTL_NOTIF_RECV operation terminates, and that > process ID is reused by another process. An example of > this kind of race is the following > > 1. A notification is generated on the listening file > descriptor. The returned seccomp_notif contains the TID > of the target thread (in the pid field of the > structure). > > 2. The target terminates. > > 3. Another thread or process is created on the system that > by chance reuses the TID that was freed when the target > terminated. > > 4. The supervisor open(2)s the /proc/[tid]/mem file for the > TID obtained in step 1, with the intention of (say) > inspecting the memory location(s) that containing the > argument(s) of the system call that triggered the > notification in step 1. > > In the above scenario, the risk is that the supervisor may > try to access the memory of a process other than the > target. 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 > may 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 notification ID > is no longer valid), -1 is returned, and errno is set to > ENOENT. > > SECCOMP_IOCTL_NOTIF_SEND > This operation is used to send a notification response back > to the kernel. The third ioctl(2) argument of this > structure is a pointer to a structure of the following > form: > > struct seccomp_notif_resp { > __u64 id; /* Cookie value */ > __s64 val; /* Success return value */ > __s32 error; /* 0 (success) or negative > error number */ > __u32 flags; /* See below */ > }; > > The fields of this structure are as follows: > > id This is the cookie value that was obtained using the > SECCOMP_IOCTL_NOTIF_RECV operation. This cookie > value allows the kernel to correctly associate this > response with the system call that triggered the > user-space notification. > > val This is the value that will be used for a spoofed > success return for the target's system call; see > below. > > error This is the value that will be used as the error > number (errno) for a spoofed error return for the > target's system call; see below. > > flags This is a bit mask that includes zero or more of the > following flags: > > SECCOMP_USER_NOTIF_FLAG_CONTINUE (since Linux 5.5) > Tell the kernel to execute the target's > system call. > > Two kinds of response are possible: > > • A response to the kernel telling it to execute the > target'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 > 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. > > The SECCOMP_USER_NOTIF_FLAG_CONTINUE flag should be used > with caution; see NOTES. > > • A spoofed return value for the target's system call. In > this case, the kernel does not execute the target's > system call, instead causing the system call to return a > spoofed value as specified by fields of the > seccomp_notif_resp structure. The supervisor should set > the fields of this structure as follows: > > + flags does not contain > SECCOMP_USER_NOTIF_FLAG_CONTINUE. > > + error is set either to 0 for a spoofed "success" > return or to a negative error number for a spoofed > "failure" return. In the former case, the kernel > causes the target's system call to return the value > specified in the val field. In the later case, the > kernel causes the target's system call to return -1, > and errno is assigned the negated error value. > > + val is set to a value that will be used as the return > value for a spoofed "success" return for the target's > system call. The value in this field is ignored if > the error field contains a nonzero value. Strictly speaking, this is architecture specific, but all architectures do it this way. Should seccomp enforce val == 0 when err != 0 ? > > 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 > SECCOMP_USER_NOTIF_FLAG_CONTINUE, and the error or > val field was not zero. > > ENOENT The blocked system call in the target has been > interrupted by a signal handler or the target has > terminated. > > NOTES > select()/poll()/epoll semantics > 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). These interfaces indicate that > the file descriptor is ready as follows: > > • When a notification is pending, these interfaces indicate that > the file descriptor is readable. Following such an indication, > a subsequent SECCOMP_IOCTL_NOTIF_RECV ioctl(2) will not block, > returning either information about a notification or else > failing with the error EINTR if the target has been killed by a > signal or its system call has been interrupted by a signal > handler. > > • After the notification has been received (i.e., by the > SECCOMP_IOCTL_NOTIF_RECV ioctl(2) operation), these interfaces > indicate that the file descriptor is writable, meaning that a > notification response can be sent using the > SECCOMP_IOCTL_NOTIF_SEND ioctl(2) operation. > > • After the last thread using the filter has terminated and been > reaped using waitpid(2) (or similar), the file descriptor > indicates an end-of-file condition (readable in select(2); > POLLHUP/EPOLLHUP in poll(2)/ epoll_wait(2)). I'll reply separately about the "ioctl() does not terminate when all filters have terminated" case. > > Design goals; use of SECCOMP_USER_NOTIF_FLAG_CONTINUE > The intent of the user-space notification feature is to allow > system 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 policies 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 > caution. 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 > precedence 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 > privileged 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. > > Interaction with SA_RESTART signal handlers > Consider the following scenario: > > • The target process has used sigaction(2) to install a signal > handler with the SA_RESTART flag. > > • The target has made a system call that triggered a seccomp user- > space notification and the target is currently blocked until the > supervisor sends a notification response. > > • A signal is delivered to the target and the signal handler is > executed. > > • When (if) the supervisor attempts to send a notification > response, the SECCOMP_IOCTL_NOTIF_SEND ioctl(2)) operation will > fail with the ENOENT error. > > In this scenario, the kernel will restart the target's system > call. Consequently, the supervisor will receive another user- > space notification. Thus, depending on how many times the blocked > system call is interrupted by a signal handler, the supervisor may > receive multiple notifications for the same system call in the maybe "... for the same instance of a system call in the target." for clarity? > target. > > One oddity is that system call restarting as described in this > scenario will occur even for the blocking system calls listed in > signal(7) that would never normally be restarted by the SA_RESTART > flag. Does this need fixing? I imagine the correct behavior for this case would be a response to _SEND of EINPROGRESS and the target would see EINTR normally? I mean, it's not like seccomp doesn't already expose weirdness with syscall restarts. Not even arm64 compat agrees[3] with arm32 in this regard. :( > BUGS > If a SECCOMP_IOCTL_NOTIF_RECV ioctl(2) operation is performed > after the target terminates, then the ioctl(2) call simply blocks > (rather than returning an error to indicate that the target no > longer exists). I want this fixed. It caused me no end of pain when building the selftests, and ended up spawning my implementing a global test timeout in kselftest. :P Before the usage counter refactor, there was no sane way to deal with this, but now I think we're close[2]. I'll reply separately about this. > > EXAMPLES > The (somewhat contrived) program shown below demonstrates the use > of the interfaces described in this page. The program creates a > child process that serves as the "target" process. The child > process installs a seccomp filter that returns the > SECCOMP_RET_USER_NOTIF action value if a call is made to mkdir(2). > The child process then calls mkdir(2) once for each of the > supplied command-line arguments, and reports the result returned > by the call. After processing all arguments, the child process > terminates. > > The parent process acts as the supervisor, listening for the > notifications that are generated when the target process calls > mkdir(2). When such a notification occurs, the supervisor > examines the memory of the target process (using /proc/[pid]/mem) > to discover the pathname argument that was supplied to the > mkdir(2) call, and performs one of the following actions: I like this example! It's simple enough to be understandable and complex enough to show the purpose of user_notif. :) > > • If the pathname begins with the prefix "/tmp/", then the > supervisor attempts to create the specified directory, and then > spoofs a return for the target process based on the return value > of the supervisor's mkdir(2) call. In the event that that call > succeeds, the spoofed success return value is the length of the > pathname. > > • If the pathname begins with "./" (i.e., it is a relative > pathname), the supervisor sends a > SECCOMP_USER_NOTIF_FLAG_CONTINUE response to the kernel to say > that the kernel should execute the target process's mkdir(2) > call. > > • If the pathname begins with some other prefix, the supervisor > spoofs an error return for the target process, so that the > target process's mkdir(2) call appears to fail with the error > EOPNOTSUPP ("Operation not supported"). Additionally, if the > specified pathname is exactly "/bye", then the supervisor > terminates. > > This program can be used to demonstrate various aspects of the > 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:"). > > In the following example, the target attempts to create the > directory /tmp/x. Upon receiving the notification, the supervisor > creates the directory on the target's behalf, and spoofs a success > return to be received by the target process's mkdir(2) call. > > $ ./seccomp_unotify /tmp/x > T: PID = 23168 > > T: about to mkdir("/tmp/x") > S: got notification (ID 0x17445c4a0f4e0e3c) for PID 23168 > S: executing: mkdir("/tmp/x", 0700) > S: success! spoofed return = 6 > S: sending response (flags = 0; val = 6; error = 0) > T: SUCCESS: mkdir(2) returned 6 > > T: terminating > S: target has terminated; bye > > In the above output, note that the spoofed return value seen by > the target process is 6 (the length of the pathname /tmp/x), > whereas a normal mkdir(2) call returns 0 on success. > > In the next example, the target attempts to create a directory > using the relative pathname ./sub. Since this pathname starts > with "./", the supervisor sends a SECCOMP_USER_NOTIF_FLAG_CONTINUE > response to the kernel, and the kernel then (successfully) > executes the target process's mkdir(2) call. > > $ ./seccomp_unotify ./sub > T: PID = 23204 > > T: about to mkdir("./sub") > S: got notification (ID 0xddb16abe25b4c12) for PID 23204 > S: target can execute system call > S: sending response (flags = 0x1; val = 0; error = 0) > T: SUCCESS: mkdir(2) returned 0 > > T: terminating > S: target has terminated; bye > > If the target process attempts to create a directory with a > pathname that doesn't start with "." and doesn't begin with the > prefix "/tmp/", then the supervisor spoofs an error return > (EOPNOTSUPP, "Operation not supported") for the target's mkdir(2) > call (which is not executed): > > $ ./seccomp_unotify /xxx > T: PID = 23178 > > T: about to mkdir("/xxx") > S: got notification (ID 0xe7dc095d1c524e80) for PID 23178 > S: spoofing error response (Operation not supported) > S: sending response (flags = 0; val = 0; error = -95) > T: ERROR: mkdir(2): Operation not supported > > T: terminating > S: target has terminated; bye > > In the next example, the target process attempts to create a > directory with the pathname /tmp/nosuchdir/b. Upon receiving the > notification, the supervisor attempts to create that directory, > but the mkdir(2) call fails because the directory /tmp/nosuchdir > does not exist. Consequently, the supervisor spoofs an error > return that passes the error that it received back to the target > process's mkdir(2) call. > > $ ./seccomp_unotify /tmp/nosuchdir/b > T: PID = 23199 > > T: about to mkdir("/tmp/nosuchdir/b") > S: got notification (ID 0x8744454293506046) for PID 23199 > S: executing: mkdir("/tmp/nosuchdir/b", 0700) > S: failure! (errno = 2; No such file or directory) > S: sending response (flags = 0; val = 0; error = -2) > T: ERROR: mkdir(2): No such file or directory > > T: terminating > S: target has terminated; bye > > If the supervisor receives a notification and sees that the > argument of the target's mkdir(2) is the string "/bye", then (as > well as spoofing an EOPNOTSUPP error), the supervisor terminates. > If the target process subsequently executes another mkdir(2) that > triggers its seccomp filter to return the SECCOMP_RET_USER_NOTIF > action value, then the kernel causes the target process's system > call to fail with the error ENOSYS ("Function not implemented"). > This is demonstrated by the following example: > > $ ./seccomp_unotify /bye /tmp/y > T: PID = 23185 > > T: about to mkdir("/bye") > S: got notification (ID 0xa81236b1d2f7b0f4) for PID 23185 > S: spoofing error response (Operation not supported) > S: sending response (flags = 0; val = 0; error = -95) > S: terminating ********** > T: ERROR: mkdir(2): Operation not supported > > T: about to mkdir("/tmp/y") > T: ERROR: mkdir(2): Function not implemented > > T: terminating > > Program source > #define _GNU_SOURCE > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > #include > > #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ > } while (0) Because I love macros, you can expand this to make it take a format string: #define errExit(fmt, ...) do { \ char __err[64]; \ strerror_r(errno, __err, sizeof(__err)); \ fprintf(stderr, fmt ": %s\n", ##__VA_ARG__, __err); \ exit(EXIT_FAILURE); \ } while (0) > > /* 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 suitably aligned. */ > 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; > } > > /* Receive a file descriptor on a connected UNIX domain socket. Returns > the received file descriptor on success, or -1 on error. */ > > static int > recvfd(int sockfd) > { > struct msghdr msgh; > struct iovec iov; > int data, fd; > ssize_t nr; > > /* Allocate a char buffer for the ancillary data. See the comments > in sendfd() */ > union { > char buf[CMSG_SPACE(sizeof(int))]; > struct cmsghdr align; > } controlMsg; > struct cmsghdr *cmsgp; > > /* The 'msg_name' field can be used to obtain the address of the > sending socket. However, we do not need this information. */ > > msgh.msg_name = NULL; > msgh.msg_namelen = 0; > > /* Specify buffer for receiving real data */ > > msgh.msg_iov = &iov; > msgh.msg_iovlen = 1; > iov.iov_base = &data; /* Real data is an 'int' */ > iov.iov_len = sizeof(int); > > /* Set 'msghdr' fields that describe ancillary data */ > > msgh.msg_control = controlMsg.buf; > msgh.msg_controllen = sizeof(controlMsg.buf); > > /* Receive real plus ancillary data; real data is ignored */ > > nr = recvmsg(sockfd, &msgh, 0); > if (nr == -1) > return -1; > > cmsgp = CMSG_FIRSTHDR(&msgh); > > /* Check the validity of the 'cmsghdr' */ > > if (cmsgp == NULL || > cmsgp->cmsg_len != CMSG_LEN(sizeof(int)) || > cmsgp->cmsg_level != SOL_SOCKET || > cmsgp->cmsg_type != SCM_RIGHTS) { > errno = EINVAL; > return -1; > } > > /* Return the received file descriptor to our caller */ > > memcpy(&fd, CMSG_DATA(cmsgp), sizeof(int)); > return fd; > } > > static void > sigchldHandler(int sig) > { > char *msg = "\tS: target has terminated; bye\n"; > > write(STDOUT_FILENO, msg, strlen(msg)); white space nit: extra space before "=" efficiency nit: strlen isn't needed, since it can be done with compile-time constant constants: char msg[] = "\tS: target has terminated; bye\n"; write(STDOUT_FILENO, msg, sizeof(msg) - 1); (some optimization levels may already replace the strlen a sizeof - 1) > _exit(EXIT_SUCCESS); > } > > static int > seccomp(unsigned int operation, unsigned int flags, void *args) > { > return syscall(__NR_seccomp, operation, flags, args); > } > > /* The following is the x86-64-specific BPF boilerplate code for checking > that the BPF program is running on the right architecture + ABI. At > completion of these instructions, the accumulator contains the system > call number. */ > > /* For the x32 ABI, all system call numbers have bit 30 set */ > > #define X32_SYSCALL_BIT 0x40000000 > > #define X86_64_CHECK_ARCH_AND_LOAD_SYSCALL_NR \ > BPF_STMT(BPF_LD | BPF_W | BPF_ABS, \ > (offsetof(struct seccomp_data, arch))), \ > BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 0, 2), \ > BPF_STMT(BPF_LD | BPF_W | BPF_ABS, \ > (offsetof(struct seccomp_data, nr))), \ > BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, X32_SYSCALL_BIT, 0, 1), \ > BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS) > > /* installNotifyFilter() installs a seccomp filter that generates > user-space notifications (SECCOMP_RET_USER_NOTIF) when the process > calls mkdir(2); the filter allows all other system calls. > > The function return value is a file descriptor from which the > user-space notifications can be fetched. */ > > static int > installNotifyFilter(void) > { > struct sock_filter filter[] = { > X86_64_CHECK_ARCH_AND_LOAD_SYSCALL_NR, > > /* mkdir() triggers notification to user-space supervisor */ > > BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mkdir, 0, 1), > BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_USER_NOTIF), > > /* Every other system call is allowed */ > > BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), > }; > > struct sock_fprog prog = { > .len = sizeof(filter) / sizeof(filter[0]), > .filter = filter, > }; > > /* Install the filter with the SECCOMP_FILTER_FLAG_NEW_LISTENER flag; > as a result, seccomp() returns a notification file descriptor. */ > > int notifyFd = seccomp(SECCOMP_SET_MODE_FILTER, > SECCOMP_FILTER_FLAG_NEW_LISTENER, &prog); > if (notifyFd == -1) > errExit("seccomp-install-notify-filter"); > > return notifyFd; > } > > /* Close a pair of sockets created by socketpair() */ > > static void > closeSocketPair(int sockPair[2]) > { > if (close(sockPair[0]) == -1) > errExit("closeSocketPair-close-0"); > if (close(sockPair[1]) == -1) > errExit("closeSocketPair-close-1"); > } > > /* Implementation of the target process; create a child process that: > > (1) installs a seccomp filter with the > SECCOMP_FILTER_FLAG_NEW_LISTENER flag; > (2) writes the seccomp notification file descriptor returned from > the previous step onto the UNIX domain socket, 'sockPair[0]'; > (3) calls mkdir(2) for each element of 'argv'. > > The function return value in the parent is the PID of the child > process; the child does not return from this function. */ > > static pid_t > targetProcess(int sockPair[2], char *argv[]) > { > pid_t targetPid = fork(); > if (targetPid == -1) > errExit("fork"); > > if (targetPid > 0) /* In parent, return PID of child */ > return targetPid; > > /* Child falls through to here */ > > printf("T: PID = %ld\n", (long) getpid()); > > /* Install seccomp filter(s) */ > > if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) > errExit("prctl"); > > int notifyFd = installNotifyFilter(); > > /* Pass the notification file descriptor to the tracing process over > a UNIX domain socket */ > > if (sendfd(sockPair[0], notifyFd) == -1) > errExit("sendfd"); > > /* Notification and socket FDs are no longer needed in target */ > > if (close(notifyFd) == -1) > errExit("close-target-notify-fd"); > > closeSocketPair(sockPair); > > /* Perform a mkdir() call for each of the command-line arguments */ > > for (char **ap = argv; *ap != NULL; ap++) { > printf("\nT: about to mkdir(\"%s\")\n", *ap); > > int s = mkdir(*ap, 0700); > if (s == -1) > perror("T: ERROR: mkdir(2)"); > else > printf("T: SUCCESS: mkdir(2) returned %d\n", s); > } > > printf("\nT: terminating\n"); > exit(EXIT_SUCCESS); > } > > /* Check that the notification ID provided by a SECCOMP_IOCTL_NOTIF_RECV > operation is still valid. It will no longer be valid if the process > has terminated. This operation can be used when accessing /proc/PID > files in the target process in order to avoid TOCTOU race conditions > where the PID that is returned by SECCOMP_IOCTL_NOTIF_RECV terminates > and is reused by another process. */ > > static void > checkNotificationIdIsValid(int notifyFd, uint64_t id) > { > if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_ID_VALID, &id) == -1) { > fprintf(stderr, "\tS: notification ID check: " > "target has terminated!!!\n"); > > exit(EXIT_FAILURE); And now you can do: errExit("\tS: notification ID check: " "target has terminated! ioctl"); ;) > } > } > > /* Access the memory of the target process in order to discover the > pathname that was given to mkdir() */ > > static bool > 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); > 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); > > /* Read bytes at the location containing the pathname argument > (i.e., the first argument) of the mkdir(2) call */ > > ssize_t nread = pread(procMemFd, path, len, req->data.args[0]); > if (nread == -1) > errExit("pread"); > > if (nread == 0) { > fprintf(stderr, "\tS: pread() of /proc/PID/mem " > "returned 0 (EOF)\n"); > exit(EXIT_FAILURE); > } > > if (close(procMemFd) == -1) > errExit("close-/proc/PID/mem"); > > /* We have no guarantees about what was in the memory of the target > process. We therefore treat the buffer returned by pread() as > untrusted input. The buffer should be terminated by a null byte; > if not, then we will trigger an error for the target process. */ > > for (int j = 0; j < nread; j++) > if (path[j] == ' ') This rendering typo (' ' vs '\0') ends up manifesting badly. ;) The man source shows: if (path[j] == \(aq\0\(aq) I think this needs to be \\0 ? Or it could also be a tested as: if (strnlen(path, nread) < nread) > return true; > > return false; > } > > /* 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]; > > /* 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"); > > /* When allocating the response buffer, we must allow for the fact > that the user-space binary may have been built with user-space > headers where 'struct seccomp_notif_resp' is bigger than the > response buffer expected by the (older) kernel. Therefore, we > allocate a buffer that is the maximum of the two sizes. This > ensures that if the supervisor places bytes into the response > structure that are past the response size that the kernel expects, > then the supervisor is not touching an invalid memory location. */ > > size_t resp_size = sizes.seccomp_notif_resp; > if (sizeof(struct seccomp_notif_resp) > resp_size) > resp_size = sizeof(struct seccomp_notif_resp); > > struct seccomp_notif_resp *resp = malloc(resp_size); > if (resp == NULL) > errExit("\tS: malloc"); > > /* Loop handling notifications */ > > for (;;) { > /* Wait for next notification, returning info in '*req' */ > > memset(req, 0, sizes.seccomp_notif); > if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_RECV, req) == -1) { > if (errno == EINTR) > continue; > errExit("Supervisor: ioctl-SECCOMP_IOCTL_NOTIF_RECV"); > } > > printf("\tS: got notification (ID %#llx) for PID %d\n", > req->id, req->pid); > > /* The only system call that can generate a notification event > is mkdir(2). Nevertheless, we check that the notified system > call is indeed mkdir() as kind of future-proofing of this > code in case the seccomp filter is later modified to > generate notifications for other system calls. */ > > if (req->data.nr != __NR_mkdir) { > printf("\tS: notification contained unexpected " > "system call number; bye!!!\n"); > exit(EXIT_FAILURE); > } > > bool pathOK = getTargetPathname(req, notifyFd, path, > sizeof(path)); > > /* Prepopulate some fields of the response */ > > resp->id = req->id; /* Response includes notification ID */ > resp->flags = 0; > resp->val = 0; > > /* If the target pathname was not valid, trigger an EINVAL error; > if the directory is in /tmp, then create it on behalf of the > supervisor; if the pathname starts with '.', tell the kernel > to let the target process execute the mkdir(); otherwise, give > an error for a directory pathname in any other location. */ > > if (!pathOK) { > resp->error = -EINVAL; > printf("\tS: spoofing error for invalid pathname (%s)\n", > strerror(-resp->error)); > } else if (strncmp(path, "/tmp/", strlen("/tmp/")) == 0) { > printf("\tS: executing: mkdir(\"%s\", %#llo)\n", > path, req->data.args[1]); > > if (mkdir(path, req->data.args[1]) == 0) { > resp->error = 0; /* "Success" */ > resp->val = strlen(path); /* Used as return value of > mkdir() in target */ > printf("\tS: success! spoofed return = %lld\n", > resp->val); > } 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) { > resp->error = resp->val = 0; > resp->flags = SECCOMP_USER_NOTIF_FLAG_CONTINUE; > printf("\tS: target can execute system call\n"); > } else { > resp->error = -EOPNOTSUPP; > printf("\tS: spoofing error response (%s)\n", > strerror(-resp->error)); > } > > /* Send a response to the notification */ > > printf("\tS: sending response " > "(flags = %#x; val = %lld; error = %d)\n", > resp->flags, resp->val, resp->error); > > if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_SEND, resp) == -1) { > if (errno == ENOENT) > printf("\tS: response failed with ENOENT; " > "perhaps target process's syscall was " > "interrupted by a signal?\n"); > else > perror("ioctl-SECCOMP_IOCTL_NOTIF_SEND"); > } > > /* If the pathname is just "/bye", then the supervisor > terminates. This allows us to see what happens if the > target process makes further calls to mkdir(2). */ > > if (strcmp(path, "/bye") == 0) { > printf("\tS: terminating **********\n"); > exit(EXIT_FAILURE); > } > } > } > > /* Implementation of the supervisor process: > > (1) obtains the notification file descriptor from 'sockPair[1]' > (2) handles notifications that arrive on that file descriptor. */ > > static void > supervisor(int sockPair[2]) > { > int notifyFd = recvfd(sockPair[1]); > if (notifyFd == -1) > errExit("recvfd"); > > closeSocketPair(sockPair); /* We no longer need the socket pair */ > > handleNotifications(notifyFd); > } > > int > main(int argc, char *argv[]) > { > int sockPair[2]; > > setbuf(stdout, NULL); > > if (argc < 2) { > fprintf(stderr, "At least one pathname argument is required\n"); > exit(EXIT_FAILURE); > } > > /* Create a UNIX domain socket that is used to pass the seccomp > notification file descriptor from the target process to the > supervisor process. */ > > if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockPair) == -1) > errExit("socketpair"); > > /* Create a child process--the "target"--that installs seccomp > filtering. The target process writes the seccomp notification > file descriptor onto 'sockPair[0]' and then calls mkdir(2) for > each directory in the command-line arguments. */ > > (void) targetProcess(sockPair, &argv[optind]); > > /* Catch SIGCHLD when the target terminates, so that the > supervisor can also terminate. */ > > struct sigaction sa; > sa.sa_handler = sigchldHandler; > sa.sa_flags = 0; > sigemptyset(&sa.sa_mask); > if (sigaction(SIGCHLD, &sa, NULL) == -1) > errExit("sigaction"); > > supervisor(sockPair); > > exit(EXIT_SUCCESS); > } > > SEE ALSO > ioctl(2), seccomp(2) > > A further example program can be found in the kernel source file > samples/seccomp/user-trap.c. > > Linux 2020-10-01 SECCOMP_USER_NOTIF(2) Thank you so much for this documentation and example! :) -Kees [1] https://git.kernel.org/linus/dfe719fef03d752f1682fa8aeddf30ba501c8555 [2] https://lore.kernel.org/lkml/CAG48ez3kpEDO1x_HfvOM2R9M78Ach9O_4+Pjs-vLLfqvZL+13A@mail.gmail.com/ [3] https://lore.kernel.org/lkml/CAGXu5jKzif=vp6gn5ZtrTx-JTN367qFphobnt9s=awbaafwoUw@mail.gmail.com/ -- Kees Cook 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=-8.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham 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 E86FAC4363A for ; Mon, 26 Oct 2020 00:19:56 +0000 (UTC) Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (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 4A20D223BE for ; Mon, 26 Oct 2020 00:19:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="dDktHPh1" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4A20D223BE Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=containers-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id CA9B585C62; Mon, 26 Oct 2020 00:19:55 +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 brU9xvbT35r2; Mon, 26 Oct 2020 00:19:52 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by fraxinus.osuosl.org (Postfix) with ESMTP id 9183285C47; Mon, 26 Oct 2020 00:19:52 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7D156C088B; Mon, 26 Oct 2020 00:19:52 +0000 (UTC) Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2F6CFC0051 for ; Mon, 26 Oct 2020 00:19:51 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 1703586785 for ; Mon, 26 Oct 2020 00:19:51 +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 4x56sU5w1ZA3 for ; Mon, 26 Oct 2020 00:19:47 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by whitealder.osuosl.org (Postfix) with ESMTPS id 725378677F for ; Mon, 26 Oct 2020 00:19:47 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id t14so5114582pgg.1 for ; Sun, 25 Oct 2020 17:19:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=ZZ2a4aOmPjyQjPWSse0Y9NGMYSnUn8G3zEmlqVOLMFc=; b=dDktHPh1RGN624IjgTdeCk991cxycw5WvnOSaWkqtnSZAjdcKDbvAP2OF3D1ECVjAl eqepqpN0AxzpG3OWPp5xHKcAeXyl4Z4ZV26WQEUl4Bra0e9/GHYQjLogFkam4oQY4xKD QSPEN+Q0tvE02IyLA0WOV0Fa4X6UQB6YWZP+w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=ZZ2a4aOmPjyQjPWSse0Y9NGMYSnUn8G3zEmlqVOLMFc=; b=VCyJPLtdZo03F7LoDvgtgjfFwys+csdk3MYB7Mk5ypM655iPG7r1ot9HFU9glZceqJ BRKeEGaub4IMdR2jIuzhbXa/2Jqbjkk0e2QWPt5e2VpGb+LP+b9GXHNioT1MReDjkjJM oNefgm6+PAEy2s1ZD4n3dFslSsVR9o0Twuv6j1AWw2OAUBZ+0wnfMA6wAzK6LSkO7cXq WqYE35xjcUiN7LKIQjkzMI5RRrlE7t426np3+mkfGJK2vN9oHg6eEu9DOfIk2stHYq+F wy0sEVlOSiaFtF6cega31izew+jIkKXOroW8XYylpeqIF5TgyPmDYFsVenq0Ai1Rk9Fp Ol2Q== X-Gm-Message-State: AOAM532bohobkqIjTtWuTBYb5ywRTBkvpsfCvJIDNlY3gKQFbYYTPkVx KEjDR+WtFAMCEKmnZ33sFNOYYQ== X-Google-Smtp-Source: ABdhPJxjlEz21at3a78MBRzgHi7GljicYmNqfcTeN3KUjQ8xXnALihf+MYh/wD7/glH3jV3TUCgP+Q== X-Received: by 2002:a62:5c06:0:b029:160:1b43:14ed with SMTP id q6-20020a625c060000b02901601b4314edmr9205604pfb.11.1603671586067; Sun, 25 Oct 2020 17:19:46 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id w17sm10041350pjq.42.2020.10.25.17.19.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Oct 2020 17:19:44 -0700 (PDT) Date: Sun, 25 Oct 2020 17:19:43 -0700 From: Kees Cook To: "Michael Kerrisk (man-pages)" Subject: Re: For review: seccomp_user_notif(2) manual page Message-ID: <202010250759.F9745E0B6@keescook> References: <45f07f17-18b6-d187-0914-6f341fe90857@gmail.com> <202009301632.9C6A850272@keescook> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Cc: linux-man , Song Liu , wad@chromium.org, Robert Sesek , Daniel Borkmann , Jann Horn , Linux Containers , lkml , Alexei Starovoitov , Giuseppe Scrivano , bpf@vger.kernel.org, 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" T24gVGh1LCBPY3QgMTUsIDIwMjAgYXQgMDE6MjQ6MDNQTSArMDIwMCwgTWljaGFlbCBLZXJyaXNr IChtYW4tcGFnZXMpIHdyb3RlOgo+IE9uIDEwLzEvMjAgMTozOSBBTSwgS2VlcyBDb29rIHdyb3Rl Ogo+ID4gSSdsbCBjb21tZW50IG1vcmUgbGF0ZXIsIGJ1dCBJJ3ZlIHJ1biBvdXQgb2YgdGltZSB0 b2RheSBhbmQgSSBkaWRuJ3Qgc2VlCj4gPiBhbnlvbmUgbWVudGlvbiB0aGlzIGRldGFpbCB5ZXQg aW4gdGhlIGV4aXN0aW5nIHRocmVhZHMuLi4gOikKPiAKPiBMYXRlciBuZXZlciBjYW1lIDotKS4g QnV0LCBJIGhvcGUgeW91IG1heSBoYXZlIGNvbW1lbnRzIGZvciB0aGUgCj4gbmV4dCBkcmFmdCwg d2hpY2ggSSB3aWxsIHNlbmQgb3V0IHNvb24uCgpMYXRlciBpcyBub3csIGFuZCBTb29uIGFwcHJv YWNoZXMhCgpJIGZpbmFsbHkgY2F1Z2h0IHVwIGFuZCByZWFkIHRocm91Z2ggdGhpcyB3aG9sZSB0 aHJlYWQuIFRoYW5rIHlvdSBhbGwKZm9yIHRoZSBidWcgZml4WzFdLCBhbmQgSSdtIGxvb2tpbmcg Zm9yd2FyZCB0byBtb3JlWzJdLiA6KQoKRm9yIG15IHJlcGx5IEkgZmlndXJlZCBJJ2QgYmFzZSBp dCBvbiB0aGUgY3VycmVudCBkcmFmdCwgc28gaGVyZSdzIGEKc2ltdWxhdGVkIHF1b3RlIGJhc2Vk IG9uIHRoZSBzZWNjb21wX3VzZXJfbm90aWYgYnJhbmNoIG9mCmh0dHBzOi8vZ2l0Lmtlcm5lbC5v cmcvcHViL3NjbS9kb2NzL21hbi1wYWdlcy9tYW4tcGFnZXMuZ2l0CnRocm91Z2ggY29tbWl0IDcx MTAxMTU4ZmUzMzBhZjVhMjY1NTI0NDdhMGJiNDMzYjY5ZTE1YjcKJCBDT0xVTU5TPTc1IG1hbiAt LW5oIC0tbmogbWFuMi9zZWNjb21wX3VzZXJfbm90aWYuMiB8IHNlZCAncy9eLz4gLycKCk9uIFN1 biwgT2N0IDI1LCAyMDIwIGF0IDAxOjU0OjA1UE0gKzAxMDAsIE1pY2hhZWwgS2VycmlzayAobWFu LXBhZ2VzKSB3cm90ZToKPiBTRUNDT01QX1VTRVJfTk9USUYoMikgICBMaW51eCBQcm9ncmFtbWVy J3MgTWFudWFsICAgU0VDQ09NUF9VU0VSX05PVElGKDIpCj4gCj4gTkFNRQo+ICAgICAgICBzZWNj b21wX3VzZXJfbm90aWYgLSBTZWNjb21wIHVzZXItc3BhY2Ugbm90aWZpY2F0aW9uIG1lY2hhbmlz bQo+IAo+IFNZTk9QU0lTCj4gICAgICAgICNpbmNsdWRlIDxsaW51eC9zZWNjb21wLmg+Cj4gICAg ICAgICNpbmNsdWRlIDxsaW51eC9maWx0ZXIuaD4KPiAgICAgICAgI2luY2x1ZGUgPGxpbnV4L2F1 ZGl0Lmg+Cj4gCj4gICAgICAgIGludCBzZWNjb21wKHVuc2lnbmVkIGludCBvcGVyYXRpb24sIHVu c2lnbmVkIGludCBmbGFncywgdm9pZCAqYXJncyk7Cj4gCj4gICAgICAgICNpbmNsdWRlIDxzeXMv aW9jdGwuaD4KPiAKPiAgICAgICAgaW50IGlvY3RsKGludCBmZCwgU0VDQ09NUF9JT0NUTF9OT1RJ Rl9SRUNWLAo+ICAgICAgICAgICAgICAgICAgc3RydWN0IHNlY2NvbXBfbm90aWYgKnJlcSk7Cj4g ICAgICAgIGludCBpb2N0bChpbnQgZmQsIFNFQ0NPTVBfSU9DVExfTk9USUZfU0VORCwKPiAgICAg ICAgICAgICAgICAgIHN0cnVjdCBzZWNjb21wX25vdGlmX3Jlc3AgKnJlc3ApOwo+ICAgICAgICBp bnQgaW9jdGwoaW50IGZkLCBTRUNDT01QX0lPQ1RMX05PVElGX0lEX1ZBTElELCBfX3U2NCAqaWQp Owo+IAo+IERFU0NSSVBUSU9OCj4gICAgICAgIFRoaXMgcGFnZSBkZXNjcmliZXMgdGhlIHVzZXIt c3BhY2Ugbm90aWZpY2F0aW9uIG1lY2hhbmlzbSBwcm92aWRlZAo+ICAgICAgICBieSB0aGUgU2Vj dXJlIENvbXB1dGluZyAoc2VjY29tcCkgZmFjaWxpdHkuICBBcyB3ZWxsIGFzIHRoZSB1c2Ugb2YK PiAgICAgICAgdGhlIFNFQ0NPTVBfRklMVEVSX0ZMQUdfTkVXX0xJU1RFTkVSIGZsYWcsIHRoZQo+ ICAgICAgICBTRUNDT01QX1JFVF9VU0VSX05PVElGIGFjdGlvbiB2YWx1ZSwgYW5kIHRoZQo+ICAg ICAgICBTRUNDT01QX0dFVF9OT1RJRl9TSVpFUyBvcGVyYXRpb24gZGVzY3JpYmVkIGluIHNlY2Nv bXAoMiksIHRoaXMKPiAgICAgICAgbWVjaGFuaXNtIGludm9sdmVzIHRoZSB1c2Ugb2YgYSBudW1i ZXIgb2YgcmVsYXRlZCBpb2N0bCgyKQo+ICAgICAgICBvcGVyYXRpb25zIChkZXNjcmliZWQgYmVs b3cpLgo+IAo+ICAgIE92ZXJ2aWV3Cj4gICAgICAgIEluIGNvbnZlbnRpb25hbCB1c2FnZSBvZiBh IHNlY2NvbXAgZmlsdGVyLCB0aGUgZGVjaXNpb24gYWJvdXQgaG93Cj4gICAgICAgIHRvIHRyZWF0 IGEgc3lzdGVtIGNhbGwgaXMgbWFkZSBieSB0aGUgZmlsdGVyIGl0c2VsZi4gIEJ5IGNvbnRyYXN0 LAo+ICAgICAgICB0aGUgdXNlci1zcGFjZSBub3RpZmljYXRpb24gbWVjaGFuaXNtIGFsbG93cyB0 aGUgc2VjY29tcCBmaWx0ZXIgdG8KPiAgICAgICAgZGVsZWdhdGUgdGhlIGhhbmRsaW5nIG9mIHRo ZSBzeXN0ZW0gY2FsbCB0byBhbm90aGVyIHVzZXItc3BhY2UKPiAgICAgICAgcHJvY2Vzcy4gIE5v dGUgdGhhdCB0aGlzIG1lY2hhbmlzbSBpcyBleHBsaWNpdGx5IG5vdCBpbnRlbmRlZCBhcyBhCj4g ICAgICAgIG1ldGhvZCBpbXBsZW1lbnRpbmcgc2VjdXJpdHkgcG9saWN5OyBzZWUgTk9URVMuCj4g Cj4gICAgICAgIEluIHRoZSBkaXNjdXNzaW9uIHRoYXQgZm9sbG93cywgdGhlIHRocmVhZChzKSBv biB3aGljaCB0aGUgc2VjY29tcAo+ICAgICAgICBmaWx0ZXIgaXMgaW5zdGFsbGVkIGlzIChhcmUp IHJlZmVycmVkIHRvIGFzIHRoZSB0YXJnZXQsIGFuZCB0aGUKPiAgICAgICAgcHJvY2VzcyB0aGF0 IGlzIG5vdGlmaWVkIGJ5IHRoZSB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbiBtZWNoYW5pc20KPiAg ICAgICAgaXMgcmVmZXJyZWQgdG8gYXMgdGhlIHN1cGVydmlzb3IuCj4gCj4gICAgICAgIEEgc3Vp dGFibHkgcHJpdmlsZWdlZCBzdXBlcnZpc29yIGNhbiB1c2UgdGhlIHVzZXItc3BhY2UKPiAgICAg ICAgbm90aWZpY2F0aW9uIG1lY2hhbmlzbSB0byBwZXJmb3JtIGFjdGlvbnMgb24gYmVoYWxmIG9m IHRoZSB0YXJnZXQuCj4gICAgICAgIFRoZSBhZHZhbnRhZ2Ugb2YgdGhlIHVzZXItc3BhY2Ugbm90 aWZpY2F0aW9uIG1lY2hhbmlzbSBpcyB0aGF0IHRoZQo+ICAgICAgICBzdXBlcnZpc29yIHdpbGwg dXN1YWxseSBiZSBhYmxlIHRvIHJldHJpZXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZQo+ICAgICAg ICB0YXJnZXQgYW5kIHRoZSBwZXJmb3JtZWQgc3lzdGVtIGNhbGwgdGhhdCB0aGUgc2VjY29tcCBm aWx0ZXIKPiAgICAgICAgaXRzZWxmIGNhbm5vdC4gIChBIHNlY2NvbXAgZmlsdGVyIGlzIGxpbWl0 ZWQgaW4gdGhlIGluZm9ybWF0aW9uIGl0Cj4gICAgICAgIGNhbiBvYnRhaW4gYW5kIHRoZSBhY3Rp b25zIHRoYXQgaXQgY2FuIHBlcmZvcm0gYmVjYXVzZSBpdCBpcwo+ICAgICAgICBydW5uaW5nIG9u IGEgdmlydHVhbCBtYWNoaW5lIGluc2lkZSB0aGUga2VybmVsLikKPiAKPiAgICAgICAgQW4gb3Zl cnZpZXcgb2YgdGhlIHN0ZXBzIHBlcmZvcm1lZCBieSB0aGUgdGFyZ2V0IGFuZCB0aGUKPiAgICAg ICAgc3VwZXJ2aXNvciBpcyBhcyBmb2xsb3dzOgo+IAo+ICAgICAgICAxLiBUaGUgdGFyZ2V0IGVz dGFibGlzaGVzIGEgc2VjY29tcCBmaWx0ZXIgaW4gdGhlIHVzdWFsIG1hbm5lciwKPiAgICAgICAg ICAgYnV0IHdpdGggdHdvIGRpZmZlcmVuY2VzOgo+IAo+ICAgICAgICAgICDigKIgVGhlIHNlY2Nv bXAoMikgZmxhZ3MgYXJndW1lbnQgaW5jbHVkZXMgdGhlIGZsYWcKPiAgICAgICAgICAgICBTRUND T01QX0ZJTFRFUl9GTEFHX05FV19MSVNURU5FUi4gIENvbnNlcXVlbnRseSwgdGhlIHJldHVybgo+ ICAgICAgICAgICAgIHZhbHVlICBvZiB0aGUgKHN1Y2Nlc3NmdWwpIHNlY2NvbXAoMikgY2FsbCBp cyBhIG5ldwoKbml0OiBleHRyYSBzcGFjZQoKPiAgICAgICAgICAgICAibGlzdGVuaW5nIiBmaWxl IGRlc2NyaXB0b3IgdGhhdCBjYW4gYmUgdXNlZCB0byByZWNlaXZlCj4gICAgICAgICAgICAgbm90 aWZpY2F0aW9ucy4gIE9ubHkgb25lICJsaXN0ZW5pbmciIHNlY2NvbXAgZmlsdGVyIGNhbiBiZQo+ ICAgICAgICAgICAgIGluc3RhbGxlZCBmb3IgYSB0aHJlYWQuCgpJIGxpa2UgdGhpcyBsaW1pdGF0 aW9uLCBidXQgSSBleHBlY3QgdGhhdCBpdCdsbCBuZWVkIHRvIGNoYW5nZSBpbiB0aGUKZnV0dXJl LiBFdmVuIHdpdGggTFNNcywgd2Ugc2VlIHRoZSBuZWVkIGZvciBhcmJpdHJhcnkgc3RhY2tpbmcs IGFuZCB0aGUKaWRlYSBvZiB0aGVyZSBiZWluZyBvbmx5IDEgc3VwZXJ2aXNvciB3aWxsIGV2ZW50 dWFsbHkgYnJlYWsgZG93bi4gUmlnaHQKbm93IHRoZXJlIGlzIG9ubHkgMSBiZWNhdXNlIG9ubHkg Y29udGFpbmVyIG1hbmFnZXJzIGFyZSB1c2luZyB0aGlzCmZlYXR1cmUuIEJ1dCBpZiBzb21lIGRh ZW1vbiBzdGFydHMgdXNpbmcgaXQgdG8gaXNvbGF0ZSBzb21lIHRocmVhZCwKc3VkZGVubHkgaXQg bWlnaHQgYnJlYWsgaWYgYSBjb250YWluZXIgbWFuYWdlciBpcyB0cnlpbmcgdG8gbGlzdGVuIHRv IGl0CnRvbywgZXRjLiBJIGV4cGVjdCBpdCB3b24ndCBiZSBuZWVkZWQgc29vbiwgYnV0IEkgZG8g dGhpbmsgaXQnbGwgY2hhbmdlLgoKPiAKPiAgICAgICAgICAg4oCiIEluIGNhc2VzIHdoZXJlIGl0 IGlzIGFwcHJvcHJpYXRlLCB0aGUgc2VjY29tcCBmaWx0ZXIgcmV0dXJucwo+ICAgICAgICAgICAg IHRoZSBhY3Rpb24gdmFsdWUgU0VDQ09NUF9SRVRfVVNFUl9OT1RJRi4gIFRoaXMgcmV0dXJuIHZh bHVlCj4gICAgICAgICAgICAgd2lsbCB0cmlnZ2VyIGEgbm90aWZpY2F0aW9uIGV2ZW50Lgo+IAo+ ICAgICAgICAyLiBJbiBvcmRlciB0aGF0IHRoZSBzdXBlcnZpc29yIGNhbiBvYnRhaW4gbm90aWZp Y2F0aW9ucyB1c2luZyB0aGUKPiAgICAgICAgICAgbGlzdGVuaW5nIGZpbGUgZGVzY3JpcHRvciwg KGEgZHVwbGljYXRlIG9mKSB0aGF0IGZpbGUKPiAgICAgICAgICAgZGVzY3JpcHRvciBtdXN0IGJl IHBhc3NlZCBmcm9tIHRoZSB0YXJnZXQgdG8gdGhlIHN1cGVydmlzb3IuCgpZZXQgYW5vdGhlciBy ZWFzb24gdG8gaGF2ZSBhbiAiYWN0aXZhdGUgb24gZXhlYyIgbW9kZSBmb3Igc2VjY29tcC4gV2l0 aApub19uZXdfcHJpdnMgX25vdF8gYmVpbmcgZGVsYXllZCBpbiBzdWNoIGEgd2F5LCBJIHRoaW5r IGl0J2QgYmUgc2FmZSB0bwphZGQuIFRoZSBzdXBlcnZpc29yIHdvdWxkIGdldCB0aGUgZmQgaW1t ZWRpYXRlbHksIGFuZCB0aGVuIG9uY2UgaXQKZm9yay9leGVjZWQgc3VkZGVubHkgdGhlIHdob2xl IHRoaW5nIHdvdWxkIGFjdGl2YXRlLCBhbmQgbm8gZmQgcGFzc2luZwpuZWVkZWQuCgpUaGUgIm9u IGV4ZWMiIGJvdW5kYXJ5IGlzIHJlYWxseSBvbmx5IG5lZWRlZCBmb3Igb2JsaXZpb3VzIHRhcmdl dHMuIEZvcgphIGNvb3JkaW5hdGVkIHRhcmdldCwgSSd2ZSB0aG91Z2h0IGl0IG1pZ2h0IGJlIG5p Y2UgdG8gaGF2ZSBhbiBhcmJpdHJhcnkKImdvIiBwb2ludCwgd2hlcmUgdGhlIHRhcmdldCBjb3Vs ZCBjYWxsIHNlY2NvbXAoKSB3aXRoIHNvbWV0aGluZyBsaWtlIGEKU0VDQ09NUF9BQ1RJVkFURV9E RUxBWUVEX0ZJTFRFUlMgb3BlcmF0aW9uLiBUaGlzIGxldHMgYW55IHByb2Nlc3MKaW5pdGlhbGl6 YXRpb24gaGFwcGVuIHRoYXQgbWlnaHQgbmVlZCB0byBkbyB0aGluZ3MgdGhhdCB3b3VsZCBiZSBi bG9ja2VkCmJ5IGZpbHRlcnMsIGV0Yy4KCkJlZm9yZToKCglmb3JrCglpbnN0YWxsIHNvbWUgZmls dGVycyB0aGF0IGRvbid0IGJsb2NrIGluaXRpYWxpemF0aW9uCglleGVjCglkbyBzb21lIGluaXRp YWxpemF0aW9uCglpbnN0YWxsIG1vcmUgZmlsdGVycywgbWF5YmUgYmxvY2sgZXhlYywgc2VjY29t cAoJcnVuCgpBZnRlcjoKCglmb3JrCglpbnN0YWxsIGRlbGF5ZWQgZmlsdGVycwoJZXhlYwoJZG8g c29tZSBpbml0aWFsaXphdGlvbgoJYWN0aXZhdGUgZGVsYXllZCBmaWx0ZXJzCglydW4KCkluIHBy YWN0aWNlLCB0aGUgdHdvLXN0YWdlIGZpbHRlciBhcHBsaWNhdGlvbiBoYXMgYmVlbiBmaW5lLCBp Zgpzb21ldGltZXMgYSBiaXQgY29tcGxleCAoZS5nLiBmb3IgdXNlcl9ub3RpZiwgImRvIHNvbWUg aW5pdGlhbGl6YXRpb24iCmluY2x1ZGVzIGZpZ3VyaW5nIG91dCBob3cgdG8gcGFzcyB0aGUgZmQg YmFjayB0byB0aGUgc3VwZXJ2aXNvciwgZXRjKS4KCj4gICAgICAgICAgIE9uZSB3YXkgaW4gd2hp Y2ggdGhpcyBjb3VsZCBiZSBkb25lIGlzIGJ5IHBhc3NpbmcgdGhlIGZpbGUKPiAgICAgICAgICAg ZGVzY3JpcHRvciBvdmVyIGEgVU5JWCBkb21haW4gc29ja2V0IGNvbm5lY3Rpb24gYmV0d2VlbiB0 aGUKPiAgICAgICAgICAgdGFyZ2V0IGFuZCB0aGUgc3VwZXJ2aXNvciAodXNpbmcgdGhlIFNDTV9S SUdIVFMgYW5jaWxsYXJ5Cj4gICAgICAgICAgIG1lc3NhZ2UgdHlwZSBkZXNjcmliZWQgaW4gdW5p eCg3KSkuCj4gCj4gICAgICAgIDMuIFRoZSBzdXBlcnZpc29yIHdpbGwgcmVjZWl2ZSBub3RpZmlj YXRpb24gZXZlbnRzIG9uIHRoZQo+ICAgICAgICAgICBsaXN0ZW5pbmcgZmlsZSBkZXNjcmlwdG9y LiAgVGhlc2UgZXZlbnRzIGFyZSByZXR1cm5lZCBhcwo+ICAgICAgICAgICBzdHJ1Y3R1cmVzIG9m IHR5cGUgc2VjY29tcF9ub3RpZi4gIEJlY2F1c2UgdGhpcyBzdHJ1Y3R1cmUgYW5kCj4gICAgICAg ICAgIGl0cyBzaXplIG1heSBldm9sdmUgb3ZlciBrZXJuZWwgdmVyc2lvbnMsIHRoZSBzdXBlcnZp c29yIG11c3QKPiAgICAgICAgICAgZmlyc3QgZGV0ZXJtaW5lIHRoZSBzaXplIG9mIHRoaXMgc3Ry dWN0dXJlIHVzaW5nIHRoZSBzZWNjb21wKDIpCj4gICAgICAgICAgIFNFQ0NPTVBfR0VUX05PVElG X1NJWkVTIG9wZXJhdGlvbiwgd2hpY2ggcmV0dXJucyBhIHN0cnVjdHVyZSBvZgo+ICAgICAgICAg ICB0eXBlIHNlY2NvbXBfbm90aWZfc2l6ZXMuICBUaGUgc3VwZXJ2aXNvciBhbGxvY2F0ZXMgYSBi dWZmZXIgb2YKPiAgICAgICAgICAgc2l6ZSBzZWNjb21wX25vdGlmX3NpemVzLnNlY2NvbXBfbm90 aWYgYnl0ZXMgdG8gcmVjZWl2ZQo+ICAgICAgICAgICBub3RpZmljYXRpb24gZXZlbnRzLiAgSW4g YWRkaXRpb24sdGhlIHN1cGVydmlzb3IgYWxsb2NhdGVzCj4gICAgICAgICAgIGFub3RoZXIgYnVm ZmVyIG9mIHNpemUgc2VjY29tcF9ub3RpZl9zaXplcy5zZWNjb21wX25vdGlmX3Jlc3AKPiAgICAg ICAgICAgYnl0ZXMgZm9yIHRoZSByZXNwb25zZSAoYSBzdHJ1Y3Qgc2VjY29tcF9ub3RpZl9yZXNw IHN0cnVjdHVyZSkKPiAgICAgICAgICAgdGhhdCBpdCB3aWxsIHByb3ZpZGUgdG8gdGhlIGtlcm5l bCAoYW5kIHRodXMgdGhlIHRhcmdldCkuCj4gCj4gICAgICAgIDQuIFRoZSB0YXJnZXQgdGhlbiBw ZXJmb3JtcyBpdHMgd29ya2xvYWQsIHdoaWNoIGluY2x1ZGVzIHN5c3RlbQo+ICAgICAgICAgICBj YWxscyB0aGF0IHdpbGwgYmUgY29udHJvbGxlZCBieSB0aGUgc2VjY29tcCBmaWx0ZXIuICBXaGVu ZXZlcgo+ICAgICAgICAgICBvbmUgb2YgdGhlc2Ugc3lzdGVtIGNhbGxzIGNhdXNlcyB0aGUgZmls dGVyIHRvIHJldHVybiB0aGUKPiAgICAgICAgICAgU0VDQ09NUF9SRVRfVVNFUl9OT1RJRiBhY3Rp b24gdmFsdWUsIHRoZSBrZXJuZWwgZG9lcyBub3QgKHlldCkKPiAgICAgICAgICAgZXhlY3V0ZSB0 aGUgc3lzdGVtIGNhbGw7IGluc3RlYWQsIGV4ZWN1dGlvbiBvZiB0aGUgdGFyZ2V0IGlzCj4gICAg ICAgICAgIHRlbXBvcmFyaWx5IGJsb2NrZWQgaW5zaWRlIHRoZSBrZXJuZWwgKGluIGEgc2xlZXAg c3RhdGUgdGhhdCBpcwo+ICAgICAgICAgICBpbnRlcnJ1cHRpYmxlIGJ5IHNpZ25hbHMpIGFuZCBh IG5vdGlmaWNhdGlvbiBldmVudCBpcyBnZW5lcmF0ZWQKPiAgICAgICAgICAgb24gdGhlIGxpc3Rl bmluZyBmaWxlIGRlc2NyaXB0b3IuCj4gCj4gICAgICAgIDUuIFRoZSBzdXBlcnZpc29yIGNhbiBu b3cgcmVwZWF0ZWRseSBtb25pdG9yIHRoZSBsaXN0ZW5pbmcgZmlsZQo+ICAgICAgICAgICBkZXNj cmlwdG9yIGZvciBTRUNDT01QX1JFVF9VU0VSX05PVElGLXRyaWdnZXJlZCBldmVudHMuICBUbyBk bwo+ICAgICAgICAgICB0aGlzLCB0aGUgc3VwZXJ2aXNvciB1c2VzIHRoZSBTRUNDT01QX0lPQ1RM X05PVElGX1JFQ1YgaW9jdGwoMikKPiAgICAgICAgICAgb3BlcmF0aW9uIHRvIHJlYWQgaW5mb3Jt YXRpb24gYWJvdXQgYSBub3RpZmljYXRpb24gZXZlbnQ7IHRoaXMKPiAgICAgICAgICAgb3BlcmF0 aW9uIGJsb2NrcyB1bnRpbCBhbiBldmVudCBpcyBhdmFpbGFibGUuICBUaGUgb3BlcmF0aW9uCj4g ICAgICAgICAgIHJldHVybnMgYSBzZWNjb21wX25vdGlmIHN0cnVjdHVyZSBjb250YWluaW5nIGlu Zm9ybWF0aW9uIGFib3V0Cj4gICAgICAgICAgIHRoZSBzeXN0ZW0gY2FsbCB0aGF0IGlzIGJlaW5n IGF0dGVtcHRlZCBieSB0aGUgdGFyZ2V0Lgo+IAo+ICAgICAgICA2LiBUaGUgc2VjY29tcF9ub3Rp ZiBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgdGhlCj4gICAgICAgICAgIFNFQ0NPTVBfSU9DVExfTk9U SUZfUkVDViBvcGVyYXRpb24gaW5jbHVkZXMgdGhlIHNhbWUKPiAgICAgICAgICAgaW5mb3JtYXRp b24gKGEgc2VjY29tcF9kYXRhIHN0cnVjdHVyZSkgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZQo+ICAg ICAgICAgICBzZWNjb21wIGZpbHRlci4gIFRoaXMgaW5mb3JtYXRpb24gYWxsb3dzIHRoZSBzdXBl cnZpc29yIHRvCj4gICAgICAgICAgIGRpc2NvdmVyIHRoZSBzeXN0ZW0gY2FsbCBudW1iZXIgYW5k IHRoZSBhcmd1bWVudHMgZm9yIHRoZQo+ICAgICAgICAgICB0YXJnZXQncyBzeXN0ZW0gY2FsbC4g IEluIGFkZGl0aW9uLCB0aGUgbm90aWZpY2F0aW9uIGV2ZW50Cj4gICAgICAgICAgIGNvbnRhaW5z IHRoZSBJRCBvZiB0aGUgdGhyZWFkIHRoYXQgdHJpZ2dlcmVkIHRoZSBub3RpZmljYXRpb24uCgpT aG91bGQgImNvb2tpZSIgYmUgYXQgbGVhc3QgbmFtZWQgaGVyZSwganVzdCB0byBwcm92aWRlIGEg Yml0IG1vcmUKY29udGV4dCBmb3Igd2hlbiBpdCBpcyBtZW50aW9uZWQgaW4gOCBiZWxvdz8gRS5n LjoKCgkJCSAgICAgICAuLi4gSW4gYWRkaXRpb24sIHRoZSBub3RpZmljYXRpb24gZXZlbnQKCSAg ICBjb250YWlucyB0aGUgdHJpZ2dlcmluZyB0aHJlYWQncyBJRCBhbmQgYSB1bmlxdWUgY29va2ll IHRvIGJlCgkgICAgdXNlZCBpbiBzdWJzZXF1ZW50IFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFM SUQgYW5kCgkgICAgU0VDQ09NUF9JT0NUTF9OT1RJRl9TRU5EIG9wZXJhdGlvbnMuCgo+IAo+ICAg ICAgICAgICBUaGUgaW5mb3JtYXRpb24gaW4gdGhlIG5vdGlmaWNhdGlvbiBjYW4gYmUgdXNlZCB0 byBkaXNjb3ZlciB0aGUKPiAgICAgICAgICAgdmFsdWVzIG9mIHBvaW50ZXIgYXJndW1lbnRzIGZv ciB0aGUgdGFyZ2V0J3Mgc3lzdGVtIGNhbGwuCj4gICAgICAgICAgIChUaGlzIGlzIHNvbWV0aGlu ZyB0aGF0IGNhbid0IGJlIGRvbmUgZnJvbSB3aXRoaW4gYSBzZWNjb21wCj4gICAgICAgICAgIGZp bHRlci4pICBPbmUgd2F5IGluIHdoaWNoIHRoZSBzdXBlcnZpc29yIGNhbiBkbyB0aGlzIGlzIHRv Cj4gICAgICAgICAgIG9wZW4gdGhlIGNvcnJlc3BvbmRpbmcgL3Byb2MvW3RpZF0vbWVtIGZpbGUg KHNlZSBwcm9jKDUpKSBhbmQKPiAgICAgICAgICAgcmVhZCBieXRlcyBmcm9tIHRoZSBsb2NhdGlv biB0aGF0IGNvcnJlc3BvbmRzIHRvIG9uZSBvZiB0aGUKPiAgICAgICAgICAgcG9pbnRlciBhcmd1 bWVudHMgd2hvc2UgdmFsdWUgaXMgc3VwcGxpZWQgaW4gdGhlIG5vdGlmaWNhdGlvbgo+ICAgICAg ICAgICBldmVudC4gIChUaGUgc3VwZXJ2aXNvciBtdXN0IGJlIGNhcmVmdWwgdG8gYXZvaWQgYSBy YWNlCj4gICAgICAgICAgIGNvbmRpdGlvbiB0aGF0IGNhbiBvY2N1ciB3aGVuIGRvaW5nIHRoaXM7 IHNlZSB0aGUgZGVzY3JpcHRpb24KPiAgICAgICAgICAgb2YgdGhlIFNFQ0NPTVBfSU9DVExfTk9U SUZfSURfVkFMSUQgaW9jdGwoMikgb3BlcmF0aW9uIGJlbG93LikKPiAgICAgICAgICAgSW4gYWRk aXRpb24sIHRoZSBzdXBlcnZpc29yIGNhbiBhY2Nlc3Mgb3RoZXIgc3lzdGVtIGluZm9ybWF0aW9u Cj4gICAgICAgICAgIHRoYXQgaXMgdmlzaWJsZSBpbiB1c2VyIHNwYWNlIGJ1dCB3aGljaCBpcyBu b3QgYWNjZXNzaWJsZSBmcm9tCj4gICAgICAgICAgIGEgc2VjY29tcCBmaWx0ZXIuCj4gCj4gICAg ICAgIDcuIEhhdmluZyBvYnRhaW5lZCBpbmZvcm1hdGlvbiBhcyBwZXIgdGhlIHByZXZpb3VzIHN0 ZXAsIHRoZQo+ICAgICAgICAgICBzdXBlcnZpc29yIG1heSB0aGVuIGNob29zZSB0byBwZXJmb3Jt IGFuIGFjdGlvbiBpbiByZXNwb25zZSB0bwo+ICAgICAgICAgICB0aGUgdGFyZ2V0J3Mgc3lzdGVt IGNhbGwgKHdoaWNoLCBhcyBub3RlZCBhYm92ZSwgaXMgbm90Cj4gICAgICAgICAgIGV4ZWN1dGVk IHdoZW4gdGhlIHNlY2NvbXAgZmlsdGVyIHJldHVybnMgdGhlCj4gICAgICAgICAgIFNFQ0NPTVBf UkVUX1VTRVJfTk9USUYgYWN0aW9uIHZhbHVlKS4KPiAKPiAgICAgICAgICAgT25lIGV4YW1wbGUg dXNlIGNhc2UgaGVyZSByZWxhdGVzIHRvIGNvbnRhaW5lcnMuICBUaGUgdGFyZ2V0Cj4gICAgICAg ICAgIG1heSBiZSBsb2NhdGVkIGluc2lkZSBhIGNvbnRhaW5lciB3aGVyZSBpdCBkb2VzIG5vdCBo YXZlCj4gICAgICAgICAgIHN1ZmZpY2llbnQgY2FwYWJpbGl0aWVzIHRvIG1vdW50IGEgZmlsZXN5 c3RlbSBpbiB0aGUKPiAgICAgICAgICAgY29udGFpbmVyJ3MgbW91bnQgbmFtZXNwYWNlLiAgSG93 ZXZlciwgdGhlIHN1cGVydmlzb3IgbWF5IGJlIGEKPiAgICAgICAgICAgbW9yZSBwcml2aWxlZ2Vk IHByb2Nlc3MgdGhhdCBkb2VzIGhhdmUgc3VmZmljaWVudCBjYXBhYmlsaXRpZXMKPiAgICAgICAg ICAgdG8gcGVyZm9ybSB0aGUgbW91bnQgb3BlcmF0aW9uLgo+IAo+ICAgICAgICA4LiBUaGUgc3Vw ZXJ2aXNvciB0aGVuIHNlbmRzIGEgcmVzcG9uc2UgdG8gdGhlIG5vdGlmaWNhdGlvbi4gIFRoZQo+ ICAgICAgICAgICBpbmZvcm1hdGlvbiBpbiB0aGlzIHJlc3BvbnNlIGlzIHVzZWQgYnkgdGhlIGtl cm5lbCB0byBjb25zdHJ1Y3QKPiAgICAgICAgICAgYSByZXR1cm4gdmFsdWUgZm9yIHRoZSB0YXJn ZXQncyBzeXN0ZW0gY2FsbCBhbmQgcHJvdmlkZSBhIHZhbHVlCj4gICAgICAgICAgIHRoYXQgd2ls bCBiZSBhc3NpZ25lZCB0byB0aGUgZXJybm8gdmFyaWFibGUgb2YgdGhlIHRhcmdldC4KPiAKPiAg ICAgICAgICAgVGhlIHJlc3BvbnNlIGlzIHNlbnQgdXNpbmcgdGhlIFNFQ0NPTVBfSU9DVExfTk9U SUZfU0VORAo+ICAgICAgICAgICBpb2N0bCgyKSBvcGVyYXRpb24sIHdoaWNoIGlzIHVzZWQgdG8g dHJhbnNtaXQgYQo+ICAgICAgICAgICBzZWNjb21wX25vdGlmX3Jlc3Agc3RydWN0dXJlIHRvIHRo ZSBrZXJuZWwuICBUaGlzIHN0cnVjdHVyZQo+ICAgICAgICAgICBpbmNsdWRlcyBhIGNvb2tpZSB2 YWx1ZSB0aGF0IHRoZSBzdXBlcnZpc29yIG9idGFpbmVkIGluIHRoZQo+ICAgICAgICAgICBzZWNj b21wX25vdGlmIHN0cnVjdHVyZSByZXR1cm5lZCBieSB0aGUKPiAgICAgICAgICAgU0VDQ09NUF9J T0NUTF9OT1RJRl9SRUNWIG9wZXJhdGlvbi4gIFRoaXMgY29va2llIHZhbHVlIGFsbG93cwo+ICAg ICAgICAgICB0aGUga2VybmVsIHRvIGFzc29jaWF0ZSB0aGUgcmVzcG9uc2Ugd2l0aCB0aGUgdGFy Z2V0LgoKRGVzY3JpYmluZyB3aGVyZSB0aGUgY29va2llIGNhbWUgZnJvbSBzZWVtcyBsaWtlIGl0 IHNob3VsZCBsaXZlIGluIDYKYWJvdmUuIEEgcmVhZGVyIHdvdWxkIGhhdmUgdG8gdGFrZSB0aGlz IG5ldyBpbmZvIGFuZCBmaWd1cmUgb3V0IHdoZXJlClNFQ0NPTVBfSU9DVExfTk9USUZfUkVDViB3 YXMgZGVzY3JpYmVkIGFuZCBwaWVjZSBpdCB0b2dldGhlci4gV2l0aCB0aGUKc3VnZ2VzdGlvbiB0 byA2IGFib3ZlLCBtYXliZToKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgLi4uIFRoaXMgc3RydWN0dXJlCiAgICAgICAgICAgIG11c3QgaW5jbHVk ZSB0aGUgY29va2llIHZhbHVlIHRoYXQgdGhlIHN1cGVydmlzb3Igb2J0YWluZWQgaW4KICAgICAg ICAgICAgdGhlIHNlY2NvbXBfbm90aWYgc3RydWN0dXJlIHJldHVybmVkIGJ5IHRoZQoJICAgIFNF Q0NPTVBfSU9DVExfTk9USUZfUkVDViBvcGVyYXRpb24sIHdoaWNoIGFsbG93cyB0aGUga2VybmVs CiAgICAgICAgICAgIHRvIGFzc29jaWF0ZSB0aGUgcmVzcG9uc2Ugd2l0aCB0aGUgdGFyZ2V0LgoK PiAKPiAgICAgICAgOS4gT25jZSB0aGUgbm90aWZpY2F0aW9uIGhhcyBiZWVuIHNlbnQsIHRoZSBz eXN0ZW0gY2FsbCBpbiB0aGUKPiAgICAgICAgICAgdGFyZ2V0IHRocmVhZCB1bmJsb2NrcywgcmV0 dXJuaW5nIHRoZSBpbmZvcm1hdGlvbiB0aGF0IHdhcwo+ICAgICAgICAgICBwcm92aWRlZCBieSB0 aGUgc3VwZXJ2aXNvciBpbiB0aGUgbm90aWZpY2F0aW9uIHJlc3BvbnNlLgo+IAo+ICAgICAgICBB cyBhIHZhcmlhdGlvbiBvbiB0aGUgbGFzdCB0d28gc3RlcHMsIHRoZSBzdXBlcnZpc29yIGNhbiBz ZW5kIGEKPiAgICAgICAgcmVzcG9uc2UgdGhhdCB0ZWxscyB0aGUga2VybmVsIHRoYXQgaXQgc2hv dWxkIGV4ZWN1dGUgdGhlIHRhcmdldAo+ICAgICAgICB0aHJlYWQncyBzeXN0ZW0gY2FsbDsgc2Vl IHRoZSBkaXNjdXNzaW9uIG9mCj4gICAgICAgIFNFQ0NPTVBfVVNFUl9OT1RJRl9GTEFHX0NPTlRJ TlVFLCBiZWxvdy4KPiAKPiAgICBpb2N0bCgyKSBvcGVyYXRpb25zCj4gICAgICAgIFRoZSBmb2xs b3dpbmcgaW9jdGwoMikgb3BlcmF0aW9ucyBhcmUgcHJvdmlkZWQgdG8gc3VwcG9ydCBzZWNjb21w Cj4gICAgICAgIHVzZXItc3BhY2Ugbm90aWZpY2F0aW9uLiAgRm9yIGVhY2ggb2YgdGhlc2Ugb3Bl cmF0aW9ucywgdGhlIGZpcnN0Cj4gICAgICAgIChmaWxlIGRlc2NyaXB0b3IpIGFyZ3VtZW50IG9m IGlvY3RsKDIpIGlzIHRoZSBsaXN0ZW5pbmcgZmlsZQo+ICAgICAgICBkZXNjcmlwdG9yIHJldHVy bmVkIGJ5IGEgY2FsbCB0byBzZWNjb21wKDIpIHdpdGggdGhlCj4gICAgICAgIFNFQ0NPTVBfRklM VEVSX0ZMQUdfTkVXX0xJU1RFTkVSIGZsYWcuCj4gCj4gICAgICAgIFNFQ0NPTVBfSU9DVExfTk9U SUZfUkVDVgo+ICAgICAgICAgICAgICAgVGhpcyBvcGVyYXRpb24gaXMgdXNlZCB0byBvYnRhaW4g YSB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbgo+ICAgICAgICAgICAgICAgZXZlbnQuICBJZiBubyBz dWNoIGV2ZW50IGlzIGN1cnJlbnRseSBwZW5kaW5nLCB0aGUKPiAgICAgICAgICAgICAgIG9wZXJh dGlvbiBibG9ja3MgdW50aWwgYW4gZXZlbnQgb2NjdXJzLiAgVGhlIHRoaXJkIGlvY3RsKDIpCj4g ICAgICAgICAgICAgICBhcmd1bWVudCBpcyBhIHBvaW50ZXIgdG8gYSBzdHJ1Y3R1cmUgb2YgdGhl IGZvbGxvd2luZyBmb3JtCj4gICAgICAgICAgICAgICB3aGljaCBjb250YWlucyBpbmZvcm1hdGlv biBhYm91dCB0aGUgZXZlbnQuICBUaGlzIHN0cnVjdHVyZQo+ICAgICAgICAgICAgICAgbXVzdCBi ZSB6ZXJvZWQgb3V0IGJlZm9yZSB0aGUgY2FsbC4KPiAKPiAgICAgICAgICAgICAgICAgICBzdHJ1 Y3Qgc2VjY29tcF9ub3RpZiB7Cj4gICAgICAgICAgICAgICAgICAgICAgIF9fdTY0ICBpZDsgICAg ICAgICAgICAgIC8qIENvb2tpZSAqLwo+ICAgICAgICAgICAgICAgICAgICAgICBfX3UzMiAgcGlk OyAgICAgICAgICAgICAvKiBUSUQgb2YgdGFyZ2V0IHRocmVhZCAqLwoKU2hvdWxkIHdlIHJlbmFt ZSB0aGlzIHZhcmlhYmxlIGZyb20gcGlkIHRvIHRpZD8gWWVzIGl0J3MgVUFQSSwgYnV0IHlheSBm b3IKYW5vbnltb3VzIHVuaW9uczoKCnN0cnVjdCBzZWNjb21wX25vdGlmIHsKCV9fdTY0CQlpZDsJ CS8qIENvb2tpZSAqLwoJdW5pb24gewoJCV9fdTMyCXBpZDsKCQlfX3UzMgl0aWQ7CQkvKiBUSUQg b2YgdGFyZ2V0IHRocmVhZCAqLwoJfTsKCV9fdTMyICBmbGFnczsJCQkvKiBDdXJyZW50bHkgdW51 c2VkICgwKSAqLwoJc3RydWN0IHNlY2NvbXBfZGF0YSBkYXRhOwkvKiBTZWUgc2VjY29tcCgyKSAq Lwp9OwoKPiAgICAgICAgICAgICAgICAgICAgICAgX191MzIgIGZsYWdzOyAgICAgICAgICAgLyog Q3VycmVudGx5IHVudXNlZCAoMCkgKi8KPiAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHNl Y2NvbXBfZGF0YSBkYXRhOyAgIC8qIFNlZSBzZWNjb21wKDIpICovCj4gICAgICAgICAgICAgICAg ICAgfTsKPiAKPiAgICAgICAgICAgICAgIFRoZSBmaWVsZHMgaW4gdGhpcyBzdHJ1Y3R1cmUgYXJl IGFzIGZvbGxvd3M6Cj4gCj4gICAgICAgICAgICAgICBpZCAgICAgVGhpcyBpcyBhIGNvb2tpZSBm b3IgdGhlIG5vdGlmaWNhdGlvbi4gIEVhY2ggc3VjaAo+ICAgICAgICAgICAgICAgICAgICAgIGNv b2tpZSBpcyBndWFyYW50ZWVkIHRvIGJlIHVuaXF1ZSBmb3IgdGhlCj4gICAgICAgICAgICAgICAg ICAgICAgY29ycmVzcG9uZGluZyBzZWNjb21wIGZpbHRlci4KPiAKPiAgICAgICAgICAgICAgICAg ICAgICDigKIgSXQgY2FuIGJlIHVzZWQgd2l0aCB0aGUKPiAgICAgICAgICAgICAgICAgICAgICAg IFNFQ0NPTVBfSU9DVExfTk9USUZfSURfVkFMSUQgaW9jdGwoMikgb3BlcmF0aW9uIHRvCj4gICAg ICAgICAgICAgICAgICAgICAgICB2ZXJpZnkgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0aWxsIGFsaXZl Lgo+IAo+ICAgICAgICAgICAgICAgICAgICAgIOKAoiBXaGVuIHJldHVybmluZyBhIG5vdGlmaWNh dGlvbiByZXNwb25zZSB0byB0aGUKPiAgICAgICAgICAgICAgICAgICAgICAgIGtlcm5lbCwgdGhl IHN1cGVydmlzb3IgbXVzdCBpbmNsdWRlIHRoZSBjb29raWUKPiAgICAgICAgICAgICAgICAgICAg ICAgIHZhbHVlIGluIHRoZSBzZWNjb21wX25vdGlmX3Jlc3Agc3RydWN0dXJlIHRoYXQgaXMKPiAg ICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZCBhcyB0aGUgYXJndW1lbnQgb2YgdGhlCj4g ICAgICAgICAgICAgICAgICAgICAgICBTRUNDT01QX0lPQ1RMX05PVElGX1NFTkQgb3BlcmF0aW9u Lgo+IAo+ICAgICAgICAgICAgICAgcGlkICAgIFRoaXMgaXMgdGhlIHRocmVhZCBJRCBvZiB0aGUg dGFyZ2V0IHRocmVhZCB0aGF0Cj4gICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmVkIHRoZSBu b3RpZmljYXRpb24gZXZlbnQuCj4gCj4gICAgICAgICAgICAgICBmbGFncyAgVGhpcyBpcyBhIGJp dCBtYXNrIG9mIGZsYWdzIHByb3ZpZGluZyBmdXJ0aGVyCj4gICAgICAgICAgICAgICAgICAgICAg aW5mb3JtYXRpb24gb24gdGhlIGV2ZW50LiAgSW4gdGhlIGN1cnJlbnQKPiAgICAgICAgICAgICAg ICAgICAgICBpbXBsZW1lbnRhdGlvbiwgdGhpcyBmaWVsZCBpcyBhbHdheXMgemVyby4KPiAKPiAg ICAgICAgICAgICAgIGRhdGEgICBUaGlzIGlzIGEgc2VjY29tcF9kYXRhIHN0cnVjdHVyZSBjb250 YWluaW5nCj4gICAgICAgICAgICAgICAgICAgICAgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN5c3Rl bSBjYWxsIHRoYXQgdHJpZ2dlcmVkIHRoZQo+ICAgICAgICAgICAgICAgICAgICAgIG5vdGlmaWNh dGlvbi4gIFRoaXMgaXMgdGhlIHNhbWUgc3RydWN0dXJlIHRoYXQgaXMKPiAgICAgICAgICAgICAg ICAgICAgICBwYXNzZWQgdG8gdGhlIHNlY2NvbXAgZmlsdGVyLiAgU2VlIHNlY2NvbXAoMikgZm9y Cj4gICAgICAgICAgICAgICAgICAgICAgZGV0YWlscyBvZiB0aGlzIHN0cnVjdHVyZS4KPiAKPiAg ICAgICAgICAgICAgIE9uIHN1Y2Nlc3MsIHRoaXMgb3BlcmF0aW9uIHJldHVybnMgMDsgb24gZmFp bHVyZSwgLTEgaXMKPiAgICAgICAgICAgICAgIHJldHVybmVkLCBhbmQgZXJybm8gaXMgc2V0IHRv IGluZGljYXRlIHRoZSBjYXVzZSBvZiB0aGUKPiAgICAgICAgICAgICAgIGVycm9yLiAgVGhpcyBv cGVyYXRpb24gY2FuIGZhaWwgd2l0aCB0aGUgZm9sbG93aW5nIGVycm9yczoKPiAKPiAgICAgICAg ICAgICAgIEVJTlZBTCAoc2luY2UgTGludXggNS41KQo+ICAgICAgICAgICAgICAgICAgICAgIFRo ZSBzZWNjb21wX25vdGlmIHN0cnVjdHVyZSB0aGF0IHdhcyBwYXNzZWQgdG8gdGhlCj4gICAgICAg ICAgICAgICAgICAgICAgY2FsbCBjb250YWluZWQgbm9uemVybyBmaWVsZHMuCj4gCj4gICAgICAg ICAgICAgICBFTk9FTlQgVGhlIHRhcmdldCB0aHJlYWQgd2FzIGtpbGxlZCBieSBhIHNpZ25hbCBh cyB0aGUKPiAgICAgICAgICAgICAgICAgICAgICBub3RpZmljYXRpb24gaW5mb3JtYXRpb24gd2Fz IGJlaW5nIGdlbmVyYXRlZCwgb3IgdGhlCj4gICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0J3Mg KGJsb2NrZWQpIHN5c3RlbSBjYWxsIHdhcyBpbnRlcnJ1cHRlZCBieSBhCj4gICAgICAgICAgICAg ICAgICAgICAgc2lnbmFsIGhhbmRsZXIuCj4gCj4gICAgICAgIFNFQ0NPTVBfSU9DVExfTk9USUZf SURfVkFMSUQKPiAgICAgICAgICAgICAgIFRoaXMgb3BlcmF0aW9uIGNhbiBiZSB1c2VkIHRvIGNo ZWNrIHRoYXQgYSBub3RpZmljYXRpb24gSUQKPiAgICAgICAgICAgICAgIHJldHVybmVkIGJ5IGFu IGVhcmxpZXIgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWIG9wZXJhdGlvbgo+ICAgICAgICAgICAg ICAgaXMgc3RpbGwgdmFsaWQgKGkuZS4sIHRoYXQgdGhlIHRhcmdldCBzdGlsbCBleGlzdHMpLgoK TWF5YmUgY2xhcmlmeSBhIGJpdCBtb3JlLCBzaW5jZSBpdCdzIGNvdmVyaW5nIG1vcmUgdGhhbiBq dXN0ICJpcyB0aGUKdGFyZ2V0IHN0aWxsIGFsaXZlIiwgYnV0IGFsc28gImlzIHRoYXQgc3lzY2Fs bCBzdGlsbCB3YWl0aW5nIGZvciBhCnJlc3BvbnNlIjoKCiAgICAgICAgICAgICAgICBpcyBzdGls bCB2YWxpZCAoaS5lLiwgdGhhdCB0aGUgdGFyZ2V0IHN0aWxsIGV4aXN0cyBhbmQKCQl0aGUgc3lz Y2FsbCBpcyBzdGlsbCBibG9ja2VkIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2UpLgoKCj4gCj4gICAg ICAgICAgICAgICBUaGUgdGhpcmQgaW9jdGwoMikgYXJndW1lbnQgaXMgYSBwb2ludGVyIHRvIHRo ZSBjb29raWUgKGlkKQo+ICAgICAgICAgICAgICAgcmV0dXJuZWQgYnkgdGhlIFNFQ0NPTVBfSU9D VExfTk9USUZfUkVDViBvcGVyYXRpb24uCj4gCj4gICAgICAgICAgICAgICBUaGlzIG9wZXJhdGlv biBpcyBuZWNlc3NhcnkgdG8gYXZvaWQgcmFjZSBjb25kaXRpb25zIHRoYXQKPiAgICAgICAgICAg ICAgIGNhbiBvY2N1ciB3aGVuIHRoZSBwaWQgcmV0dXJuZWQgYnkgdGhlCj4gICAgICAgICAgICAg ICBTRUNDT01QX0lPQ1RMX05PVElGX1JFQ1Ygb3BlcmF0aW9uIHRlcm1pbmF0ZXMsIGFuZCB0aGF0 Cj4gICAgICAgICAgICAgICBwcm9jZXNzIElEIGlzIHJldXNlZCBieSBhbm90aGVyIHByb2Nlc3Mu ICBBbiBleGFtcGxlIG9mCj4gICAgICAgICAgICAgICB0aGlzIGtpbmQgb2YgcmFjZSBpcyB0aGUg Zm9sbG93aW5nCj4gCj4gICAgICAgICAgICAgICAxLiBBIG5vdGlmaWNhdGlvbiBpcyBnZW5lcmF0 ZWQgb24gdGhlIGxpc3RlbmluZyBmaWxlCj4gICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLiAg VGhlIHJldHVybmVkIHNlY2NvbXBfbm90aWYgY29udGFpbnMgdGhlIFRJRAo+ICAgICAgICAgICAg ICAgICAgb2YgdGhlIHRhcmdldCB0aHJlYWQgKGluIHRoZSBwaWQgZmllbGQgb2YgdGhlCj4gICAg ICAgICAgICAgICAgICBzdHJ1Y3R1cmUpLgo+IAo+ICAgICAgICAgICAgICAgMi4gVGhlIHRhcmdl dCB0ZXJtaW5hdGVzLgo+IAo+ICAgICAgICAgICAgICAgMy4gQW5vdGhlciB0aHJlYWQgb3IgcHJv Y2VzcyBpcyBjcmVhdGVkIG9uIHRoZSBzeXN0ZW0gdGhhdAo+ICAgICAgICAgICAgICAgICAgYnkg Y2hhbmNlIHJldXNlcyB0aGUgVElEIHRoYXQgd2FzIGZyZWVkIHdoZW4gdGhlIHRhcmdldAo+ICAg ICAgICAgICAgICAgICAgdGVybWluYXRlZC4KPiAKPiAgICAgICAgICAgICAgIDQuIFRoZSBzdXBl cnZpc29yIG9wZW4oMilzIHRoZSAvcHJvYy9bdGlkXS9tZW0gZmlsZSBmb3IgdGhlCj4gICAgICAg ICAgICAgICAgICBUSUQgb2J0YWluZWQgaW4gc3RlcCAxLCB3aXRoIHRoZSBpbnRlbnRpb24gb2Yg KHNheSkKPiAgICAgICAgICAgICAgICAgIGluc3BlY3RpbmcgdGhlIG1lbW9yeSBsb2NhdGlvbihz KSB0aGF0IGNvbnRhaW5pbmcgdGhlCj4gICAgICAgICAgICAgICAgICBhcmd1bWVudChzKSBvZiB0 aGUgc3lzdGVtIGNhbGwgdGhhdCB0cmlnZ2VyZWQgdGhlCj4gICAgICAgICAgICAgICAgICBub3Rp ZmljYXRpb24gaW4gc3RlcCAxLgo+IAo+ICAgICAgICAgICAgICAgSW4gdGhlIGFib3ZlIHNjZW5h cmlvLCB0aGUgcmlzayBpcyB0aGF0IHRoZSBzdXBlcnZpc29yIG1heQo+ICAgICAgICAgICAgICAg dHJ5IHRvIGFjY2VzcyB0aGUgbWVtb3J5IG9mIGEgcHJvY2VzcyBvdGhlciB0aGFuIHRoZQo+ICAg ICAgICAgICAgICAgdGFyZ2V0LiAgVGhpcyByYWNlIGNhbiBiZSBhdm9pZGVkIGJ5IGZvbGxvd2lu ZyB0aGUgY2FsbCB0bwo+ICAgICAgICAgICAgICAgb3BlbigyKSB3aXRoIGEgU0VDQ09NUF9JT0NU TF9OT1RJRl9JRF9WQUxJRCBvcGVyYXRpb24gdG8KPiAgICAgICAgICAgICAgIHZlcmlmeSB0aGF0 IHRoZSBwcm9jZXNzIHRoYXQgZ2VuZXJhdGVkIHRoZSBub3RpZmljYXRpb24gaXMKPiAgICAgICAg ICAgICAgIHN0aWxsIGFsaXZlLiAgKE5vdGUgdGhhdCBpZiB0aGUgdGFyZ2V0IHRlcm1pbmF0ZXMg YWZ0ZXIgdGhlCj4gICAgICAgICAgICAgICBsYXR0ZXIgc3RlcCwgYSBzdWJzZXF1ZW50IHJlYWQo MikgZnJvbSB0aGUgZmlsZSBkZXNjcmlwdG9yCj4gICAgICAgICAgICAgICBtYXkgcmV0dXJuIDAs IGluZGljYXRpbmcgZW5kIG9mIGZpbGUuKQo+IAo+ICAgICAgICAgICAgICAgT24gc3VjY2VzcyAo aS5lLiwgdGhlIG5vdGlmaWNhdGlvbiBJRCBpcyBzdGlsbCB2YWxpZCksIHRoaXMKPiAgICAgICAg ICAgICAgIG9wZXJhdGlvbiByZXR1cm5zIDAuICBPbiBmYWlsdXJlIChpLmUuLCB0aGUgbm90aWZp Y2F0aW9uIElECj4gICAgICAgICAgICAgICBpcyBubyBsb25nZXIgdmFsaWQpLCAtMSBpcyByZXR1 cm5lZCwgYW5kIGVycm5vIGlzIHNldCB0bwo+ICAgICAgICAgICAgICAgRU5PRU5ULgo+IAo+ICAg ICAgICBTRUNDT01QX0lPQ1RMX05PVElGX1NFTkQKPiAgICAgICAgICAgICAgIFRoaXMgb3BlcmF0 aW9uIGlzIHVzZWQgdG8gc2VuZCBhIG5vdGlmaWNhdGlvbiByZXNwb25zZSBiYWNrCj4gICAgICAg ICAgICAgICB0byB0aGUga2VybmVsLiAgVGhlIHRoaXJkIGlvY3RsKDIpIGFyZ3VtZW50IG9mIHRo aXMKPiAgICAgICAgICAgICAgIHN0cnVjdHVyZSBpcyBhIHBvaW50ZXIgdG8gYSBzdHJ1Y3R1cmUg b2YgdGhlIGZvbGxvd2luZwo+ICAgICAgICAgICAgICAgZm9ybToKPiAKPiAgICAgICAgICAgICAg ICAgICBzdHJ1Y3Qgc2VjY29tcF9ub3RpZl9yZXNwIHsKPiAgICAgICAgICAgICAgICAgICAgICAg X191NjQgaWQ7ICAgICAgICAgICAgICAgLyogQ29va2llIHZhbHVlICovCj4gICAgICAgICAgICAg ICAgICAgICAgIF9fczY0IHZhbDsgICAgICAgICAgICAgIC8qIFN1Y2Nlc3MgcmV0dXJuIHZhbHVl ICovCj4gICAgICAgICAgICAgICAgICAgICAgIF9fczMyIGVycm9yOyAgICAgICAgICAgIC8qIDAg KHN1Y2Nlc3MpIG9yIG5lZ2F0aXZlCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIGVycm9yIG51bWJlciAqLwo+ICAgICAgICAgICAgICAgICAgICAgICBf X3UzMiBmbGFnczsgICAgICAgICAgICAvKiBTZWUgYmVsb3cgKi8KPiAgICAgICAgICAgICAgICAg ICB9Owo+IAo+ICAgICAgICAgICAgICAgVGhlIGZpZWxkcyBvZiB0aGlzIHN0cnVjdHVyZSBhcmUg YXMgZm9sbG93czoKPiAKPiAgICAgICAgICAgICAgIGlkICAgICBUaGlzIGlzIHRoZSBjb29raWUg dmFsdWUgdGhhdCB3YXMgb2J0YWluZWQgdXNpbmcgdGhlCj4gICAgICAgICAgICAgICAgICAgICAg U0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWIG9wZXJhdGlvbi4gIFRoaXMgY29va2llCj4gICAgICAg ICAgICAgICAgICAgICAgdmFsdWUgYWxsb3dzIHRoZSBrZXJuZWwgdG8gY29ycmVjdGx5IGFzc29j aWF0ZSB0aGlzCj4gICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2Ugd2l0aCB0aGUgc3lzdGVt IGNhbGwgdGhhdCB0cmlnZ2VyZWQgdGhlCj4gICAgICAgICAgICAgICAgICAgICAgdXNlci1zcGFj ZSBub3RpZmljYXRpb24uCj4gCj4gICAgICAgICAgICAgICB2YWwgICAgVGhpcyBpcyB0aGUgdmFs dWUgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIGEgc3Bvb2ZlZAo+ICAgICAgICAgICAgICAgICAgICAg IHN1Y2Nlc3MgcmV0dXJuIGZvciB0aGUgdGFyZ2V0J3Mgc3lzdGVtIGNhbGw7IHNlZQo+ICAgICAg ICAgICAgICAgICAgICAgIGJlbG93Lgo+IAo+ICAgICAgICAgICAgICAgZXJyb3IgIFRoaXMgaXMg dGhlIHZhbHVlIHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBlcnJvcgo+ICAgICAgICAgICAgICAg ICAgICAgIG51bWJlciAoZXJybm8pIGZvciBhIHNwb29mZWQgZXJyb3IgcmV0dXJuIGZvciB0aGUK PiAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQncyBzeXN0ZW0gY2FsbDsgc2VlIGJlbG93Lgo+ IAo+ICAgICAgICAgICAgICAgZmxhZ3MgIFRoaXMgaXMgYSBiaXQgbWFzayB0aGF0IGluY2x1ZGVz IHplcm8gb3IgbW9yZSBvZiB0aGUKPiAgICAgICAgICAgICAgICAgICAgICBmb2xsb3dpbmcgZmxh Z3M6Cj4gCj4gICAgICAgICAgICAgICAgICAgICAgU0VDQ09NUF9VU0VSX05PVElGX0ZMQUdfQ09O VElOVUUgKHNpbmNlIExpbnV4IDUuNSkKPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVs bCB0aGUga2VybmVsIHRvIGV4ZWN1dGUgdGhlIHRhcmdldCdzCj4gICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHN5c3RlbSBjYWxsLgo+IAo+ICAgICAgICAgICAgICAgVHdvIGtpbmRzIG9mIHJl c3BvbnNlIGFyZSBwb3NzaWJsZToKPiAKPiAgICAgICAgICAgICAgIOKAoiBBIHJlc3BvbnNlIHRv IHRoZSBrZXJuZWwgdGVsbGluZyBpdCB0byBleGVjdXRlIHRoZQo+ICAgICAgICAgICAgICAgICB0 YXJnZXQncyBzeXN0ZW0gY2FsbC4gIEluIHRoaXMgY2FzZSwgdGhlIGZsYWdzIGZpZWxkCj4gICAg ICAgICAgICAgICAgIGluY2x1ZGVzIFNFQ0NPTVBfVVNFUl9OT1RJRl9GTEFHX0NPTlRJTlVFIGFu ZCB0aGUgZXJyb3IKPiAgICAgICAgICAgICAgICAgYW5kIHZhbCBmaWVsZHMgbXVzdCBiZSB6ZXJv Lgo+IAo+ICAgICAgICAgICAgICAgICBUaGlzIGtpbmQgb2YgcmVzcG9uc2UgY2FuIGJlIHVzZWZ1 bCBpbiBjYXNlcyB3aGVyZSB0aGUKPiAgICAgICAgICAgICAgICAgc3VwZXJ2aXNvciBuZWVkcyB0 byBkbyBkZWVwZXIgYW5hbHlzaXMgb2YgdGhlIHRhcmdldCdzCj4gICAgICAgICAgICAgICAgIHN5 c3RlbSBjYWxsIHRoYW4gaXMgcG9zc2libGUgZnJvbSBhIHNlY2NvbXAgZmlsdGVyIChlLmcuLAo+ ICAgICAgICAgICAgICAgICBleGFtaW5pbmcgdGhlIHZhbHVlcyBvZiBwb2ludGVyIGFyZ3VtZW50 cyksIGFuZCwgaGF2aW5nCj4gICAgICAgICAgICAgICAgIGRlY2lkZWQgdGhhdCB0aGUgc3lzdGVt IGNhbGwgZG9lcyBub3QgcmVxdWlyZSBlbXVsYXRpb24KPiAgICAgICAgICAgICAgICAgYnkgdGhl IHN1cGVydmlzb3IsIHRoZSBzdXBlcnZpc29yIHdhbnRzIHRoZSBzeXN0ZW0gY2FsbAo+ICAgICAg ICAgICAgICAgICB0byBiZSBleGVjdXRlZCBub3JtYWxseSBpbiB0aGUgdGFyZ2V0Lgo+IAo+ICAg ICAgICAgICAgICAgICBUaGUgU0VDQ09NUF9VU0VSX05PVElGX0ZMQUdfQ09OVElOVUUgZmxhZyBz aG91bGQgYmUgdXNlZAo+ICAgICAgICAgICAgICAgICB3aXRoIGNhdXRpb247IHNlZSBOT1RFUy4K PiAKPiAgICAgICAgICAgICAgIOKAoiBBIHNwb29mZWQgcmV0dXJuIHZhbHVlIGZvciB0aGUgdGFy Z2V0J3Mgc3lzdGVtIGNhbGwuICBJbgo+ICAgICAgICAgICAgICAgICB0aGlzIGNhc2UsIHRoZSBr ZXJuZWwgZG9lcyBub3QgZXhlY3V0ZSB0aGUgdGFyZ2V0J3MKPiAgICAgICAgICAgICAgICAgc3lz dGVtIGNhbGwsIGluc3RlYWQgY2F1c2luZyB0aGUgc3lzdGVtIGNhbGwgdG8gcmV0dXJuIGEKPiAg ICAgICAgICAgICAgICAgc3Bvb2ZlZCB2YWx1ZSBhcyBzcGVjaWZpZWQgYnkgZmllbGRzIG9mIHRo ZQo+ICAgICAgICAgICAgICAgICBzZWNjb21wX25vdGlmX3Jlc3Agc3RydWN0dXJlLiAgVGhlIHN1 cGVydmlzb3Igc2hvdWxkIHNldAo+ICAgICAgICAgICAgICAgICB0aGUgZmllbGRzIG9mIHRoaXMg c3RydWN0dXJlIGFzIGZvbGxvd3M6Cj4gCj4gICAgICAgICAgICAgICAgICsgIGZsYWdzIGRvZXMg bm90IGNvbnRhaW4KPiAgICAgICAgICAgICAgICAgICAgU0VDQ09NUF9VU0VSX05PVElGX0ZMQUdf Q09OVElOVUUuCj4gCj4gICAgICAgICAgICAgICAgICsgIGVycm9yIGlzIHNldCBlaXRoZXIgdG8g MCBmb3IgYSBzcG9vZmVkICJzdWNjZXNzIgo+ICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3Ig dG8gYSBuZWdhdGl2ZSBlcnJvciBudW1iZXIgZm9yIGEgc3Bvb2ZlZAo+ICAgICAgICAgICAgICAg ICAgICAiZmFpbHVyZSIgcmV0dXJuLiAgSW4gdGhlIGZvcm1lciBjYXNlLCB0aGUga2VybmVsCj4g ICAgICAgICAgICAgICAgICAgIGNhdXNlcyB0aGUgdGFyZ2V0J3Mgc3lzdGVtIGNhbGwgdG8gcmV0 dXJuIHRoZSB2YWx1ZQo+ICAgICAgICAgICAgICAgICAgICBzcGVjaWZpZWQgaW4gdGhlIHZhbCBm aWVsZC4gIEluIHRoZSBsYXRlciBjYXNlLCB0aGUKPiAgICAgICAgICAgICAgICAgICAga2VybmVs IGNhdXNlcyB0aGUgdGFyZ2V0J3Mgc3lzdGVtIGNhbGwgdG8gcmV0dXJuIC0xLAo+ICAgICAgICAg ICAgICAgICAgICBhbmQgZXJybm8gaXMgYXNzaWduZWQgdGhlIG5lZ2F0ZWQgZXJyb3IgdmFsdWUu Cj4gCj4gICAgICAgICAgICAgICAgICsgIHZhbCBpcyBzZXQgdG8gYSB2YWx1ZSB0aGF0IHdpbGwg YmUgdXNlZCBhcyB0aGUgcmV0dXJuCj4gICAgICAgICAgICAgICAgICAgIHZhbHVlIGZvciBhIHNw b29mZWQgInN1Y2Nlc3MiIHJldHVybiBmb3IgdGhlIHRhcmdldCdzCj4gICAgICAgICAgICAgICAg ICAgIHN5c3RlbSBjYWxsLiAgVGhlIHZhbHVlIGluIHRoaXMgZmllbGQgaXMgaWdub3JlZCBpZgo+ ICAgICAgICAgICAgICAgICAgICB0aGUgZXJyb3IgZmllbGQgY29udGFpbnMgYSBub256ZXJvIHZh bHVlLgoKU3RyaWN0bHkgc3BlYWtpbmcsIHRoaXMgaXMgYXJjaGl0ZWN0dXJlIHNwZWNpZmljLCBi dXQgYWxsIGFyY2hpdGVjdHVyZXMKZG8gaXQgdGhpcyB3YXkuIFNob3VsZCBzZWNjb21wIGVuZm9y Y2UgdmFsID09IDAgd2hlbiBlcnIgIT0gMCA/Cgo+IAo+ICAgICAgICAgICAgICAgT24gc3VjY2Vz cywgdGhpcyBvcGVyYXRpb24gcmV0dXJucyAwOyBvbiBmYWlsdXJlLCAtMSBpcwo+ICAgICAgICAg ICAgICAgcmV0dXJuZWQsIGFuZCBlcnJubyBpcyBzZXQgdG8gaW5kaWNhdGUgdGhlIGNhdXNlIG9m IHRoZQo+ICAgICAgICAgICAgICAgZXJyb3IuICBUaGlzIG9wZXJhdGlvbiBjYW4gZmFpbCB3aXRo IHRoZSBmb2xsb3dpbmcgZXJyb3JzOgo+IAo+ICAgICAgICAgICAgICAgRUlOUFJPR1JFU1MKPiAg ICAgICAgICAgICAgICAgICAgICBBIHJlc3BvbnNlIHRvIHRoaXMgbm90aWZpY2F0aW9uIGhhcyBh bHJlYWR5IGJlZW4KPiAgICAgICAgICAgICAgICAgICAgICBzZW50Lgo+IAo+ICAgICAgICAgICAg ICAgRUlOVkFMIEFuIGludmFsaWQgdmFsdWUgd2FzIHNwZWNpZmllZCBpbiB0aGUgZmxhZ3MgZmll bGQuCj4gCj4gICAgICAgICAgICAgICBFSU5WQUwgVGhlIGZsYWdzIGZpZWxkIGNvbnRhaW5lZAo+ ICAgICAgICAgICAgICAgICAgICAgIFNFQ0NPTVBfVVNFUl9OT1RJRl9GTEFHX0NPTlRJTlVFLCBh bmQgdGhlIGVycm9yIG9yCj4gICAgICAgICAgICAgICAgICAgICAgdmFsIGZpZWxkIHdhcyBub3Qg emVyby4KPiAKPiAgICAgICAgICAgICAgIEVOT0VOVCBUaGUgYmxvY2tlZCBzeXN0ZW0gY2FsbCBp biB0aGUgdGFyZ2V0IGhhcyBiZWVuCj4gICAgICAgICAgICAgICAgICAgICAgaW50ZXJydXB0ZWQg YnkgYSBzaWduYWwgaGFuZGxlciBvciB0aGUgdGFyZ2V0IGhhcwo+ICAgICAgICAgICAgICAgICAg ICAgIHRlcm1pbmF0ZWQuCj4gCj4gTk9URVMKPiAgICBzZWxlY3QoKS9wb2xsKCkvZXBvbGwgc2Vt YW50aWNzCj4gICAgICAgIFRoZSBmaWxlIGRlc2NyaXB0b3IgcmV0dXJuZWQgd2hlbiBzZWNjb21w KDIpIGlzIGVtcGxveWVkIHdpdGggdGhlCj4gICAgICAgIFNFQ0NPTVBfRklMVEVSX0ZMQUdfTkVX X0xJU1RFTkVSIGZsYWcgY2FuIGJlIG1vbml0b3JlZCB1c2luZwo+ICAgICAgICBwb2xsKDIpLCBl cG9sbCg3KSwgYW5kIHNlbGVjdCgyKS4gIFRoZXNlIGludGVyZmFjZXMgaW5kaWNhdGUgdGhhdAo+ ICAgICAgICB0aGUgZmlsZSBkZXNjcmlwdG9yIGlzIHJlYWR5IGFzIGZvbGxvd3M6Cj4gCj4gICAg ICAgIOKAoiBXaGVuIGEgbm90aWZpY2F0aW9uIGlzIHBlbmRpbmcsIHRoZXNlIGludGVyZmFjZXMg aW5kaWNhdGUgdGhhdAo+ICAgICAgICAgIHRoZSBmaWxlIGRlc2NyaXB0b3IgaXMgcmVhZGFibGUu ICBGb2xsb3dpbmcgc3VjaCBhbiBpbmRpY2F0aW9uLAo+ICAgICAgICAgIGEgc3Vic2VxdWVudCBT RUNDT01QX0lPQ1RMX05PVElGX1JFQ1YgaW9jdGwoMikgd2lsbCBub3QgYmxvY2ssCj4gICAgICAg ICAgcmV0dXJuaW5nIGVpdGhlciBpbmZvcm1hdGlvbiBhYm91dCBhIG5vdGlmaWNhdGlvbiBvciBl bHNlCj4gICAgICAgICAgZmFpbGluZyB3aXRoIHRoZSBlcnJvciBFSU5UUiBpZiB0aGUgdGFyZ2V0 IGhhcyBiZWVuIGtpbGxlZCBieSBhCj4gICAgICAgICAgc2lnbmFsIG9yIGl0cyBzeXN0ZW0gY2Fs bCBoYXMgYmVlbiBpbnRlcnJ1cHRlZCBieSBhIHNpZ25hbAo+ICAgICAgICAgIGhhbmRsZXIuCj4g Cj4gICAgICAgIOKAoiBBZnRlciB0aGUgbm90aWZpY2F0aW9uIGhhcyBiZWVuIHJlY2VpdmVkIChp LmUuLCBieSB0aGUKPiAgICAgICAgICBTRUNDT01QX0lPQ1RMX05PVElGX1JFQ1YgaW9jdGwoMikg b3BlcmF0aW9uKSwgdGhlc2UgaW50ZXJmYWNlcwo+ICAgICAgICAgIGluZGljYXRlIHRoYXQgdGhl IGZpbGUgZGVzY3JpcHRvciBpcyB3cml0YWJsZSwgbWVhbmluZyB0aGF0IGEKPiAgICAgICAgICBu b3RpZmljYXRpb24gcmVzcG9uc2UgY2FuIGJlIHNlbnQgdXNpbmcgdGhlCj4gICAgICAgICAgU0VD Q09NUF9JT0NUTF9OT1RJRl9TRU5EIGlvY3RsKDIpIG9wZXJhdGlvbi4KPiAKPiAgICAgICAg4oCi IEFmdGVyIHRoZSBsYXN0IHRocmVhZCB1c2luZyB0aGUgZmlsdGVyIGhhcyB0ZXJtaW5hdGVkIGFu ZCBiZWVuCj4gICAgICAgICAgcmVhcGVkIHVzaW5nIHdhaXRwaWQoMikgKG9yIHNpbWlsYXIpLCB0 aGUgZmlsZSBkZXNjcmlwdG9yCj4gICAgICAgICAgaW5kaWNhdGVzIGFuIGVuZC1vZi1maWxlIGNv bmRpdGlvbiAocmVhZGFibGUgaW4gc2VsZWN0KDIpOwo+ICAgICAgICAgIFBPTExIVVAvRVBPTExI VVAgaW4gcG9sbCgyKS8gZXBvbGxfd2FpdCgyKSkuCgpJJ2xsIHJlcGx5IHNlcGFyYXRlbHkgYWJv dXQgdGhlICJpb2N0bCgpIGRvZXMgbm90IHRlcm1pbmF0ZSB3aGVuIGFsbApmaWx0ZXJzIGhhdmUg dGVybWluYXRlZCIgY2FzZS4KCj4gCj4gICAgRGVzaWduIGdvYWxzOyB1c2Ugb2YgU0VDQ09NUF9V U0VSX05PVElGX0ZMQUdfQ09OVElOVUUKPiAgICAgICAgVGhlIGludGVudCBvZiB0aGUgdXNlci1z cGFjZSBub3RpZmljYXRpb24gZmVhdHVyZSBpcyB0byBhbGxvdwo+ICAgICAgICBzeXN0ZW0gY2Fs bHMgdG8gYmUgcGVyZm9ybWVkIG9uIGJlaGFsZiBvZiB0aGUgdGFyZ2V0LiAgVGhlCj4gICAgICAg IHRhcmdldCdzIHN5c3RlbSBjYWxsIHNob3VsZCBlaXRoZXIgYmUgaGFuZGxlZCBieSB0aGUgc3Vw ZXJ2aXNvciBvcgo+ICAgICAgICBhbGxvd2VkIHRvIGNvbnRpbnVlIG5vcm1hbGx5IGluIHRoZSBr ZXJuZWwgKHdoZXJlIHN0YW5kYXJkCj4gICAgICAgIHNlY3VyaXR5IHBvbGljaWVzIHdpbGwgYmUg YXBwbGllZCkuCj4gCj4gICAgICAgIE5vdGUgd2VsbDogdGhpcyBtZWNoYW5pc20gbXVzdCBub3Qg YmUgdXNlZCB0byBtYWtlIHNlY3VyaXR5IHBvbGljeQo+ICAgICAgICBkZWNpc2lvbnMgYWJvdXQg dGhlIHN5c3RlbSBjYWxsLCB3aGljaCB3b3VsZCBiZSBpbmhlcmVudGx5IHJhY2UtCj4gICAgICAg IHByb25lIGZvciByZWFzb25zIGRlc2NyaWJlZCBuZXh0Lgo+IAo+ICAgICAgICBUaGUgU0VDQ09N UF9VU0VSX05PVElGX0ZMQUdfQ09OVElOVUUgZmxhZyBtdXN0IGJlIHVzZWQgd2l0aAo+ICAgICAg ICBjYXV0aW9uLiAgSWYgc2V0IGJ5IHRoZSBzdXBlcnZpc29yLCB0aGUgdGFyZ2V0J3Mgc3lzdGVt IGNhbGwgd2lsbAo+ICAgICAgICBjb250aW51ZS4gIEhvd2V2ZXIsIHRoZXJlIGlzIGEgdGltZS1v Zi1jaGVjaywgdGltZS1vZi11c2UgcmFjZQo+ICAgICAgICBoZXJlLCBzaW5jZSBhbiBhdHRhY2tl ciBjb3VsZCBleHBsb2l0IHRoZSBpbnRlcnZhbCBvZiB0aW1lIHdoZXJlCj4gICAgICAgIHRoZSB0 YXJnZXQgaXMgYmxvY2tlZCB3YWl0aW5nIG9uIHRoZSAiY29udGludWUiIHJlc3BvbnNlIHRvIGRv Cj4gICAgICAgIHRoaW5ncyBzdWNoIGFzIHJld3JpdGluZyB0aGUgc3lzdGVtIGNhbGwgYXJndW1l bnRzLgo+IAo+ICAgICAgICBOb3RlIGZ1cnRoZXJtb3JlIHRoYXQgYSB1c2VyLXNwYWNlIG5vdGlm aWVyIGNhbiBiZSBieXBhc3NlZCBpZiB0aGUKPiAgICAgICAgZXhpc3RpbmcgZmlsdGVycyBhbGxv dyB0aGUgdXNlIG9mIHNlY2NvbXAoMikgb3IgcHJjdGwoMikgdG8KPiAgICAgICAgaW5zdGFsbCBh IGZpbHRlciB0aGF0IHJldHVybnMgYW4gYWN0aW9uIHZhbHVlIHdpdGggYSBoaWdoZXIKPiAgICAg ICAgcHJlY2VkZW5jZSB0aGFuIFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgKHNlZSBzZWNjb21wKDIp KS4KPiAKPiAgICAgICAgSXQgc2hvdWxkIHRodXMgYmUgYWJzb2x1dGVseSBjbGVhciB0aGF0IHRo ZSBzZWNjb21wIHVzZXItc3BhY2UKPiAgICAgICAgbm90aWZpY2F0aW9uIG1lY2hhbmlzbSBjYW4g bm90IGJlIHVzZWQgdG8gaW1wbGVtZW50IGEgc2VjdXJpdHkKPiAgICAgICAgcG9saWN5ISAgSXQg c2hvdWxkIG9ubHkgZXZlciBiZSB1c2VkIGluIHNjZW5hcmlvcyB3aGVyZSBhIG1vcmUKPiAgICAg ICAgcHJpdmlsZWdlZCBwcm9jZXNzIHN1cGVydmlzZXMgdGhlIHN5c3RlbSBjYWxscyBvZiBhIGxl c3Nlcgo+ICAgICAgICBwcml2aWxlZ2VkIHRhcmdldCB0byBnZXQgYXJvdW5kIGtlcm5lbC1lbmZv cmNlZCBzZWN1cml0eQo+ICAgICAgICByZXN0cmljdGlvbnMgd2hlbiB0aGUgc3VwZXJ2aXNvciBk ZWVtcyB0aGlzIHNhZmUuICBJbiBvdGhlciB3b3JkcywKPiAgICAgICAgaW4gb3JkZXIgdG8gY29u dGludWUgYSBzeXN0ZW0gY2FsbCwgdGhlIHN1cGVydmlzb3Igc2hvdWxkIGJlIHN1cmUKPiAgICAg ICAgdGhhdCBhbm90aGVyIHNlY3VyaXR5IG1lY2hhbmlzbSBvciB0aGUga2VybmVsIGl0c2VsZiB3 aWxsCj4gICAgICAgIHN1ZmZpY2llbnRseSBibG9jayB0aGUgc3lzdGVtIGNhbGwgaWYgaXRzIGFy Z3VtZW50cyBhcmUgcmV3cml0dGVuCj4gICAgICAgIHRvIHNvbWV0aGluZyB1bnNhZmUuCj4gCj4g ICAgSW50ZXJhY3Rpb24gd2l0aCBTQV9SRVNUQVJUIHNpZ25hbCBoYW5kbGVycwo+ICAgICAgICBD b25zaWRlciB0aGUgZm9sbG93aW5nIHNjZW5hcmlvOgo+IAo+ICAgICAgICDigKIgVGhlIHRhcmdl dCBwcm9jZXNzIGhhcyB1c2VkIHNpZ2FjdGlvbigyKSB0byBpbnN0YWxsIGEgc2lnbmFsCj4gICAg ICAgICAgaGFuZGxlciB3aXRoIHRoZSBTQV9SRVNUQVJUIGZsYWcuCj4gCj4gICAgICAgIOKAoiBU aGUgdGFyZ2V0IGhhcyBtYWRlIGEgc3lzdGVtIGNhbGwgdGhhdCB0cmlnZ2VyZWQgYSBzZWNjb21w IHVzZXItCj4gICAgICAgICAgc3BhY2Ugbm90aWZpY2F0aW9uIGFuZCB0aGUgdGFyZ2V0IGlzIGN1 cnJlbnRseSBibG9ja2VkIHVudGlsIHRoZQo+ICAgICAgICAgIHN1cGVydmlzb3Igc2VuZHMgYSBu b3RpZmljYXRpb24gcmVzcG9uc2UuCj4gCj4gICAgICAgIOKAoiBBIHNpZ25hbCBpcyBkZWxpdmVy ZWQgdG8gdGhlIHRhcmdldCBhbmQgdGhlIHNpZ25hbCBoYW5kbGVyIGlzCj4gICAgICAgICAgZXhl Y3V0ZWQuCj4gCj4gICAgICAgIOKAoiBXaGVuIChpZikgdGhlIHN1cGVydmlzb3IgYXR0ZW1wdHMg dG8gc2VuZCBhIG5vdGlmaWNhdGlvbgo+ICAgICAgICAgIHJlc3BvbnNlLCB0aGUgU0VDQ09NUF9J T0NUTF9OT1RJRl9TRU5EIGlvY3RsKDIpKSBvcGVyYXRpb24gd2lsbAo+ICAgICAgICAgIGZhaWwg d2l0aCB0aGUgRU5PRU5UIGVycm9yLgo+IAo+ICAgICAgICBJbiB0aGlzIHNjZW5hcmlvLCB0aGUg a2VybmVsIHdpbGwgcmVzdGFydCB0aGUgdGFyZ2V0J3Mgc3lzdGVtCj4gICAgICAgIGNhbGwuICBD b25zZXF1ZW50bHksIHRoZSBzdXBlcnZpc29yIHdpbGwgcmVjZWl2ZSBhbm90aGVyIHVzZXItCj4g ICAgICAgIHNwYWNlIG5vdGlmaWNhdGlvbi4gIFRodXMsIGRlcGVuZGluZyBvbiBob3cgbWFueSB0 aW1lcyB0aGUgYmxvY2tlZAo+ICAgICAgICBzeXN0ZW0gY2FsbCBpcyBpbnRlcnJ1cHRlZCBieSBh IHNpZ25hbCBoYW5kbGVyLCB0aGUgc3VwZXJ2aXNvciBtYXkKPiAgICAgICAgcmVjZWl2ZSBtdWx0 aXBsZSBub3RpZmljYXRpb25zIGZvciB0aGUgc2FtZSBzeXN0ZW0gY2FsbCBpbiB0aGUKCm1heWJl ICIuLi4gZm9yIHRoZSBzYW1lIGluc3RhbmNlIG9mIGEgc3lzdGVtIGNhbGwgaW4gdGhlIHRhcmdl dC4iIGZvcgpjbGFyaXR5PwoKPiAgICAgICAgdGFyZ2V0Lgo+IAo+ICAgICAgICBPbmUgb2RkaXR5 IGlzIHRoYXQgc3lzdGVtIGNhbGwgcmVzdGFydGluZyBhcyBkZXNjcmliZWQgaW4gdGhpcwo+ICAg ICAgICBzY2VuYXJpbyB3aWxsIG9jY3VyIGV2ZW4gZm9yIHRoZSBibG9ja2luZyBzeXN0ZW0gY2Fs bHMgbGlzdGVkIGluCj4gICAgICAgIHNpZ25hbCg3KSB0aGF0IHdvdWxkIG5ldmVyIG5vcm1hbGx5 IGJlIHJlc3RhcnRlZCBieSB0aGUgU0FfUkVTVEFSVAo+ICAgICAgICBmbGFnLgoKRG9lcyB0aGlz IG5lZWQgZml4aW5nPyBJIGltYWdpbmUgdGhlIGNvcnJlY3QgYmVoYXZpb3IgZm9yIHRoaXMgY2Fz ZQp3b3VsZCBiZSBhIHJlc3BvbnNlIHRvIF9TRU5EIG9mIEVJTlBST0dSRVNTIGFuZCB0aGUgdGFy Z2V0IHdvdWxkIHNlZQpFSU5UUiBub3JtYWxseT8KCkkgbWVhbiwgaXQncyBub3QgbGlrZSBzZWNj b21wIGRvZXNuJ3QgYWxyZWFkeSBleHBvc2Ugd2VpcmRuZXNzIHdpdGgKc3lzY2FsbCByZXN0YXJ0 cy4gTm90IGV2ZW4gYXJtNjQgY29tcGF0IGFncmVlc1szXSB3aXRoIGFybTMyIGluIHRoaXMKcmVn YXJkLiA6KAoKPiBCVUdTCj4gICAgICAgIElmIGEgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWIGlv Y3RsKDIpIG9wZXJhdGlvbiBpcyBwZXJmb3JtZWQKPiAgICAgICAgYWZ0ZXIgdGhlIHRhcmdldCB0 ZXJtaW5hdGVzLCB0aGVuIHRoZSBpb2N0bCgyKSBjYWxsIHNpbXBseSBibG9ja3MKPiAgICAgICAg KHJhdGhlciB0aGFuIHJldHVybmluZyBhbiBlcnJvciB0byBpbmRpY2F0ZSB0aGF0IHRoZSB0YXJn ZXQgbm8KPiAgICAgICAgbG9uZ2VyIGV4aXN0cykuCgpJIHdhbnQgdGhpcyBmaXhlZC4gSXQgY2F1 c2VkIG1lIG5vIGVuZCBvZiBwYWluIHdoZW4gYnVpbGRpbmcgdGhlCnNlbGZ0ZXN0cywgYW5kIGVu ZGVkIHVwIHNwYXduaW5nIG15IGltcGxlbWVudGluZyBhIGdsb2JhbCB0ZXN0IHRpbWVvdXQKaW4g a3NlbGZ0ZXN0LiA6UCBCZWZvcmUgdGhlIHVzYWdlIGNvdW50ZXIgcmVmYWN0b3IsIHRoZXJlIHdh cyBubyBzYW5lCndheSB0byBkZWFsIHdpdGggdGhpcywgYnV0IG5vdyBJIHRoaW5rIHdlJ3JlIGNs b3NlWzJdLiBJJ2xsIHJlcGx5CnNlcGFyYXRlbHkgYWJvdXQgdGhpcy4KCj4gCj4gRVhBTVBMRVMK PiAgICAgICAgVGhlIChzb21ld2hhdCBjb250cml2ZWQpIHByb2dyYW0gc2hvd24gYmVsb3cgZGVt b25zdHJhdGVzIHRoZSB1c2UKPiAgICAgICAgb2YgdGhlIGludGVyZmFjZXMgZGVzY3JpYmVkIGlu IHRoaXMgcGFnZS4gIFRoZSBwcm9ncmFtIGNyZWF0ZXMgYQo+ICAgICAgICBjaGlsZCBwcm9jZXNz IHRoYXQgc2VydmVzIGFzIHRoZSAidGFyZ2V0IiBwcm9jZXNzLiAgVGhlIGNoaWxkCj4gICAgICAg IHByb2Nlc3MgaW5zdGFsbHMgYSBzZWNjb21wIGZpbHRlciB0aGF0IHJldHVybnMgdGhlCj4gICAg ICAgIFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgYWN0aW9uIHZhbHVlIGlmIGEgY2FsbCBpcyBtYWRl IHRvIG1rZGlyKDIpLgo+ICAgICAgICBUaGUgY2hpbGQgcHJvY2VzcyB0aGVuIGNhbGxzIG1rZGly KDIpIG9uY2UgZm9yIGVhY2ggb2YgdGhlCj4gICAgICAgIHN1cHBsaWVkIGNvbW1hbmQtbGluZSBh cmd1bWVudHMsIGFuZCByZXBvcnRzIHRoZSByZXN1bHQgcmV0dXJuZWQKPiAgICAgICAgYnkgdGhl IGNhbGwuICBBZnRlciBwcm9jZXNzaW5nIGFsbCBhcmd1bWVudHMsIHRoZSBjaGlsZCBwcm9jZXNz Cj4gICAgICAgIHRlcm1pbmF0ZXMuCj4gCj4gICAgICAgIFRoZSBwYXJlbnQgcHJvY2VzcyBhY3Rz IGFzIHRoZSBzdXBlcnZpc29yLCBsaXN0ZW5pbmcgZm9yIHRoZQo+ICAgICAgICBub3RpZmljYXRp b25zIHRoYXQgYXJlIGdlbmVyYXRlZCB3aGVuIHRoZSB0YXJnZXQgcHJvY2VzcyBjYWxscwo+ICAg ICAgICBta2RpcigyKS4gIFdoZW4gc3VjaCBhIG5vdGlmaWNhdGlvbiBvY2N1cnMsIHRoZSBzdXBl cnZpc29yCj4gICAgICAgIGV4YW1pbmVzIHRoZSBtZW1vcnkgb2YgdGhlIHRhcmdldCBwcm9jZXNz ICh1c2luZyAvcHJvYy9bcGlkXS9tZW0pCj4gICAgICAgIHRvIGRpc2NvdmVyIHRoZSBwYXRobmFt ZSBhcmd1bWVudCB0aGF0IHdhcyBzdXBwbGllZCB0byB0aGUKPiAgICAgICAgbWtkaXIoMikgY2Fs bCwgYW5kIHBlcmZvcm1zIG9uZSBvZiB0aGUgZm9sbG93aW5nIGFjdGlvbnM6CgpJIGxpa2UgdGhp cyBleGFtcGxlISBJdCdzIHNpbXBsZSBlbm91Z2ggdG8gYmUgdW5kZXJzdGFuZGFibGUgYW5kIGNv bXBsZXgKZW5vdWdoIHRvIHNob3cgdGhlIHB1cnBvc2Ugb2YgdXNlcl9ub3RpZi4gOikKCj4gCj4g ICAgICAgIOKAoiBJZiB0aGUgcGF0aG5hbWUgYmVnaW5zIHdpdGggdGhlIHByZWZpeCAiL3RtcC8i LCB0aGVuIHRoZQo+ICAgICAgICAgIHN1cGVydmlzb3IgYXR0ZW1wdHMgdG8gY3JlYXRlIHRoZSBz cGVjaWZpZWQgZGlyZWN0b3J5LCBhbmQgdGhlbgo+ICAgICAgICAgIHNwb29mcyBhIHJldHVybiBm b3IgdGhlIHRhcmdldCBwcm9jZXNzIGJhc2VkIG9uIHRoZSByZXR1cm4gdmFsdWUKPiAgICAgICAg ICBvZiB0aGUgc3VwZXJ2aXNvcidzIG1rZGlyKDIpIGNhbGwuICBJbiB0aGUgZXZlbnQgdGhhdCB0 aGF0IGNhbGwKPiAgICAgICAgICBzdWNjZWVkcywgdGhlIHNwb29mZWQgc3VjY2VzcyByZXR1cm4g dmFsdWUgaXMgdGhlIGxlbmd0aCBvZiB0aGUKPiAgICAgICAgICBwYXRobmFtZS4KPiAKPiAgICAg ICAg4oCiIElmIHRoZSBwYXRobmFtZSBiZWdpbnMgd2l0aCAiLi8iIChpLmUuLCBpdCBpcyBhIHJl bGF0aXZlCj4gICAgICAgICAgcGF0aG5hbWUpLCB0aGUgc3VwZXJ2aXNvciBzZW5kcyBhCj4gICAg ICAgICAgU0VDQ09NUF9VU0VSX05PVElGX0ZMQUdfQ09OVElOVUUgcmVzcG9uc2UgdG8gdGhlIGtl cm5lbCB0byBzYXkKPiAgICAgICAgICB0aGF0IHRoZSBrZXJuZWwgc2hvdWxkIGV4ZWN1dGUgdGhl IHRhcmdldCBwcm9jZXNzJ3MgbWtkaXIoMikKPiAgICAgICAgICBjYWxsLgo+IAo+ICAgICAgICDi gKIgSWYgdGhlIHBhdGhuYW1lIGJlZ2lucyB3aXRoIHNvbWUgb3RoZXIgcHJlZml4LCB0aGUgc3Vw ZXJ2aXNvcgo+ICAgICAgICAgIHNwb29mcyBhbiBlcnJvciByZXR1cm4gZm9yIHRoZSB0YXJnZXQg cHJvY2Vzcywgc28gdGhhdCB0aGUKPiAgICAgICAgICB0YXJnZXQgcHJvY2VzcydzIG1rZGlyKDIp IGNhbGwgYXBwZWFycyB0byBmYWlsIHdpdGggdGhlIGVycm9yCj4gICAgICAgICAgRU9QTk9UU1VQ UCAoIk9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkIikuICBBZGRpdGlvbmFsbHksIGlmIHRoZQo+ICAg ICAgICAgIHNwZWNpZmllZCBwYXRobmFtZSBpcyBleGFjdGx5ICIvYnllIiwgdGhlbiB0aGUgc3Vw ZXJ2aXNvcgo+ICAgICAgICAgIHRlcm1pbmF0ZXMuCj4gCj4gICAgICAgIFRoaXMgcHJvZ3JhbSBj YW4gYmUgdXNlZCB0byBkZW1vbnN0cmF0ZSB2YXJpb3VzIGFzcGVjdHMgb2YgdGhlCj4gICAgICAg IGJlaGF2aW9yIG9mIHRoZSBzZWNjb21wIHVzZXItc3BhY2Ugbm90aWZpY2F0aW9uIG1lY2hhbmlz bS4gIFRvCj4gICAgICAgIGhlbHAgYWlkIHN1Y2ggZGVtb25zdHJhdGlvbnMsIHRoZSBwcm9ncmFt IGxvZ3MgdmFyaW91cyBtZXNzYWdlcyB0bwo+ICAgICAgICBzaG93IHRoZSBvcGVyYXRpb24gb2Yg dGhlIHRhcmdldCBwcm9jZXNzIChsaW5lcyBwcmVmaXhlZCAiVDoiKSBhbmQKPiAgICAgICAgdGhl IHN1cGVydmlzb3IgKGluZGVudGVkIGxpbmVzIHByZWZpeGVkICJTOiIpLgo+IAo+ICAgICAgICBJ biB0aGUgZm9sbG93aW5nIGV4YW1wbGUsIHRoZSB0YXJnZXQgYXR0ZW1wdHMgdG8gY3JlYXRlIHRo ZQo+ICAgICAgICBkaXJlY3RvcnkgL3RtcC94LiAgVXBvbiByZWNlaXZpbmcgdGhlIG5vdGlmaWNh dGlvbiwgdGhlIHN1cGVydmlzb3IKPiAgICAgICAgY3JlYXRlcyB0aGUgZGlyZWN0b3J5IG9uIHRo ZSB0YXJnZXQncyBiZWhhbGYsIGFuZCBzcG9vZnMgYSBzdWNjZXNzCj4gICAgICAgIHJldHVybiB0 byBiZSByZWNlaXZlZCBieSB0aGUgdGFyZ2V0IHByb2Nlc3MncyBta2RpcigyKSBjYWxsLgo+IAo+ ICAgICAgICAgICAgJCAuL3NlY2NvbXBfdW5vdGlmeSAvdG1wL3gKPiAgICAgICAgICAgIFQ6IFBJ RCA9IDIzMTY4Cj4gCj4gICAgICAgICAgICBUOiBhYm91dCB0byBta2RpcigiL3RtcC94IikKPiAg ICAgICAgICAgICAgICAgICAgUzogZ290IG5vdGlmaWNhdGlvbiAoSUQgMHgxNzQ0NWM0YTBmNGUw ZTNjKSBmb3IgUElEIDIzMTY4Cj4gICAgICAgICAgICAgICAgICAgIFM6IGV4ZWN1dGluZzogbWtk aXIoIi90bXAveCIsIDA3MDApCj4gICAgICAgICAgICAgICAgICAgIFM6IHN1Y2Nlc3MhIHNwb29m ZWQgcmV0dXJuID0gNgo+ICAgICAgICAgICAgICAgICAgICBTOiBzZW5kaW5nIHJlc3BvbnNlIChm bGFncyA9IDA7IHZhbCA9IDY7IGVycm9yID0gMCkKPiAgICAgICAgICAgIFQ6IFNVQ0NFU1M6IG1r ZGlyKDIpIHJldHVybmVkIDYKPiAKPiAgICAgICAgICAgIFQ6IHRlcm1pbmF0aW5nCj4gICAgICAg ICAgICAgICAgICAgIFM6IHRhcmdldCBoYXMgdGVybWluYXRlZDsgYnllCj4gCj4gICAgICAgIElu IHRoZSBhYm92ZSBvdXRwdXQsIG5vdGUgdGhhdCB0aGUgc3Bvb2ZlZCByZXR1cm4gdmFsdWUgc2Vl biBieQo+ICAgICAgICB0aGUgdGFyZ2V0IHByb2Nlc3MgaXMgNiAodGhlIGxlbmd0aCBvZiB0aGUg cGF0aG5hbWUgL3RtcC94KSwKPiAgICAgICAgd2hlcmVhcyBhIG5vcm1hbCBta2RpcigyKSBjYWxs IHJldHVybnMgMCBvbiBzdWNjZXNzLgo+IAo+ICAgICAgICBJbiB0aGUgbmV4dCBleGFtcGxlLCB0 aGUgdGFyZ2V0IGF0dGVtcHRzIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeQo+ICAgICAgICB1c2luZyB0 aGUgcmVsYXRpdmUgcGF0aG5hbWUgLi9zdWIuICBTaW5jZSB0aGlzIHBhdGhuYW1lIHN0YXJ0cwo+ ICAgICAgICB3aXRoICIuLyIsIHRoZSBzdXBlcnZpc29yIHNlbmRzIGEgU0VDQ09NUF9VU0VSX05P VElGX0ZMQUdfQ09OVElOVUUKPiAgICAgICAgcmVzcG9uc2UgdG8gdGhlIGtlcm5lbCwgYW5kIHRo ZSBrZXJuZWwgdGhlbiAoc3VjY2Vzc2Z1bGx5KQo+ICAgICAgICBleGVjdXRlcyB0aGUgdGFyZ2V0 IHByb2Nlc3MncyBta2RpcigyKSBjYWxsLgo+IAo+ICAgICAgICAgICAgJCAuL3NlY2NvbXBfdW5v dGlmeSAuL3N1Ygo+ICAgICAgICAgICAgVDogUElEID0gMjMyMDQKPiAKPiAgICAgICAgICAgIFQ6 IGFib3V0IHRvIG1rZGlyKCIuL3N1YiIpCj4gICAgICAgICAgICAgICAgICAgIFM6IGdvdCBub3Rp ZmljYXRpb24gKElEIDB4ZGRiMTZhYmUyNWI0YzEyKSBmb3IgUElEIDIzMjA0Cj4gICAgICAgICAg ICAgICAgICAgIFM6IHRhcmdldCBjYW4gZXhlY3V0ZSBzeXN0ZW0gY2FsbAo+ICAgICAgICAgICAg ICAgICAgICBTOiBzZW5kaW5nIHJlc3BvbnNlIChmbGFncyA9IDB4MTsgdmFsID0gMDsgZXJyb3Ig PSAwKQo+ICAgICAgICAgICAgVDogU1VDQ0VTUzogbWtkaXIoMikgcmV0dXJuZWQgMAo+IAo+ICAg ICAgICAgICAgVDogdGVybWluYXRpbmcKPiAgICAgICAgICAgICAgICAgICAgUzogdGFyZ2V0IGhh cyB0ZXJtaW5hdGVkOyBieWUKPiAKPiAgICAgICAgSWYgdGhlIHRhcmdldCBwcm9jZXNzIGF0dGVt cHRzIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSB3aXRoIGEKPiAgICAgICAgcGF0aG5hbWUgdGhhdCBk b2Vzbid0IHN0YXJ0IHdpdGggIi4iIGFuZCBkb2Vzbid0IGJlZ2luIHdpdGggdGhlCj4gICAgICAg IHByZWZpeCAiL3RtcC8iLCB0aGVuIHRoZSBzdXBlcnZpc29yIHNwb29mcyBhbiBlcnJvciByZXR1 cm4KPiAgICAgICAgKEVPUE5PVFNVUFAsICJPcGVyYXRpb24gbm90ICBzdXBwb3J0ZWQiKSBmb3Ig dGhlIHRhcmdldCdzIG1rZGlyKDIpCj4gICAgICAgIGNhbGwgKHdoaWNoIGlzIG5vdCBleGVjdXRl ZCk6Cj4gCj4gICAgICAgICAgICAkIC4vc2VjY29tcF91bm90aWZ5IC94eHgKPiAgICAgICAgICAg IFQ6IFBJRCA9IDIzMTc4Cj4gCj4gICAgICAgICAgICBUOiBhYm91dCB0byBta2RpcigiL3h4eCIp Cj4gICAgICAgICAgICAgICAgICAgIFM6IGdvdCBub3RpZmljYXRpb24gKElEIDB4ZTdkYzA5NWQx YzUyNGU4MCkgZm9yIFBJRCAyMzE3OAo+ICAgICAgICAgICAgICAgICAgICBTOiBzcG9vZmluZyBl cnJvciByZXNwb25zZSAoT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQpCj4gICAgICAgICAgICAgICAg ICAgIFM6IHNlbmRpbmcgcmVzcG9uc2UgKGZsYWdzID0gMDsgdmFsID0gMDsgZXJyb3IgPSAtOTUp Cj4gICAgICAgICAgICBUOiBFUlJPUjogbWtkaXIoMik6IE9wZXJhdGlvbiBub3Qgc3VwcG9ydGVk Cj4gCj4gICAgICAgICAgICBUOiB0ZXJtaW5hdGluZwo+ICAgICAgICAgICAgICAgICAgICBTOiB0 YXJnZXQgaGFzIHRlcm1pbmF0ZWQ7IGJ5ZQo+IAo+ICAgICAgICBJbiB0aGUgbmV4dCBleGFtcGxl LCB0aGUgdGFyZ2V0IHByb2Nlc3MgYXR0ZW1wdHMgdG8gY3JlYXRlIGEKPiAgICAgICAgZGlyZWN0 b3J5IHdpdGggdGhlIHBhdGhuYW1lIC90bXAvbm9zdWNoZGlyL2IuICBVcG9uIHJlY2VpdmluZyB0 aGUKPiAgICAgICAgbm90aWZpY2F0aW9uLCB0aGUgc3VwZXJ2aXNvciBhdHRlbXB0cyB0byBjcmVh dGUgdGhhdCBkaXJlY3RvcnksCj4gICAgICAgIGJ1dCB0aGUgbWtkaXIoMikgY2FsbCBmYWlscyBi ZWNhdXNlIHRoZSBkaXJlY3RvcnkgL3RtcC9ub3N1Y2hkaXIKPiAgICAgICAgZG9lcyBub3QgZXhp c3QuICBDb25zZXF1ZW50bHksIHRoZSBzdXBlcnZpc29yIHNwb29mcyBhbiBlcnJvcgo+ICAgICAg ICByZXR1cm4gdGhhdCBwYXNzZXMgdGhlIGVycm9yIHRoYXQgaXQgcmVjZWl2ZWQgYmFjayB0byB0 aGUgdGFyZ2V0Cj4gICAgICAgIHByb2Nlc3MncyBta2RpcigyKSBjYWxsLgo+IAo+ICAgICAgICAg ICAgJCAuL3NlY2NvbXBfdW5vdGlmeSAvdG1wL25vc3VjaGRpci9iCj4gICAgICAgICAgICBUOiBQ SUQgPSAyMzE5OQo+IAo+ICAgICAgICAgICAgVDogYWJvdXQgdG8gbWtkaXIoIi90bXAvbm9zdWNo ZGlyL2IiKQo+ICAgICAgICAgICAgICAgICAgICBTOiBnb3Qgbm90aWZpY2F0aW9uIChJRCAweDg3 NDQ0NTQyOTM1MDYwNDYpIGZvciBQSUQgMjMxOTkKPiAgICAgICAgICAgICAgICAgICAgUzogZXhl Y3V0aW5nOiBta2RpcigiL3RtcC9ub3N1Y2hkaXIvYiIsIDA3MDApCj4gICAgICAgICAgICAgICAg ICAgIFM6IGZhaWx1cmUhIChlcnJubyA9IDI7IE5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkpCj4g ICAgICAgICAgICAgICAgICAgIFM6IHNlbmRpbmcgcmVzcG9uc2UgKGZsYWdzID0gMDsgdmFsID0g MDsgZXJyb3IgPSAtMikKPiAgICAgICAgICAgIFQ6IEVSUk9SOiBta2RpcigyKTogTm8gc3VjaCBm aWxlIG9yIGRpcmVjdG9yeQo+IAo+ICAgICAgICAgICAgVDogdGVybWluYXRpbmcKPiAgICAgICAg ICAgICAgICAgICAgUzogdGFyZ2V0IGhhcyB0ZXJtaW5hdGVkOyBieWUKPiAKPiAgICAgICAgSWYg dGhlIHN1cGVydmlzb3IgcmVjZWl2ZXMgYSBub3RpZmljYXRpb24gYW5kIHNlZXMgdGhhdCB0aGUK PiAgICAgICAgYXJndW1lbnQgb2YgdGhlIHRhcmdldCdzIG1rZGlyKDIpIGlzIHRoZSBzdHJpbmcg Ii9ieWUiLCB0aGVuIChhcwo+ICAgICAgICB3ZWxsIGFzIHNwb29maW5nIGFuIEVPUE5PVFNVUFAg ZXJyb3IpLCB0aGUgc3VwZXJ2aXNvciB0ZXJtaW5hdGVzLgo+ICAgICAgICBJZiB0aGUgdGFyZ2V0 IHByb2Nlc3Mgc3Vic2VxdWVudGx5IGV4ZWN1dGVzIGFub3RoZXIgbWtkaXIoMikgdGhhdAo+ICAg ICAgICB0cmlnZ2VycyBpdHMgc2VjY29tcCBmaWx0ZXIgdG8gcmV0dXJuIHRoZSBTRUNDT01QX1JF VF9VU0VSX05PVElGCj4gICAgICAgIGFjdGlvbiB2YWx1ZSwgdGhlbiB0aGUga2VybmVsIGNhdXNl cyB0aGUgdGFyZ2V0IHByb2Nlc3MncyBzeXN0ZW0KPiAgICAgICAgY2FsbCB0byBmYWlsIHdpdGgg dGhlIGVycm9yIEVOT1NZUyAoIkZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZCIpLgo+ICAgICAgICBU aGlzIGlzIGRlbW9uc3RyYXRlZCBieSB0aGUgZm9sbG93aW5nIGV4YW1wbGU6Cj4gCj4gICAgICAg ICAgICAkIC4vc2VjY29tcF91bm90aWZ5IC9ieWUgL3RtcC95Cj4gICAgICAgICAgICBUOiBQSUQg PSAyMzE4NQo+IAo+ICAgICAgICAgICAgVDogYWJvdXQgdG8gbWtkaXIoIi9ieWUiKQo+ICAgICAg ICAgICAgICAgICAgICBTOiBnb3Qgbm90aWZpY2F0aW9uIChJRCAweGE4MTIzNmIxZDJmN2IwZjQp IGZvciBQSUQgMjMxODUKPiAgICAgICAgICAgICAgICAgICAgUzogc3Bvb2ZpbmcgZXJyb3IgcmVz cG9uc2UgKE9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkKQo+ICAgICAgICAgICAgICAgICAgICBTOiBz ZW5kaW5nIHJlc3BvbnNlIChmbGFncyA9IDA7IHZhbCA9IDA7IGVycm9yID0gLTk1KQo+ICAgICAg ICAgICAgICAgICAgICBTOiB0ZXJtaW5hdGluZyAqKioqKioqKioqCj4gICAgICAgICAgICBUOiBF UlJPUjogbWtkaXIoMik6IE9wZXJhdGlvbiBub3Qgc3VwcG9ydGVkCj4gCj4gICAgICAgICAgICBU OiBhYm91dCB0byBta2RpcigiL3RtcC95IikKPiAgICAgICAgICAgIFQ6IEVSUk9SOiBta2Rpcigy KTogRnVuY3Rpb24gbm90IGltcGxlbWVudGVkCj4gCj4gICAgICAgICAgICBUOiB0ZXJtaW5hdGlu Zwo+IAo+ICAgIFByb2dyYW0gc291cmNlCj4gICAgICAgICNkZWZpbmUgX0dOVV9TT1VSQ0UKPiAg ICAgICAgI2luY2x1ZGUgPHN5cy90eXBlcy5oPgo+ICAgICAgICAjaW5jbHVkZSA8c3lzL3ByY3Rs Lmg+Cj4gICAgICAgICNpbmNsdWRlIDxmY250bC5oPgo+ICAgICAgICAjaW5jbHVkZSA8bGltaXRz Lmg+Cj4gICAgICAgICNpbmNsdWRlIDxzaWduYWwuaD4KPiAgICAgICAgI2luY2x1ZGUgPHN0ZGRl Zi5oPgo+ICAgICAgICAjaW5jbHVkZSA8c3RkaW50Lmg+Cj4gICAgICAgICNpbmNsdWRlIDxzdGRi b29sLmg+Cj4gICAgICAgICNpbmNsdWRlIDxsaW51eC9hdWRpdC5oPgo+ICAgICAgICAjaW5jbHVk ZSA8c3lzL3N5c2NhbGwuaD4KPiAgICAgICAgI2luY2x1ZGUgPHN5cy9zdGF0Lmg+Cj4gICAgICAg ICNpbmNsdWRlIDxsaW51eC9maWx0ZXIuaD4KPiAgICAgICAgI2luY2x1ZGUgPGxpbnV4L3NlY2Nv bXAuaD4KPiAgICAgICAgI2luY2x1ZGUgPHN5cy9pb2N0bC5oPgo+ICAgICAgICAjaW5jbHVkZSA8 c3RkaW8uaD4KPiAgICAgICAgI2luY2x1ZGUgPHN0ZGxpYi5oPgo+ICAgICAgICAjaW5jbHVkZSA8 dW5pc3RkLmg+Cj4gICAgICAgICNpbmNsdWRlIDxlcnJuby5oPgo+ICAgICAgICAjaW5jbHVkZSA8 c3lzL3NvY2tldC5oPgo+ICAgICAgICAjaW5jbHVkZSA8c3lzL3VuLmg+Cj4gCj4gICAgICAgICNk ZWZpbmUgZXJyRXhpdChtc2cpICAgIGRvIHsgcGVycm9yKG1zZyk7IGV4aXQoRVhJVF9GQUlMVVJF KTsgXAo+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IHdoaWxlICgwKQoKQmVjYXVz ZSBJIGxvdmUgbWFjcm9zLCB5b3UgY2FuIGV4cGFuZCB0aGlzIHRvIG1ha2UgaXQgdGFrZSBhIGZv cm1hdApzdHJpbmc6CgojZGVmaW5lIGVyckV4aXQoZm10LCAuLi4pCWRvIHsJCQkJCVwKCQljaGFy IF9fZXJyWzY0XTsJCQkJCQlcCgkJc3RyZXJyb3JfcihlcnJubywgX19lcnIsIHNpemVvZihfX2Vy cikpOwkJXAoJCWZwcmludGYoc3RkZXJyLCBmbXQgIjogJXNcbiIsICMjX19WQV9BUkdfXywgX19l cnIpOwlcCgkJZXhpdChFWElUX0ZBSUxVUkUpOwkJCQkJXAoJfSB3aGlsZSAoMCkKCj4gCj4gICAg ICAgIC8qIFNlbmQgdGhlIGZpbGUgZGVzY3JpcHRvciAnZmQnIG92ZXIgdGhlIGNvbm5lY3RlZCBV TklYIGRvbWFpbiBzb2NrZXQKPiAgICAgICAgICAgJ3NvY2tmZCcuIFJldHVybnMgMCBvbiBzdWNj ZXNzLCBvciAtMSBvbiBlcnJvci4gKi8KPiAKPiAgICAgICAgc3RhdGljIGludAo+ICAgICAgICBz ZW5kZmQoaW50IHNvY2tmZCwgaW50IGZkKQo+ICAgICAgICB7Cj4gICAgICAgICAgICBzdHJ1Y3Qg bXNnaGRyIG1zZ2g7Cj4gICAgICAgICAgICBzdHJ1Y3QgaW92ZWMgaW92Owo+ICAgICAgICAgICAg aW50IGRhdGE7Cj4gICAgICAgICAgICBzdHJ1Y3QgY21zZ2hkciAqY21zZ3A7Cj4gCj4gICAgICAg ICAgICAvKiBBbGxvY2F0ZSBhIGNoYXIgYXJyYXkgb2Ygc3VpdGFibGUgc2l6ZSB0byBob2xkIHRo ZSBhbmNpbGxhcnkgZGF0YS4KPiAgICAgICAgICAgICAgIEhvd2V2ZXIsIHNpbmNlIHRoaXMgYnVm ZmVyIGlzIGluIHJlYWxpdHkgYSAnc3RydWN0IGNtc2doZHInLCB1c2UgYQo+ICAgICAgICAgICAg ICAgdW5pb24gdG8gZW5zdXJlIHRoYXQgaXQgaXMgc3VpdGFibHkgYWxpZ25lZC4gKi8KPiAgICAg ICAgICAgIHVuaW9uIHsKPiAgICAgICAgICAgICAgICBjaGFyICAgYnVmW0NNU0dfU1BBQ0Uoc2l6 ZW9mKGludCkpXTsKPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogU3BhY2UgbGFy Z2UgZW5vdWdoIHRvIGhvbGQgYW4gJ2ludCcgKi8KPiAgICAgICAgICAgICAgICBzdHJ1Y3QgY21z Z2hkciBhbGlnbjsKPiAgICAgICAgICAgIH0gY29udHJvbE1zZzsKPiAKPiAgICAgICAgICAgIC8q IFRoZSAnbXNnX25hbWUnIGZpZWxkIGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGFkZHJlc3Mg b2YgdGhlCj4gICAgICAgICAgICAgICBkZXN0aW5hdGlvbiBzb2NrZXQgd2hlbiBzZW5kaW5nIGEg ZGF0YWdyYW0uIEhvd2V2ZXIsIHdlIGRvIG5vdAo+ICAgICAgICAgICAgICAgbmVlZCB0byB1c2Ug dGhpcyBmaWVsZCBiZWNhdXNlICdzb2NrZmQnIGlzIGEgY29ubmVjdGVkIHNvY2tldC4gKi8KPiAK PiAgICAgICAgICAgIG1zZ2gubXNnX25hbWUgPSBOVUxMOwo+ICAgICAgICAgICAgbXNnaC5tc2df bmFtZWxlbiA9IDA7Cj4gCj4gICAgICAgICAgICAvKiBPbiBMaW51eCwgd2UgbXVzdCB0cmFuc21p dCBhdCBsZWFzdCBvbmUgYnl0ZSBvZiByZWFsIGRhdGEgaW4KPiAgICAgICAgICAgICAgIG9yZGVy IHRvIHNlbmQgYW5jaWxsYXJ5IGRhdGEuIFdlIHRyYW5zbWl0IGFuIGFyYml0cmFyeSBpbnRlZ2Vy Cj4gICAgICAgICAgICAgICB3aG9zZSB2YWx1ZSBpcyBpZ25vcmVkIGJ5IHJlY3ZmZCgpLiAqLwo+ IAo+ICAgICAgICAgICAgbXNnaC5tc2dfaW92ID0gJmlvdjsKPiAgICAgICAgICAgIG1zZ2gubXNn X2lvdmxlbiA9IDE7Cj4gICAgICAgICAgICBpb3YuaW92X2Jhc2UgPSAmZGF0YTsKPiAgICAgICAg ICAgIGlvdi5pb3ZfbGVuID0gc2l6ZW9mKGludCk7Cj4gICAgICAgICAgICBkYXRhID0gMTIzNDU7 Cj4gCj4gICAgICAgICAgICAvKiBTZXQgJ21zZ2hkcicgZmllbGRzIHRoYXQgZGVzY3JpYmUgYW5j aWxsYXJ5IGRhdGEgKi8KPiAKPiAgICAgICAgICAgIG1zZ2gubXNnX2NvbnRyb2wgPSBjb250cm9s TXNnLmJ1ZjsKPiAgICAgICAgICAgIG1zZ2gubXNnX2NvbnRyb2xsZW4gPSBzaXplb2YoY29udHJv bE1zZy5idWYpOwo+IAo+ICAgICAgICAgICAgLyogU2V0IHVwIGFuY2lsbGFyeSBkYXRhIGRlc2Ny aWJpbmcgZmlsZSBkZXNjcmlwdG9yIHRvIHNlbmQgKi8KPiAKPiAgICAgICAgICAgIGNtc2dwID0g Q01TR19GSVJTVEhEUigmbXNnaCk7Cj4gICAgICAgICAgICBjbXNncC0+Y21zZ19sZXZlbCA9IFNP TF9TT0NLRVQ7Cj4gICAgICAgICAgICBjbXNncC0+Y21zZ190eXBlID0gU0NNX1JJR0hUUzsKPiAg ICAgICAgICAgIGNtc2dwLT5jbXNnX2xlbiA9IENNU0dfTEVOKHNpemVvZihpbnQpKTsKPiAgICAg ICAgICAgIG1lbWNweShDTVNHX0RBVEEoY21zZ3ApLCAmZmQsIHNpemVvZihpbnQpKTsKPiAKPiAg ICAgICAgICAgIC8qIFNlbmQgcmVhbCBwbHVzIGFuY2lsbGFyeSBkYXRhICovCj4gCj4gICAgICAg ICAgICBpZiAoc2VuZG1zZyhzb2NrZmQsICZtc2doLCAwKSA9PSAtMSkKPiAgICAgICAgICAgICAg ICByZXR1cm4gLTE7Cj4gCj4gICAgICAgICAgICByZXR1cm4gMDsKPiAgICAgICAgfQo+IAo+ICAg ICAgICAvKiBSZWNlaXZlIGEgZmlsZSBkZXNjcmlwdG9yIG9uIGEgY29ubmVjdGVkIFVOSVggZG9t YWluIHNvY2tldC4gUmV0dXJucwo+ICAgICAgICAgICB0aGUgcmVjZWl2ZWQgZmlsZSBkZXNjcmlw dG9yIG9uIHN1Y2Nlc3MsIG9yIC0xIG9uIGVycm9yLiAqLwo+IAo+ICAgICAgICBzdGF0aWMgaW50 Cj4gICAgICAgIHJlY3ZmZChpbnQgc29ja2ZkKQo+ICAgICAgICB7Cj4gICAgICAgICAgICBzdHJ1 Y3QgbXNnaGRyIG1zZ2g7Cj4gICAgICAgICAgICBzdHJ1Y3QgaW92ZWMgaW92Owo+ICAgICAgICAg ICAgaW50IGRhdGEsIGZkOwo+ICAgICAgICAgICAgc3NpemVfdCBucjsKPiAKPiAgICAgICAgICAg IC8qIEFsbG9jYXRlIGEgY2hhciBidWZmZXIgZm9yIHRoZSBhbmNpbGxhcnkgZGF0YS4gU2VlIHRo ZSBjb21tZW50cwo+ICAgICAgICAgICAgICAgaW4gc2VuZGZkKCkgKi8KPiAgICAgICAgICAgIHVu aW9uIHsKPiAgICAgICAgICAgICAgICBjaGFyICAgYnVmW0NNU0dfU1BBQ0Uoc2l6ZW9mKGludCkp XTsKPiAgICAgICAgICAgICAgICBzdHJ1Y3QgY21zZ2hkciBhbGlnbjsKPiAgICAgICAgICAgIH0g Y29udHJvbE1zZzsKPiAgICAgICAgICAgIHN0cnVjdCBjbXNnaGRyICpjbXNncDsKPiAKPiAgICAg ICAgICAgIC8qIFRoZSAnbXNnX25hbWUnIGZpZWxkIGNhbiBiZSB1c2VkIHRvIG9idGFpbiB0aGUg YWRkcmVzcyBvZiB0aGUKPiAgICAgICAgICAgICAgIHNlbmRpbmcgc29ja2V0LiBIb3dldmVyLCB3 ZSBkbyBub3QgbmVlZCB0aGlzIGluZm9ybWF0aW9uLiAqLwo+IAo+ICAgICAgICAgICAgbXNnaC5t c2dfbmFtZSA9IE5VTEw7Cj4gICAgICAgICAgICBtc2doLm1zZ19uYW1lbGVuID0gMDsKPiAKPiAg ICAgICAgICAgIC8qIFNwZWNpZnkgYnVmZmVyIGZvciByZWNlaXZpbmcgcmVhbCBkYXRhICovCj4g Cj4gICAgICAgICAgICBtc2doLm1zZ19pb3YgPSAmaW92Owo+ICAgICAgICAgICAgbXNnaC5tc2df aW92bGVuID0gMTsKPiAgICAgICAgICAgIGlvdi5pb3ZfYmFzZSA9ICZkYXRhOyAgICAgICAvKiBS ZWFsIGRhdGEgaXMgYW4gJ2ludCcgKi8KPiAgICAgICAgICAgIGlvdi5pb3ZfbGVuID0gc2l6ZW9m KGludCk7Cj4gCj4gICAgICAgICAgICAvKiBTZXQgJ21zZ2hkcicgZmllbGRzIHRoYXQgZGVzY3Jp YmUgYW5jaWxsYXJ5IGRhdGEgKi8KPiAKPiAgICAgICAgICAgIG1zZ2gubXNnX2NvbnRyb2wgPSBj b250cm9sTXNnLmJ1ZjsKPiAgICAgICAgICAgIG1zZ2gubXNnX2NvbnRyb2xsZW4gPSBzaXplb2Yo Y29udHJvbE1zZy5idWYpOwo+IAo+ICAgICAgICAgICAgLyogUmVjZWl2ZSByZWFsIHBsdXMgYW5j aWxsYXJ5IGRhdGE7IHJlYWwgZGF0YSBpcyBpZ25vcmVkICovCj4gCj4gICAgICAgICAgICBuciA9 IHJlY3Ztc2coc29ja2ZkLCAmbXNnaCwgMCk7Cj4gICAgICAgICAgICBpZiAobnIgPT0gLTEpCj4g ICAgICAgICAgICAgICAgcmV0dXJuIC0xOwo+IAo+ICAgICAgICAgICAgY21zZ3AgPSBDTVNHX0ZJ UlNUSERSKCZtc2doKTsKPiAKPiAgICAgICAgICAgIC8qIENoZWNrIHRoZSB2YWxpZGl0eSBvZiB0 aGUgJ2Ntc2doZHInICovCj4gCj4gICAgICAgICAgICBpZiAoY21zZ3AgPT0gTlVMTCB8fAo+ICAg ICAgICAgICAgICAgICAgICBjbXNncC0+Y21zZ19sZW4gIT0gQ01TR19MRU4oc2l6ZW9mKGludCkp IHx8Cj4gICAgICAgICAgICAgICAgICAgIGNtc2dwLT5jbXNnX2xldmVsICE9IFNPTF9TT0NLRVQg fHwKPiAgICAgICAgICAgICAgICAgICAgY21zZ3AtPmNtc2dfdHlwZSAhPSBTQ01fUklHSFRTKSB7 Cj4gICAgICAgICAgICAgICAgZXJybm8gPSBFSU5WQUw7Cj4gICAgICAgICAgICAgICAgcmV0dXJu IC0xOwo+ICAgICAgICAgICAgfQo+IAo+ICAgICAgICAgICAgLyogUmV0dXJuIHRoZSByZWNlaXZl ZCBmaWxlIGRlc2NyaXB0b3IgdG8gb3VyIGNhbGxlciAqLwo+IAo+ICAgICAgICAgICAgbWVtY3B5 KCZmZCwgQ01TR19EQVRBKGNtc2dwKSwgc2l6ZW9mKGludCkpOwo+ICAgICAgICAgICAgcmV0dXJu IGZkOwo+ICAgICAgICB9Cj4gCj4gICAgICAgIHN0YXRpYyB2b2lkCj4gICAgICAgIHNpZ2NobGRI YW5kbGVyKGludCBzaWcpCj4gICAgICAgIHsKPiAgICAgICAgICAgIGNoYXIgKm1zZyAgPSAiXHRT OiB0YXJnZXQgaGFzIHRlcm1pbmF0ZWQ7IGJ5ZVxuIjsKPiAKPiAgICAgICAgICAgIHdyaXRlKFNU RE9VVF9GSUxFTk8sIG1zZywgc3RybGVuKG1zZykpOwoKd2hpdGUgc3BhY2Ugbml0OiBleHRyYSBz cGFjZSBiZWZvcmUgIj0iCmVmZmljaWVuY3kgbml0OiBzdHJsZW4gaXNuJ3QgbmVlZGVkLCBzaW5j ZSBpdCBjYW4gYmUgZG9uZSB3aXRoCmNvbXBpbGUtdGltZSBjb25zdGFudCBjb25zdGFudHM6Cgog ICAgICAgICAgICAgY2hhciBtc2dbXSA9ICJcdFM6IHRhcmdldCBoYXMgdGVybWluYXRlZDsgYnll XG4iOwogICAgICAgICAgICAgd3JpdGUoU1RET1VUX0ZJTEVOTywgbXNnLCBzaXplb2YobXNnKSAt IDEpOwoKKHNvbWUgb3B0aW1pemF0aW9uIGxldmVscyBtYXkgYWxyZWFkeSByZXBsYWNlIHRoZSBz dHJsZW4gYSBzaXplb2YgLSAxKQoKPiAgICAgICAgICAgIF9leGl0KEVYSVRfU1VDQ0VTUyk7Cj4g ICAgICAgIH0KPiAKPiAgICAgICAgc3RhdGljIGludAo+ICAgICAgICBzZWNjb21wKHVuc2lnbmVk IGludCBvcGVyYXRpb24sIHVuc2lnbmVkIGludCBmbGFncywgdm9pZCAqYXJncykKPiAgICAgICAg ewo+ICAgICAgICAgICAgcmV0dXJuIHN5c2NhbGwoX19OUl9zZWNjb21wLCBvcGVyYXRpb24sIGZs YWdzLCBhcmdzKTsKPiAgICAgICAgfQo+IAo+ICAgICAgICAvKiBUaGUgZm9sbG93aW5nIGlzIHRo ZSB4ODYtNjQtc3BlY2lmaWMgQlBGIGJvaWxlcnBsYXRlIGNvZGUgZm9yIGNoZWNraW5nCj4gICAg ICAgICAgIHRoYXQgdGhlIEJQRiBwcm9ncmFtIGlzIHJ1bm5pbmcgb24gdGhlIHJpZ2h0IGFyY2hp dGVjdHVyZSArIEFCSS4gQXQKPiAgICAgICAgICAgY29tcGxldGlvbiBvZiB0aGVzZSBpbnN0cnVj dGlvbnMsIHRoZSBhY2N1bXVsYXRvciBjb250YWlucyB0aGUgc3lzdGVtCj4gICAgICAgICAgIGNh bGwgbnVtYmVyLiAqLwo+IAo+ICAgICAgICAvKiBGb3IgdGhlIHgzMiBBQkksIGFsbCBzeXN0ZW0g Y2FsbCBudW1iZXJzIGhhdmUgYml0IDMwIHNldCAqLwo+IAo+ICAgICAgICAjZGVmaW5lIFgzMl9T WVNDQUxMX0JJVCAgICAgICAgIDB4NDAwMDAwMDAKPiAKPiAgICAgICAgI2RlZmluZSBYODZfNjRf Q0hFQ0tfQVJDSF9BTkRfTE9BRF9TWVNDQUxMX05SIFwKPiAgICAgICAgICAgICAgICBCUEZfU1RN VChCUEZfTEQgfCBCUEZfVyB8IEJQRl9BQlMsIFwKPiAgICAgICAgICAgICAgICAgICAgICAgIChv ZmZzZXRvZihzdHJ1Y3Qgc2VjY29tcF9kYXRhLCBhcmNoKSkpLCBcCj4gICAgICAgICAgICAgICAg QlBGX0pVTVAoQlBGX0pNUCB8IEJQRl9KRVEgfCBCUEZfSywgQVVESVRfQVJDSF9YODZfNjQsIDAs IDIpLCBcCj4gICAgICAgICAgICAgICAgQlBGX1NUTVQoQlBGX0xEIHwgQlBGX1cgfCBCUEZfQUJT LCBcCj4gICAgICAgICAgICAgICAgICAgICAgICAgKG9mZnNldG9mKHN0cnVjdCBzZWNjb21wX2Rh dGEsIG5yKSkpLCBcCj4gICAgICAgICAgICAgICAgQlBGX0pVTVAoQlBGX0pNUCB8IEJQRl9KR0Ug fCBCUEZfSywgWDMyX1NZU0NBTExfQklULCAwLCAxKSwgXAo+ICAgICAgICAgICAgICAgIEJQRl9T VE1UKEJQRl9SRVQgfCBCUEZfSywgU0VDQ09NUF9SRVRfS0lMTF9QUk9DRVNTKQo+IAo+ICAgICAg ICAvKiBpbnN0YWxsTm90aWZ5RmlsdGVyKCkgaW5zdGFsbHMgYSBzZWNjb21wIGZpbHRlciB0aGF0 IGdlbmVyYXRlcwo+ICAgICAgICAgICB1c2VyLXNwYWNlIG5vdGlmaWNhdGlvbnMgKFNFQ0NPTVBf UkVUX1VTRVJfTk9USUYpIHdoZW4gdGhlIHByb2Nlc3MKPiAgICAgICAgICAgY2FsbHMgbWtkaXIo Mik7IHRoZSBmaWx0ZXIgYWxsb3dzIGFsbCBvdGhlciBzeXN0ZW0gY2FsbHMuCj4gCj4gICAgICAg ICAgIFRoZSBmdW5jdGlvbiByZXR1cm4gdmFsdWUgaXMgYSBmaWxlIGRlc2NyaXB0b3IgZnJvbSB3 aGljaCB0aGUKPiAgICAgICAgICAgdXNlci1zcGFjZSBub3RpZmljYXRpb25zIGNhbiBiZSBmZXRj aGVkLiAqLwo+IAo+ICAgICAgICBzdGF0aWMgaW50Cj4gICAgICAgIGluc3RhbGxOb3RpZnlGaWx0 ZXIodm9pZCkKPiAgICAgICAgewo+ICAgICAgICAgICAgc3RydWN0IHNvY2tfZmlsdGVyIGZpbHRl cltdID0gewo+ICAgICAgICAgICAgICAgIFg4Nl82NF9DSEVDS19BUkNIX0FORF9MT0FEX1NZU0NB TExfTlIsCj4gCj4gICAgICAgICAgICAgICAgLyogbWtkaXIoKSB0cmlnZ2VycyBub3RpZmljYXRp b24gdG8gdXNlci1zcGFjZSBzdXBlcnZpc29yICovCj4gCj4gICAgICAgICAgICAgICAgQlBGX0pV TVAoQlBGX0pNUCB8IEJQRl9KRVEgfCBCUEZfSywgX19OUl9ta2RpciwgMCwgMSksCj4gICAgICAg ICAgICAgICAgQlBGX1NUTVQoQlBGX1JFVCArIEJQRl9LLCBTRUNDT01QX1JFVF9VU0VSX05PVElG KSwKPiAKPiAgICAgICAgICAgICAgICAvKiBFdmVyeSBvdGhlciBzeXN0ZW0gY2FsbCBpcyBhbGxv d2VkICovCj4gCj4gICAgICAgICAgICAgICAgQlBGX1NUTVQoQlBGX1JFVCB8IEJQRl9LLCBTRUND T01QX1JFVF9BTExPVyksCj4gICAgICAgICAgICB9Owo+IAo+ICAgICAgICAgICAgc3RydWN0IHNv Y2tfZnByb2cgcHJvZyA9IHsKPiAgICAgICAgICAgICAgICAubGVuID0gc2l6ZW9mKGZpbHRlcikg LyBzaXplb2YoZmlsdGVyWzBdKSwKPiAgICAgICAgICAgICAgICAuZmlsdGVyID0gZmlsdGVyLAo+ ICAgICAgICAgICAgfTsKPiAKPiAgICAgICAgICAgIC8qIEluc3RhbGwgdGhlIGZpbHRlciB3aXRo IHRoZSBTRUNDT01QX0ZJTFRFUl9GTEFHX05FV19MSVNURU5FUiBmbGFnOwo+ICAgICAgICAgICAg ICAgYXMgYSByZXN1bHQsIHNlY2NvbXAoKSByZXR1cm5zIGEgbm90aWZpY2F0aW9uIGZpbGUgZGVz Y3JpcHRvci4gKi8KPiAKPiAgICAgICAgICAgIGludCBub3RpZnlGZCA9IHNlY2NvbXAoU0VDQ09N UF9TRVRfTU9ERV9GSUxURVIsCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNF Q0NPTVBfRklMVEVSX0ZMQUdfTkVXX0xJU1RFTkVSLCAmcHJvZyk7Cj4gICAgICAgICAgICBpZiAo bm90aWZ5RmQgPT0gLTEpCj4gICAgICAgICAgICAgICAgZXJyRXhpdCgic2VjY29tcC1pbnN0YWxs LW5vdGlmeS1maWx0ZXIiKTsKPiAKPiAgICAgICAgICAgIHJldHVybiBub3RpZnlGZDsKPiAgICAg ICAgfQo+IAo+ICAgICAgICAvKiBDbG9zZSBhIHBhaXIgb2Ygc29ja2V0cyBjcmVhdGVkIGJ5IHNv Y2tldHBhaXIoKSAqLwo+IAo+ICAgICAgICBzdGF0aWMgdm9pZAo+ICAgICAgICBjbG9zZVNvY2tl dFBhaXIoaW50IHNvY2tQYWlyWzJdKQo+ICAgICAgICB7Cj4gICAgICAgICAgICBpZiAoY2xvc2Uo c29ja1BhaXJbMF0pID09IC0xKQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoImNsb3NlU29ja2V0 UGFpci1jbG9zZS0wIik7Cj4gICAgICAgICAgICBpZiAoY2xvc2Uoc29ja1BhaXJbMV0pID09IC0x KQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoImNsb3NlU29ja2V0UGFpci1jbG9zZS0xIik7Cj4g ICAgICAgIH0KPiAKPiAgICAgICAgLyogSW1wbGVtZW50YXRpb24gb2YgdGhlIHRhcmdldCBwcm9j ZXNzOyBjcmVhdGUgYSBjaGlsZCBwcm9jZXNzIHRoYXQ6Cj4gCj4gICAgICAgICAgICgxKSBpbnN0 YWxscyBhIHNlY2NvbXAgZmlsdGVyIHdpdGggdGhlCj4gICAgICAgICAgICAgICBTRUNDT01QX0ZJ TFRFUl9GTEFHX05FV19MSVNURU5FUiBmbGFnOwo+ICAgICAgICAgICAoMikgd3JpdGVzIHRoZSBz ZWNjb21wIG5vdGlmaWNhdGlvbiBmaWxlIGRlc2NyaXB0b3IgcmV0dXJuZWQgZnJvbQo+ICAgICAg ICAgICAgICAgdGhlIHByZXZpb3VzIHN0ZXAgb250byB0aGUgVU5JWCBkb21haW4gc29ja2V0LCAn c29ja1BhaXJbMF0nOwo+ICAgICAgICAgICAoMykgY2FsbHMgbWtkaXIoMikgZm9yIGVhY2ggZWxl bWVudCBvZiAnYXJndicuCj4gCj4gICAgICAgICAgIFRoZSBmdW5jdGlvbiByZXR1cm4gdmFsdWUg aW4gdGhlIHBhcmVudCBpcyB0aGUgUElEIG9mIHRoZSBjaGlsZAo+ICAgICAgICAgICBwcm9jZXNz OyB0aGUgY2hpbGQgZG9lcyBub3QgcmV0dXJuIGZyb20gdGhpcyBmdW5jdGlvbi4gKi8KPiAKPiAg ICAgICAgc3RhdGljIHBpZF90Cj4gICAgICAgIHRhcmdldFByb2Nlc3MoaW50IHNvY2tQYWlyWzJd LCBjaGFyICphcmd2W10pCj4gICAgICAgIHsKPiAgICAgICAgICAgIHBpZF90IHRhcmdldFBpZCA9 IGZvcmsoKTsKPiAgICAgICAgICAgIGlmICh0YXJnZXRQaWQgPT0gLTEpCj4gICAgICAgICAgICAg ICAgZXJyRXhpdCgiZm9yayIpOwo+IAo+ICAgICAgICAgICAgaWYgKHRhcmdldFBpZCA+IDApICAg ICAgICAgIC8qIEluIHBhcmVudCwgcmV0dXJuIFBJRCBvZiBjaGlsZCAqLwo+ICAgICAgICAgICAg ICAgIHJldHVybiB0YXJnZXRQaWQ7Cj4gCj4gICAgICAgICAgICAvKiBDaGlsZCBmYWxscyB0aHJv dWdoIHRvIGhlcmUgKi8KPiAKPiAgICAgICAgICAgIHByaW50ZigiVDogUElEID0gJWxkXG4iLCAo bG9uZykgZ2V0cGlkKCkpOwo+IAo+ICAgICAgICAgICAgLyogSW5zdGFsbCBzZWNjb21wIGZpbHRl cihzKSAqLwo+IAo+ICAgICAgICAgICAgaWYgKHByY3RsKFBSX1NFVF9OT19ORVdfUFJJVlMsIDEs IDAsIDAsIDApKQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoInByY3RsIik7Cj4gCj4gICAgICAg ICAgICBpbnQgbm90aWZ5RmQgPSBpbnN0YWxsTm90aWZ5RmlsdGVyKCk7Cj4gCj4gICAgICAgICAg ICAvKiBQYXNzIHRoZSBub3RpZmljYXRpb24gZmlsZSBkZXNjcmlwdG9yIHRvIHRoZSB0cmFjaW5n IHByb2Nlc3Mgb3Zlcgo+ICAgICAgICAgICAgICAgYSBVTklYIGRvbWFpbiBzb2NrZXQgKi8KPiAK PiAgICAgICAgICAgIGlmIChzZW5kZmQoc29ja1BhaXJbMF0sIG5vdGlmeUZkKSA9PSAtMSkKPiAg ICAgICAgICAgICAgICBlcnJFeGl0KCJzZW5kZmQiKTsKPiAKPiAgICAgICAgICAgIC8qIE5vdGlm aWNhdGlvbiBhbmQgc29ja2V0IEZEcyBhcmUgbm8gbG9uZ2VyIG5lZWRlZCBpbiB0YXJnZXQgKi8K PiAKPiAgICAgICAgICAgIGlmIChjbG9zZShub3RpZnlGZCkgPT0gLTEpCj4gICAgICAgICAgICAg ICAgZXJyRXhpdCgiY2xvc2UtdGFyZ2V0LW5vdGlmeS1mZCIpOwo+IAo+ICAgICAgICAgICAgY2xv c2VTb2NrZXRQYWlyKHNvY2tQYWlyKTsKPiAKPiAgICAgICAgICAgIC8qIFBlcmZvcm0gYSBta2Rp cigpIGNhbGwgZm9yIGVhY2ggb2YgdGhlIGNvbW1hbmQtbGluZSBhcmd1bWVudHMgKi8KPiAKPiAg ICAgICAgICAgIGZvciAoY2hhciAqKmFwID0gYXJndjsgKmFwICE9IE5VTEw7IGFwKyspIHsKPiAg ICAgICAgICAgICAgICBwcmludGYoIlxuVDogYWJvdXQgdG8gbWtkaXIoXCIlc1wiKVxuIiwgKmFw KTsKPiAKPiAgICAgICAgICAgICAgICBpbnQgcyA9IG1rZGlyKCphcCwgMDcwMCk7Cj4gICAgICAg ICAgICAgICAgaWYgKHMgPT0gLTEpCj4gICAgICAgICAgICAgICAgICAgIHBlcnJvcigiVDogRVJS T1I6IG1rZGlyKDIpIik7Cj4gICAgICAgICAgICAgICAgZWxzZQo+ICAgICAgICAgICAgICAgICAg ICBwcmludGYoIlQ6IFNVQ0NFU1M6IG1rZGlyKDIpIHJldHVybmVkICVkXG4iLCBzKTsKPiAgICAg ICAgICAgIH0KPiAKPiAgICAgICAgICAgIHByaW50ZigiXG5UOiB0ZXJtaW5hdGluZ1xuIik7Cj4g ICAgICAgICAgICBleGl0KEVYSVRfU1VDQ0VTUyk7Cj4gICAgICAgIH0KPiAKPiAgICAgICAgLyog Q2hlY2sgdGhhdCB0aGUgbm90aWZpY2F0aW9uIElEIHByb3ZpZGVkIGJ5IGEgU0VDQ09NUF9JT0NU TF9OT1RJRl9SRUNWCj4gICAgICAgICAgIG9wZXJhdGlvbiBpcyBzdGlsbCB2YWxpZC4gSXQgd2ls bCBubyBsb25nZXIgYmUgdmFsaWQgaWYgdGhlIHByb2Nlc3MKPiAgICAgICAgICAgaGFzIHRlcm1p bmF0ZWQuIFRoaXMgb3BlcmF0aW9uIGNhbiBiZSB1c2VkIHdoZW4gYWNjZXNzaW5nIC9wcm9jL1BJ RAo+ICAgICAgICAgICBmaWxlcyBpbiB0aGUgdGFyZ2V0IHByb2Nlc3MgaW4gb3JkZXIgdG8gYXZv aWQgVE9DVE9VIHJhY2UgY29uZGl0aW9ucwo+ICAgICAgICAgICB3aGVyZSB0aGUgUElEIHRoYXQg aXMgcmV0dXJuZWQgYnkgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWIHRlcm1pbmF0ZXMKPiAgICAg ICAgICAgYW5kIGlzIHJldXNlZCBieSBhbm90aGVyIHByb2Nlc3MuICovCj4gCj4gICAgICAgIHN0 YXRpYyB2b2lkCj4gICAgICAgIGNoZWNrTm90aWZpY2F0aW9uSWRJc1ZhbGlkKGludCBub3RpZnlG ZCwgdWludDY0X3QgaWQpCj4gICAgICAgIHsKPiAgICAgICAgICAgIGlmIChpb2N0bChub3RpZnlG ZCwgU0VDQ09NUF9JT0NUTF9OT1RJRl9JRF9WQUxJRCwgJmlkKSA9PSAtMSkgewo+ICAgICAgICAg ICAgICAgIGZwcmludGYoc3RkZXJyLCAiXHRTOiBub3RpZmljYXRpb24gSUQgY2hlY2s6ICIKPiAg ICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQgaGFzIHRlcm1pbmF0ZWQhISFcbiIpOwo+IAo+ ICAgICAgICAgICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKCkFuZCBub3cgeW91IGNhbiBkbzoK CgkJZXJyRXhpdCgiXHRTOiBub3RpZmljYXRpb24gSUQgY2hlY2s6ICIKCQkJInRhcmdldCBoYXMg dGVybWluYXRlZCEgaW9jdGwiKTsKCjspCgo+ICAgICAgICAgICAgfQo+ICAgICAgICB9Cj4gCj4g ICAgICAgIC8qIEFjY2VzcyB0aGUgbWVtb3J5IG9mIHRoZSB0YXJnZXQgcHJvY2VzcyBpbiBvcmRl ciB0byBkaXNjb3ZlciB0aGUKPiAgICAgICAgICAgcGF0aG5hbWUgdGhhdCB3YXMgZ2l2ZW4gdG8g bWtkaXIoKSAqLwo+IAo+ICAgICAgICBzdGF0aWMgYm9vbAo+ICAgICAgICBnZXRUYXJnZXRQYXRo bmFtZShzdHJ1Y3Qgc2VjY29tcF9ub3RpZiAqcmVxLCBpbnQgbm90aWZ5RmQsCj4gICAgICAgICAg ICAgICAgICAgICAgICAgIGNoYXIgKnBhdGgsIHNpemVfdCBsZW4pCj4gICAgICAgIHsKPiAgICAg ICAgICAgIGNoYXIgcHJvY01lbVBhdGhbUEFUSF9NQVhdOwo+IAo+ICAgICAgICAgICAgc25wcmlu dGYocHJvY01lbVBhdGgsIHNpemVvZihwcm9jTWVtUGF0aCksICIvcHJvYy8lZC9tZW0iLCByZXEt PnBpZCk7Cj4gCj4gICAgICAgICAgICBpbnQgcHJvY01lbUZkID0gb3Blbihwcm9jTWVtUGF0aCwg T19SRE9OTFkpOwo+ICAgICAgICAgICAgaWYgKHByb2NNZW1GZCA9PSAtMSkKPiAgICAgICAgICAg ICAgICBlcnJFeGl0KCJTdXBlcnZpc29yOiBvcGVuIik7Cj4gCj4gICAgICAgICAgICAvKiBDaGVj ayB0aGF0IHRoZSBwcm9jZXNzIHdob3NlIGluZm8gd2UgYXJlIGFjY2Vzc2luZyBpcyBzdGlsbCBh bGl2ZS4KPiAgICAgICAgICAgICAgIElmIHRoZSBTRUNDT01QX0lPQ1RMX05PVElGX0lEX1ZBTElE IG9wZXJhdGlvbiAocGVyZm9ybWVkCj4gICAgICAgICAgICAgICBpbiBjaGVja05vdGlmaWNhdGlv bklkSXNWYWxpZCgpKSBzdWNjZWVkcywgd2Uga25vdyB0aGF0IHRoZQo+ICAgICAgICAgICAgICAg L3Byb2MvUElEL21lbSBmaWxlIGRlc2NyaXB0b3IgdGhhdCB3ZSBvcGVuZWQgY29ycmVzcG9uZHMg dG8gdGhlCj4gICAgICAgICAgICAgICBwcm9jZXNzIGZvciB3aGljaCB3ZSByZWNlaXZlZCBhIG5v dGlmaWNhdGlvbi4gSWYgdGhhdCBwcm9jZXNzCj4gICAgICAgICAgICAgICBzdWJzZXF1ZW50bHkg dGVybWluYXRlcywgdGhlbiByZWFkKCkgb24gdGhhdCBmaWxlIGRlc2NyaXB0b3IKPiAgICAgICAg ICAgICAgIHdpbGwgcmV0dXJuIDAgKEVPRikuICovCj4gCj4gICAgICAgICAgICBjaGVja05vdGlm aWNhdGlvbklkSXNWYWxpZChub3RpZnlGZCwgcmVxLT5pZCk7Cj4gCj4gICAgICAgICAgICAvKiBS ZWFkIGJ5dGVzIGF0IHRoZSBsb2NhdGlvbiBjb250YWluaW5nIHRoZSBwYXRobmFtZSBhcmd1bWVu dAo+ICAgICAgICAgICAgICAgKGkuZS4sIHRoZSBmaXJzdCBhcmd1bWVudCkgb2YgdGhlIG1rZGly KDIpIGNhbGwgKi8KPiAKPiAgICAgICAgICAgIHNzaXplX3QgbnJlYWQgPSBwcmVhZChwcm9jTWVt RmQsIHBhdGgsIGxlbiwgcmVxLT5kYXRhLmFyZ3NbMF0pOwo+ICAgICAgICAgICAgaWYgKG5yZWFk ID09IC0xKQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoInByZWFkIik7Cj4gCj4gICAgICAgICAg ICBpZiAobnJlYWQgPT0gMCkgewo+ICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiXHRT OiBwcmVhZCgpIG9mIC9wcm9jL1BJRC9tZW0gIgo+ICAgICAgICAgICAgICAgICAgICAgICAgInJl dHVybmVkIDAgKEVPRilcbiIpOwo+ICAgICAgICAgICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsK PiAgICAgICAgICAgIH0KPiAKPiAgICAgICAgICAgIGlmIChjbG9zZShwcm9jTWVtRmQpID09IC0x KQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoImNsb3NlLS9wcm9jL1BJRC9tZW0iKTsKPiAKPiAg ICAgICAgICAgIC8qIFdlIGhhdmUgbm8gZ3VhcmFudGVlcyBhYm91dCB3aGF0IHdhcyBpbiB0aGUg bWVtb3J5IG9mIHRoZSB0YXJnZXQKPiAgICAgICAgICAgICAgIHByb2Nlc3MuIFdlIHRoZXJlZm9y ZSB0cmVhdCB0aGUgYnVmZmVyIHJldHVybmVkIGJ5IHByZWFkKCkgYXMKPiAgICAgICAgICAgICAg IHVudHJ1c3RlZCBpbnB1dC4gVGhlIGJ1ZmZlciBzaG91bGQgYmUgdGVybWluYXRlZCBieSBhIG51 bGwgYnl0ZTsKPiAgICAgICAgICAgICAgIGlmIG5vdCwgdGhlbiB3ZSB3aWxsIHRyaWdnZXIgYW4g ZXJyb3IgZm9yIHRoZSB0YXJnZXQgcHJvY2Vzcy4gKi8KPiAKPiAgICAgICAgICAgIGZvciAoaW50 IGogPSAwOyBqIDwgbnJlYWQ7IGorKykKPiAgICAgICAgICAgICAgICBpZiAocGF0aFtqXSA9PSAn ICcpCgpUaGlzIHJlbmRlcmluZyB0eXBvICgnICcgdnMgJ1wwJykgZW5kcyB1cCBtYW5pZmVzdGlu ZyBiYWRseS4gOykgVGhlIG1hbgpzb3VyY2Ugc2hvd3M6CgogICAgICAgIGlmIChwYXRoW2pdID09 IFwoYXFcMFwoYXEpCgpJIHRoaW5rIHRoaXMgbmVlZHMgdG8gYmUgXFwwID8KCk9yIGl0IGNvdWxk IGFsc28gYmUgYSB0ZXN0ZWQgYXM6CgoJaWYgKHN0cm5sZW4ocGF0aCwgbnJlYWQpIDwgbnJlYWQp Cgo+ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKPiAKPiAgICAgICAgICAgIHJldHVy biBmYWxzZTsKPiAgICAgICAgfQo+IAo+ICAgICAgICAvKiBIYW5kbGUgbm90aWZpY2F0aW9ucyB0 aGF0IGFycml2ZSB2aWEgdGhlIFNFQ0NPTVBfUkVUX1VTRVJfTk9USUYgZmlsZQo+ICAgICAgICAg ICBkZXNjcmlwdG9yLCAnbm90aWZ5RmQnLiAqLwo+IAo+ICAgICAgICBzdGF0aWMgdm9pZAo+ICAg ICAgICBoYW5kbGVOb3RpZmljYXRpb25zKGludCBub3RpZnlGZCkKPiAgICAgICAgewo+ICAgICAg ICAgICAgc3RydWN0IHNlY2NvbXBfbm90aWZfc2l6ZXMgc2l6ZXM7Cj4gICAgICAgICAgICBjaGFy IHBhdGhbUEFUSF9NQVhdOwo+IAo+ICAgICAgICAgICAgLyogRGlzY292ZXIgdGhlIHNpemVzIG9m IHRoZSBzdHJ1Y3R1cmVzIHRoYXQgYXJlIHVzZWQgdG8gcmVjZWl2ZQo+ICAgICAgICAgICAgICAg bm90aWZpY2F0aW9ucyBhbmQgc2VuZCBub3RpZmljYXRpb24gcmVzcG9uc2VzLCBhbmQgYWxsb2Nh dGUKPiAgICAgICAgICAgICAgIGJ1ZmZlcnMgb2YgdGhvc2Ugc2l6ZXMuICovCj4gCj4gICAgICAg ICAgICBpZiAoc2VjY29tcChTRUNDT01QX0dFVF9OT1RJRl9TSVpFUywgMCwgJnNpemVzKSA9PSAt MSkKPiAgICAgICAgICAgICAgICBlcnJFeGl0KCJcdFM6IHNlY2NvbXAtU0VDQ09NUF9HRVRfTk9U SUZfU0laRVMiKTsKPiAKPiAgICAgICAgICAgIHN0cnVjdCBzZWNjb21wX25vdGlmICpyZXEgPSBt YWxsb2Moc2l6ZXMuc2VjY29tcF9ub3RpZik7Cj4gICAgICAgICAgICBpZiAocmVxID09IE5VTEwp Cj4gICAgICAgICAgICAgICAgZXJyRXhpdCgiXHRTOiBtYWxsb2MiKTsKPiAKPiAgICAgICAgICAg IC8qIFdoZW4gYWxsb2NhdGluZyB0aGUgcmVzcG9uc2UgYnVmZmVyLCB3ZSBtdXN0IGFsbG93IGZv ciB0aGUgZmFjdAo+ICAgICAgICAgICAgICAgdGhhdCB0aGUgdXNlci1zcGFjZSBiaW5hcnkgbWF5 IGhhdmUgYmVlbiBidWlsdCB3aXRoIHVzZXItc3BhY2UKPiAgICAgICAgICAgICAgIGhlYWRlcnMg d2hlcmUgJ3N0cnVjdCBzZWNjb21wX25vdGlmX3Jlc3AnIGlzIGJpZ2dlciB0aGFuIHRoZQo+ICAg ICAgICAgICAgICAgcmVzcG9uc2UgYnVmZmVyIGV4cGVjdGVkIGJ5IHRoZSAob2xkZXIpIGtlcm5l bC4gVGhlcmVmb3JlLCB3ZQo+ICAgICAgICAgICAgICAgYWxsb2NhdGUgYSBidWZmZXIgdGhhdCBp cyB0aGUgbWF4aW11bSBvZiB0aGUgdHdvIHNpemVzLiBUaGlzCj4gICAgICAgICAgICAgICBlbnN1 cmVzIHRoYXQgaWYgdGhlIHN1cGVydmlzb3IgcGxhY2VzIGJ5dGVzIGludG8gdGhlIHJlc3BvbnNl Cj4gICAgICAgICAgICAgICBzdHJ1Y3R1cmUgdGhhdCBhcmUgcGFzdCB0aGUgcmVzcG9uc2Ugc2l6 ZSB0aGF0IHRoZSBrZXJuZWwgZXhwZWN0cywKPiAgICAgICAgICAgICAgIHRoZW4gdGhlIHN1cGVy dmlzb3IgaXMgbm90IHRvdWNoaW5nIGFuIGludmFsaWQgbWVtb3J5IGxvY2F0aW9uLiAqLwo+IAo+ ICAgICAgICAgICAgc2l6ZV90IHJlc3Bfc2l6ZSA9IHNpemVzLnNlY2NvbXBfbm90aWZfcmVzcDsK PiAgICAgICAgICAgIGlmIChzaXplb2Yoc3RydWN0IHNlY2NvbXBfbm90aWZfcmVzcCkgPiByZXNw X3NpemUpCj4gICAgICAgICAgICAgICAgcmVzcF9zaXplID0gc2l6ZW9mKHN0cnVjdCBzZWNjb21w X25vdGlmX3Jlc3ApOwo+IAo+ICAgICAgICAgICAgc3RydWN0IHNlY2NvbXBfbm90aWZfcmVzcCAq cmVzcCA9IG1hbGxvYyhyZXNwX3NpemUpOwo+ICAgICAgICAgICAgaWYgKHJlc3AgPT0gTlVMTCkK PiAgICAgICAgICAgICAgICBlcnJFeGl0KCJcdFM6IG1hbGxvYyIpOwo+IAo+ICAgICAgICAgICAg LyogTG9vcCBoYW5kbGluZyBub3RpZmljYXRpb25zICovCj4gCj4gICAgICAgICAgICBmb3IgKDs7 KSB7Cj4gICAgICAgICAgICAgICAgLyogV2FpdCBmb3IgbmV4dCBub3RpZmljYXRpb24sIHJldHVy bmluZyBpbmZvIGluICcqcmVxJyAqLwo+IAo+ICAgICAgICAgICAgICAgIG1lbXNldChyZXEsIDAs IHNpemVzLnNlY2NvbXBfbm90aWYpOwo+ICAgICAgICAgICAgICAgIGlmIChpb2N0bChub3RpZnlG ZCwgU0VDQ09NUF9JT0NUTF9OT1RJRl9SRUNWLCByZXEpID09IC0xKSB7Cj4gICAgICAgICAgICAg ICAgICAgIGlmIChlcnJubyA9PSBFSU5UUikKPiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRp bnVlOwo+ICAgICAgICAgICAgICAgICAgICBlcnJFeGl0KCJTdXBlcnZpc29yOiBpb2N0bC1TRUND T01QX0lPQ1RMX05PVElGX1JFQ1YiKTsKPiAgICAgICAgICAgICAgICB9Cj4gCj4gICAgICAgICAg ICAgICAgcHJpbnRmKCJcdFM6IGdvdCBub3RpZmljYXRpb24gKElEICUjbGx4KSBmb3IgUElEICVk XG4iLAo+ICAgICAgICAgICAgICAgICAgICAgICAgcmVxLT5pZCwgcmVxLT5waWQpOwo+IAo+ICAg ICAgICAgICAgICAgIC8qIFRoZSBvbmx5IHN5c3RlbSBjYWxsIHRoYXQgY2FuIGdlbmVyYXRlIGEg bm90aWZpY2F0aW9uIGV2ZW50Cj4gICAgICAgICAgICAgICAgICAgaXMgbWtkaXIoMikuIE5ldmVy dGhlbGVzcywgd2UgY2hlY2sgdGhhdCB0aGUgbm90aWZpZWQgc3lzdGVtCj4gICAgICAgICAgICAg ICAgICAgY2FsbCBpcyBpbmRlZWQgbWtkaXIoKSBhcyBraW5kIG9mIGZ1dHVyZS1wcm9vZmluZyBv ZiB0aGlzCj4gICAgICAgICAgICAgICAgICAgY29kZSBpbiBjYXNlIHRoZSBzZWNjb21wIGZpbHRl ciBpcyBsYXRlciBtb2RpZmllZCB0bwo+ICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlIG5vdGlm aWNhdGlvbnMgZm9yIG90aGVyIHN5c3RlbSBjYWxscy4gKi8KPiAKPiAgICAgICAgICAgICAgICBp ZiAocmVxLT5kYXRhLm5yICE9IF9fTlJfbWtkaXIpIHsKPiAgICAgICAgICAgICAgICAgICAgcHJp bnRmKCJcdFM6IG5vdGlmaWNhdGlvbiBjb250YWluZWQgdW5leHBlY3RlZCAiCj4gICAgICAgICAg ICAgICAgICAgICAgICAgICAgInN5c3RlbSBjYWxsIG51bWJlcjsgYnllISEhXG4iKTsKPiAgICAg ICAgICAgICAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwo+ICAgICAgICAgICAgICAgIH0KPiAK PiAgICAgICAgICAgICAgICBib29sIHBhdGhPSyA9IGdldFRhcmdldFBhdGhuYW1lKHJlcSwgbm90 aWZ5RmQsIHBhdGgsCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBzaXplb2YocGF0aCkpOwo+IAo+ICAgICAgICAgICAgICAgIC8qIFByZXBvcHVsYXRlIHNv bWUgZmllbGRzIG9mIHRoZSByZXNwb25zZSAqLwo+IAo+ICAgICAgICAgICAgICAgIHJlc3AtPmlk ID0gcmVxLT5pZDsgICAgIC8qIFJlc3BvbnNlIGluY2x1ZGVzIG5vdGlmaWNhdGlvbiBJRCAqLwo+ ICAgICAgICAgICAgICAgIHJlc3AtPmZsYWdzID0gMDsKPiAgICAgICAgICAgICAgICByZXNwLT52 YWwgPSAwOwo+IAo+ICAgICAgICAgICAgICAgIC8qIElmIHRoZSB0YXJnZXQgcGF0aG5hbWUgd2Fz IG5vdCB2YWxpZCwgdHJpZ2dlciBhbiBFSU5WQUwgZXJyb3I7Cj4gICAgICAgICAgICAgICAgICAg aWYgdGhlIGRpcmVjdG9yeSBpcyBpbiAvdG1wLCB0aGVuIGNyZWF0ZSBpdCBvbiBiZWhhbGYgb2Yg dGhlCj4gICAgICAgICAgICAgICAgICAgc3VwZXJ2aXNvcjsgaWYgdGhlIHBhdGhuYW1lIHN0YXJ0 cyB3aXRoICcuJywgdGVsbCB0aGUga2VybmVsCj4gICAgICAgICAgICAgICAgICAgdG8gbGV0IHRo ZSB0YXJnZXQgcHJvY2VzcyBleGVjdXRlIHRoZSBta2RpcigpOyBvdGhlcndpc2UsIGdpdmUKPiAg ICAgICAgICAgICAgICAgICBhbiBlcnJvciBmb3IgYSBkaXJlY3RvcnkgcGF0aG5hbWUgaW4gYW55 IG90aGVyIGxvY2F0aW9uLiAqLwo+IAo+ICAgICAgICAgICAgICAgIGlmICghcGF0aE9LKSB7Cj4g ICAgICAgICAgICAgICAgICAgIHJlc3AtPmVycm9yID0gLUVJTlZBTDsKPiAgICAgICAgICAgICAg ICAgICAgcHJpbnRmKCJcdFM6IHNwb29maW5nIGVycm9yIGZvciBpbnZhbGlkIHBhdGhuYW1lICgl cylcbiIsCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoLXJlc3AtPmVycm9y KSk7Cj4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJuY21wKHBhdGgsICIvdG1wLyIsIHN0 cmxlbigiL3RtcC8iKSkgPT0gMCkgewo+ICAgICAgICAgICAgICAgICAgICBwcmludGYoIlx0Uzog ZXhlY3V0aW5nOiBta2RpcihcIiVzXCIsICUjbGxvKVxuIiwKPiAgICAgICAgICAgICAgICAgICAg ICAgICAgICBwYXRoLCByZXEtPmRhdGEuYXJnc1sxXSk7Cj4gCj4gICAgICAgICAgICAgICAgICAg IGlmIChta2RpcihwYXRoLCByZXEtPmRhdGEuYXJnc1sxXSkgPT0gMCkgewo+ICAgICAgICAgICAg ICAgICAgICAgICAgcmVzcC0+ZXJyb3IgPSAwOyAgICAgICAgICAgIC8qICJTdWNjZXNzIiAqLwo+ ICAgICAgICAgICAgICAgICAgICAgICAgcmVzcC0+dmFsID0gc3RybGVuKHBhdGgpOyAgIC8qIFVz ZWQgYXMgcmV0dXJuIHZhbHVlIG9mCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgbWtkaXIoKSBpbiB0YXJnZXQgKi8KPiAgICAgICAgICAgICAg ICAgICAgICAgIHByaW50ZigiXHRTOiBzdWNjZXNzISBzcG9vZmVkIHJldHVybiA9ICVsbGRcbiIs Cj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3AtPnZhbCk7Cj4gICAgICAgICAg ICAgICAgICAgIH0gZWxzZSB7Cj4gCj4gICAgICAgICAgICAgICAgICAgICAgICAvKiBJZiBta2Rp cigpIGZhaWxlZCBpbiB0aGUgc3VwZXJ2aXNvciwgcGFzcyB0aGUgZXJyb3IKPiAgICAgICAgICAg ICAgICAgICAgICAgICAgIGJhY2sgdG8gdGhlIHRhcmdldCAqLwo+IAo+ICAgICAgICAgICAgICAg ICAgICAgICAgcmVzcC0+ZXJyb3IgPSAtZXJybm87Cj4gICAgICAgICAgICAgICAgICAgICAgICBw cmludGYoIlx0UzogZmFpbHVyZSEgKGVycm5vID0gJWQ7ICVzKVxuIiwgZXJybm8sCj4gICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVycm9yKGVycm5vKSk7Cj4gICAgICAgICAgICAg ICAgICAgIH0KPiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cm5jbXAocGF0aCwgIi4vIiwg c3RybGVuKCIuLyIpKSA9PSAwKSB7Cj4gICAgICAgICAgICAgICAgICAgIHJlc3AtPmVycm9yID0g cmVzcC0+dmFsID0gMDsKPiAgICAgICAgICAgICAgICAgICAgcmVzcC0+ZmxhZ3MgPSBTRUNDT01Q X1VTRVJfTk9USUZfRkxBR19DT05USU5VRTsKPiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJc dFM6IHRhcmdldCBjYW4gZXhlY3V0ZSBzeXN0ZW0gY2FsbFxuIik7Cj4gICAgICAgICAgICAgICAg fSBlbHNlIHsKPiAgICAgICAgICAgICAgICAgICAgcmVzcC0+ZXJyb3IgPSAtRU9QTk9UU1VQUDsK PiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJcdFM6IHNwb29maW5nIGVycm9yIHJlc3BvbnNl ICglcylcbiIsCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoLXJlc3AtPmVy cm9yKSk7Cj4gICAgICAgICAgICAgICAgfQo+IAo+ICAgICAgICAgICAgICAgIC8qIFNlbmQgYSBy ZXNwb25zZSB0byB0aGUgbm90aWZpY2F0aW9uICovCj4gCj4gICAgICAgICAgICAgICAgcHJpbnRm KCJcdFM6IHNlbmRpbmcgcmVzcG9uc2UgIgo+ICAgICAgICAgICAgICAgICAgICAgICAgIihmbGFn cyA9ICUjeDsgdmFsID0gJWxsZDsgZXJyb3IgPSAlZClcbiIsCj4gICAgICAgICAgICAgICAgICAg ICAgICByZXNwLT5mbGFncywgcmVzcC0+dmFsLCByZXNwLT5lcnJvcik7Cj4gCj4gICAgICAgICAg ICAgICAgaWYgKGlvY3RsKG5vdGlmeUZkLCBTRUNDT01QX0lPQ1RMX05PVElGX1NFTkQsIHJlc3Ap ID09IC0xKSB7Cj4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJubyA9PSBFTk9FTlQpCj4gICAg ICAgICAgICAgICAgICAgICAgICBwcmludGYoIlx0UzogcmVzcG9uc2UgZmFpbGVkIHdpdGggRU5P RU5UOyAiCj4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwZXJoYXBzIHRhcmdldCBw cm9jZXNzJ3Mgc3lzY2FsbCB3YXMgIgo+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAi aW50ZXJydXB0ZWQgYnkgYSBzaWduYWw/XG4iKTsKPiAgICAgICAgICAgICAgICAgICAgZWxzZQo+ ICAgICAgICAgICAgICAgICAgICAgICAgcGVycm9yKCJpb2N0bC1TRUNDT01QX0lPQ1RMX05PVElG X1NFTkQiKTsKPiAgICAgICAgICAgICAgICB9Cj4gCj4gICAgICAgICAgICAgICAgLyogSWYgdGhl IHBhdGhuYW1lIGlzIGp1c3QgIi9ieWUiLCB0aGVuIHRoZSBzdXBlcnZpc29yCj4gICAgICAgICAg ICAgICAgICAgdGVybWluYXRlcy4gVGhpcyBhbGxvd3MgdXMgdG8gc2VlIHdoYXQgaGFwcGVucyBp ZiB0aGUKPiAgICAgICAgICAgICAgICAgICB0YXJnZXQgcHJvY2VzcyBtYWtlcyBmdXJ0aGVyIGNh bGxzIHRvIG1rZGlyKDIpLiAqLwo+IAo+ICAgICAgICAgICAgICAgIGlmIChzdHJjbXAocGF0aCwg Ii9ieWUiKSA9PSAwKSB7Cj4gICAgICAgICAgICAgICAgICAgIHByaW50ZigiXHRTOiB0ZXJtaW5h dGluZyAqKioqKioqKioqXG4iKTsKPiAgICAgICAgICAgICAgICAgICAgZXhpdChFWElUX0ZBSUxV UkUpOwo+ICAgICAgICAgICAgICAgIH0KPiAgICAgICAgICAgIH0KPiAgICAgICAgfQo+IAo+ICAg ICAgICAvKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3VwZXJ2aXNvciBwcm9jZXNzOgo+IAo+ICAg ICAgICAgICAoMSkgb2J0YWlucyB0aGUgbm90aWZpY2F0aW9uIGZpbGUgZGVzY3JpcHRvciBmcm9t ICdzb2NrUGFpclsxXScKPiAgICAgICAgICAgKDIpIGhhbmRsZXMgbm90aWZpY2F0aW9ucyB0aGF0 IGFycml2ZSBvbiB0aGF0IGZpbGUgZGVzY3JpcHRvci4gKi8KPiAKPiAgICAgICAgc3RhdGljIHZv aWQKPiAgICAgICAgc3VwZXJ2aXNvcihpbnQgc29ja1BhaXJbMl0pCj4gICAgICAgIHsKPiAgICAg ICAgICAgIGludCBub3RpZnlGZCA9IHJlY3ZmZChzb2NrUGFpclsxXSk7Cj4gICAgICAgICAgICBp ZiAobm90aWZ5RmQgPT0gLTEpCj4gICAgICAgICAgICAgICAgZXJyRXhpdCgicmVjdmZkIik7Cj4g Cj4gICAgICAgICAgICBjbG9zZVNvY2tldFBhaXIoc29ja1BhaXIpOyAgLyogV2Ugbm8gbG9uZ2Vy IG5lZWQgdGhlIHNvY2tldCBwYWlyICovCj4gCj4gICAgICAgICAgICBoYW5kbGVOb3RpZmljYXRp b25zKG5vdGlmeUZkKTsKPiAgICAgICAgfQo+IAo+ICAgICAgICBpbnQKPiAgICAgICAgbWFpbihp bnQgYXJnYywgY2hhciAqYXJndltdKQo+ICAgICAgICB7Cj4gICAgICAgICAgICBpbnQgc29ja1Bh aXJbMl07Cj4gCj4gICAgICAgICAgICBzZXRidWYoc3Rkb3V0LCBOVUxMKTsKPiAKPiAgICAgICAg ICAgIGlmIChhcmdjIDwgMikgewo+ICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiQXQg bGVhc3Qgb25lIHBhdGhuYW1lIGFyZ3VtZW50IGlzIHJlcXVpcmVkXG4iKTsKPiAgICAgICAgICAg ICAgICBleGl0KEVYSVRfRkFJTFVSRSk7Cj4gICAgICAgICAgICB9Cj4gCj4gICAgICAgICAgICAv KiBDcmVhdGUgYSBVTklYIGRvbWFpbiBzb2NrZXQgdGhhdCBpcyB1c2VkIHRvIHBhc3MgdGhlIHNl Y2NvbXAKPiAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbiBmaWxlIGRlc2NyaXB0b3IgZnJvbSB0 aGUgdGFyZ2V0IHByb2Nlc3MgdG8gdGhlCj4gICAgICAgICAgICAgICBzdXBlcnZpc29yIHByb2Nl c3MuICovCj4gCj4gICAgICAgICAgICBpZiAoc29ja2V0cGFpcihBRl9VTklYLCBTT0NLX1NUUkVB TSwgMCwgc29ja1BhaXIpID09IC0xKQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoInNvY2tldHBh aXIiKTsKPiAKPiAgICAgICAgICAgIC8qIENyZWF0ZSBhIGNoaWxkIHByb2Nlc3MtLXRoZSAidGFy Z2V0Ii0tdGhhdCBpbnN0YWxscyBzZWNjb21wCj4gICAgICAgICAgICAgICBmaWx0ZXJpbmcuIFRo ZSB0YXJnZXQgcHJvY2VzcyB3cml0ZXMgdGhlIHNlY2NvbXAgbm90aWZpY2F0aW9uCj4gICAgICAg ICAgICAgICBmaWxlIGRlc2NyaXB0b3Igb250byAnc29ja1BhaXJbMF0nIGFuZCB0aGVuIGNhbGxz IG1rZGlyKDIpIGZvcgo+ICAgICAgICAgICAgICAgZWFjaCBkaXJlY3RvcnkgaW4gdGhlIGNvbW1h bmQtbGluZSBhcmd1bWVudHMuICovCj4gCj4gICAgICAgICAgICAodm9pZCkgdGFyZ2V0UHJvY2Vz cyhzb2NrUGFpciwgJmFyZ3Zbb3B0aW5kXSk7Cj4gCj4gICAgICAgICAgICAvKiBDYXRjaCBTSUdD SExEIHdoZW4gdGhlIHRhcmdldCB0ZXJtaW5hdGVzLCBzbyB0aGF0IHRoZQo+ICAgICAgICAgICAg ICAgc3VwZXJ2aXNvciBjYW4gYWxzbyB0ZXJtaW5hdGUuICovCj4gCj4gICAgICAgICAgICBzdHJ1 Y3Qgc2lnYWN0aW9uIHNhOwo+ICAgICAgICAgICAgc2Euc2FfaGFuZGxlciA9IHNpZ2NobGRIYW5k bGVyOwo+ICAgICAgICAgICAgc2Euc2FfZmxhZ3MgPSAwOwo+ICAgICAgICAgICAgc2lnZW1wdHlz ZXQoJnNhLnNhX21hc2spOwo+ICAgICAgICAgICAgaWYgKHNpZ2FjdGlvbihTSUdDSExELCAmc2Es IE5VTEwpID09IC0xKQo+ICAgICAgICAgICAgICAgIGVyckV4aXQoInNpZ2FjdGlvbiIpOwo+IAo+ ICAgICAgICAgICAgc3VwZXJ2aXNvcihzb2NrUGFpcik7Cj4gCj4gICAgICAgICAgICBleGl0KEVY SVRfU1VDQ0VTUyk7Cj4gICAgICAgIH0KPiAKPiBTRUUgQUxTTwo+ICAgICAgICBpb2N0bCgyKSwg c2VjY29tcCgyKQo+IAo+ICAgICAgICBBIGZ1cnRoZXIgZXhhbXBsZSBwcm9ncmFtIGNhbiBiZSBm b3VuZCBpbiB0aGUga2VybmVsIHNvdXJjZSBmaWxlCj4gICAgICAgIHNhbXBsZXMvc2VjY29tcC91 c2VyLXRyYXAuYy4KPiAKPiBMaW51eCAgICAgICAgICAgICAgICAgICAgICAgICAgIDIwMjAtMTAt MDEgICAgICAgICAgU0VDQ09NUF9VU0VSX05PVElGKDIpCgpUaGFuayB5b3Ugc28gbXVjaCBmb3Ig dGhpcyBkb2N1bWVudGF0aW9uIGFuZCBleGFtcGxlISA6KQoKLUtlZXMKClsxXSBodHRwczovL2dp dC5rZXJuZWwub3JnL2xpbnVzL2RmZTcxOWZlZjAzZDc1MmYxNjgyZmE4YWVkZGYzMGJhNTAxYzg1 NTUKWzJdIGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2xrbWwvQ0FHNDhlejNrcEVETzF4X0hmdk9N MlI5TTc4QWNoOU9fNCtQanMtdkxMZnF2WkwrMTNBQG1haWwuZ21haWwuY29tLwpbM10gaHR0cHM6 Ly9sb3JlLmtlcm5lbC5vcmcvbGttbC9DQUdYdTVqS3ppZj12cDZnbjVadHJUeC1KVE4zNjdxRnBo b2JudDlzPWF3YmFhZndvVXdAbWFpbC5nbWFpbC5jb20vCgotLSAKS2VlcyBDb29rCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkNvbnRhaW5lcnMgbWFpbGlu ZyBsaXN0CkNvbnRhaW5lcnNAbGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0 cy5saW51eGZvdW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vY29udGFpbmVycw==