* + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree
@ 2012-03-06 23:13 akpm
[not found] ` <20120307162630.GG20558@moon>
0 siblings, 1 reply; 5+ messages in thread
From: akpm @ 2012-03-06 23:13 UTC (permalink / raw)
To: mm-commits
Cc: oleg, adobriyan, ebiederm, gorcunov, keescook, kosaki.motohiro,
matthltc, tj, xemul
The patch titled
Subject: mm/exec: rename mm->exe_file to mm->exe_path
has been added to the -mm tree. Its filename is
mm-exec-rename-mm-exe_file-to-mm-exe_path.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/SubmitChecklist when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: Oleg Nesterov <oleg@redhat.com>
Subject: mm/exec: rename mm->exe_file to mm->exe_path
Rename mm->exe_file to mm->exe_path. We only need this member to get the
path - an additional reference to bprm->file makes no sense.
The patch doesn't rename added_exe_file_vma/removed_exe_file_vma and
mm->num_exe_file_vmas, and perhaps we can remove them later.
Also remove the stale comment in include/linux/mm.h.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Matt Helsley <matthltc@us.ibm.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Tejun Heo <tj@kernel.org
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/exec.c | 20 +++++++++---------
fs/proc/base.c | 17 +++++++--------
include/linux/mm.h | 5 +---
include/linux/mm_types.h | 2 -
kernel/fork.c | 41 ++++++++++++++++++-------------------
5 files changed, 42 insertions(+), 43 deletions(-)
diff -puN fs/exec.c~mm-exec-rename-mm-exe_file-to-mm-exe_path fs/exec.c
--- a/fs/exec.c~mm-exec-rename-mm-exe_file-to-mm-exe_path
+++ a/fs/exec.c
@@ -1100,7 +1100,7 @@ int flush_old_exec(struct linux_binprm *
if (retval)
goto out;
- set_mm_exe_file(bprm->mm, bprm->file);
+ set_mm_exe_path(bprm->mm, &bprm->file->f_path);
filename_to_taskname(bprm->tcomm, bprm->filename, sizeof(bprm->tcomm));
/*
@@ -1674,14 +1674,14 @@ static void cn_escape(char *str)
*str = '!';
}
-static int cn_print_exe_file(struct core_name *cn)
+static int cn_print_exe_path(struct core_name *cn)
{
- struct file *exe_file;
+ struct path *exe_path;
char *pathbuf, *path;
int ret;
- exe_file = get_mm_exe_file(current->mm);
- if (!exe_file) {
+ exe_path = get_mm_exe_path(current->mm);
+ if (!exe_path) {
char *commstart = cn->corename + cn->used;
ret = cn_printf(cn, "%s (path unknown)", current->comm);
cn_escape(commstart);
@@ -1691,10 +1691,10 @@ static int cn_print_exe_file(struct core
pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY);
if (!pathbuf) {
ret = -ENOMEM;
- goto put_exe_file;
+ goto put_exe_path;
}
- path = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
+ path = d_path(exe_path, pathbuf, PATH_MAX);
if (IS_ERR(path)) {
ret = PTR_ERR(path);
goto free_buf;
@@ -1706,8 +1706,8 @@ static int cn_print_exe_file(struct core
free_buf:
kfree(pathbuf);
-put_exe_file:
- fput(exe_file);
+put_exe_path:
+ path_put(exe_path);
return ret;
}
@@ -1789,7 +1789,7 @@ static int format_corename(struct core_n
break;
}
case 'E':
- err = cn_print_exe_file(cn);
+ err = cn_print_exe_path(cn);
break;
/* core limit size */
case 'c':
diff -puN fs/proc/base.c~mm-exec-rename-mm-exe_file-to-mm-exe_path fs/proc/base.c
--- a/fs/proc/base.c~mm-exec-rename-mm-exe_file-to-mm-exe_path
+++ a/fs/proc/base.c
@@ -1400,11 +1400,11 @@ static const struct file_operations proc
.release = single_release,
};
-static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
+static int proc_exe_link(struct dentry *dentry, struct path *path)
{
struct task_struct *task;
struct mm_struct *mm;
- struct file *exe_file;
+ struct path *exe_path;
task = get_proc_task(dentry->d_inode);
if (!task)
@@ -1413,15 +1413,14 @@ static int proc_exe_link(struct dentry *
put_task_struct(task);
if (!mm)
return -ENOENT;
- exe_file = get_mm_exe_file(mm);
+ exe_path = get_mm_exe_path(mm);
mmput(mm);
- if (exe_file) {
- *exe_path = exe_file->f_path;
- path_get(&exe_file->f_path);
- fput(exe_file);
- return 0;
- } else
+
+ if (!exe_path)
return -ENOENT;
+
+ *path = *exe_path;
+ return 0;
}
static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
diff -puN include/linux/mm.h~mm-exec-rename-mm-exe_file-to-mm-exe_path include/linux/mm.h
--- a/include/linux/mm.h~mm-exec-rename-mm-exe_file-to-mm-exe_path
+++ a/include/linux/mm.h
@@ -1380,11 +1380,10 @@ extern void exit_mmap(struct mm_struct *
extern int mm_take_all_locks(struct mm_struct *mm);
extern void mm_drop_all_locks(struct mm_struct *mm);
-/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
extern void added_exe_file_vma(struct mm_struct *mm);
extern void removed_exe_file_vma(struct mm_struct *mm);
-extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
-extern struct file *get_mm_exe_file(struct mm_struct *mm);
+extern void set_mm_exe_path(struct mm_struct *mm, struct path *exe_path);
+extern struct path *get_mm_exe_path(struct mm_struct *mm);
extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
extern int install_special_mapping(struct mm_struct *mm,
diff -puN include/linux/mm_types.h~mm-exec-rename-mm-exe_file-to-mm-exe_path include/linux/mm_types.h
--- a/include/linux/mm_types.h~mm-exec-rename-mm-exe_file-to-mm-exe_path
+++ a/include/linux/mm_types.h
@@ -377,7 +377,7 @@ struct mm_struct {
#endif
/* store ref to file /proc/<pid>/exe symlink points to */
- struct file *exe_file;
+ struct path *exe_path;
unsigned long num_exe_file_vmas;
#ifdef CONFIG_MMU_NOTIFIER
struct mmu_notifier_mm *mmu_notifier_mm;
diff -puN kernel/fork.c~mm-exec-rename-mm-exe_file-to-mm-exe_path kernel/fork.c
--- a/kernel/fork.c~mm-exec-rename-mm-exe_file-to-mm-exe_path
+++ a/kernel/fork.c
@@ -574,7 +574,7 @@ void mmput(struct mm_struct *mm)
ksm_exit(mm);
khugepaged_exit(mm); /* must run before exit_mmap */
exit_mmap(mm);
- set_mm_exe_file(mm, NULL);
+ set_mm_exe_path(mm, NULL);
if (!list_empty(&mm->mmlist)) {
spin_lock(&mmlist_lock);
list_del(&mm->mmlist);
@@ -601,42 +601,43 @@ void added_exe_file_vma(struct mm_struct
void removed_exe_file_vma(struct mm_struct *mm)
{
mm->num_exe_file_vmas--;
- if ((mm->num_exe_file_vmas == 0) && mm->exe_file) {
- fput(mm->exe_file);
- mm->exe_file = NULL;
+ if ((mm->num_exe_file_vmas == 0) && mm->exe_path) {
+ path_put(mm->exe_path);
+ mm->exe_path = NULL;
}
}
-void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
+void set_mm_exe_path(struct mm_struct *mm, struct path *exe_path)
{
- if (new_exe_file)
- get_file(new_exe_file);
- if (mm->exe_file)
- fput(mm->exe_file);
- mm->exe_file = new_exe_file;
+ if (mm->exe_path)
+ path_put(mm->exe_path);
+ mm->exe_path = exe_path;
+ if (mm->exe_path)
+ path_get(mm->exe_path);
mm->num_exe_file_vmas = 0;
}
-struct file *get_mm_exe_file(struct mm_struct *mm)
+struct path *get_mm_exe_path(struct mm_struct *mm)
{
- struct file *exe_file;
+ struct path *exe_path;
/* We need mmap_sem to protect against races with removal of
* VM_EXECUTABLE vmas */
down_read(&mm->mmap_sem);
- exe_file = mm->exe_file;
- if (exe_file)
- get_file(exe_file);
+ exe_path = mm->exe_path;
+ if (exe_path)
+ path_get(exe_path);
up_read(&mm->mmap_sem);
- return exe_file;
+
+ return exe_path;
}
-static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
+static void dup_mm_exe_path(struct mm_struct *oldmm, struct mm_struct *newmm)
{
- /* It's safe to write the exe_file pointer without exe_file_lock because
+ /* It's safe to write the exe_path pointer without mmap_sem because
* this is called during fork when the task is not yet in /proc */
- newmm->exe_file = get_mm_exe_file(oldmm);
+ newmm->exe_path = get_mm_exe_path(oldmm);
}
/**
@@ -811,7 +812,7 @@ struct mm_struct *dup_mm(struct task_str
if (init_new_context(tsk, mm))
goto fail_nocontext;
- dup_mm_exe_file(oldmm, mm);
+ dup_mm_exe_path(oldmm, mm);
err = dup_mmap(mm, oldmm);
if (err)
_
Subject: Subject: mm/exec: rename mm->exe_file to mm->exe_path
Patches currently in -mm which might be from oleg@redhat.com are
origin.patch
linux-next.patch
arm-use-set_current_blocked-and-block_sigmask.patch
avr32-dont-mask-signals-in-the-error-path.patch
avr32-use-set_current_blocked-in-handle_signal-sys_rt_sigreturn.patch
avr32-use-block_sigmask.patch
powerpc-use-set_current_blocked-and-block_sigmask.patch
ia64-use-set_current_blocked-and-block_sigmask.patch
microblaze-dont-reimplement-force_sigsegv.patch
microblaze-no-need-to-reset-handler-if-sa_oneshot.patch
microblaze-fix-signal-masking.patch
microblaze-use-set_current_blocked-and-block_sigmask.patch
mips-use-set_current_blocked-and-block_sigmask.patch
score-dont-mask-signals-if-we-fail-to-setup-signal-stack.patch
score-use-set_current_blocked-and-block_sigmask.patch
unicore32-use-block_sigmask.patch
blackfin-use-set_current_blocked-and-block_sigmask.patch
parisc-use-set_current_blocked-and-block_sigmask.patch
xtensa-dont-reimplement-force_sigsegv.patch
xtensa-no-need-to-reset-handler-if-sa_oneshot.patch
xtensa-dont-mask-signals-if-we-fail-to-setup-signal-stack.patch
xtensa-use-set_current_blocked-and-block_sigmask.patch
sparc-use-block_sigmask.patch
procfs-mark-thread-stack-correctly-in-proc-pid-maps.patch
procfs-mark-thread-stack-correctly-in-proc-pid-maps-fix-task_nommu-build-regression-in-linux-next.patch
procfs-mark-thread-stack-correctly-in-proc-pid-fix-rcu-locking-in-vm_is_stack.patch
mm-exec-rename-mm-exe_file-to-mm-exe_path.patch
frv-use-set_current_blocked-and-block_sigmask.patch
sh-no-need-to-reset-handler-if-sa_oneshot.patch
sh-use-set_current_blocked-and-block_sigmask.patch
h8300-use-set_current_blocked-and-block_sigmask.patch
alpha-use-set_current_blocked-and-block_sigmask.patch
m32r-use-set_current_blocked-and-block_sigmask.patch
m68k-use-set_current_blocked-and-block_sigmask.patch
mn10300-use-set_current_blocked-and-block_sigmask.patch
c6x-use-set_current_blocked-and-block_sigmask.patch
cris-use-set_current_blocked-and-block_sigmask.patch
um-dont-restore-current-blocked-on-error.patch
um-use-set_current_blocked-and-block_sigmask.patch
prctl-add-pr_setget_child_subreaper-to-allow-simple-process-supervision.patch
prctl-add-pr_setget_child_subreaper-to-allow-simple-process-supervision-fix.patch
prctl-add-pr_setget_child_subreaper-to-allow-simple-process-supervision-fix-fix.patch
kernel-exitc-if-init-dies-log-a-signal-which-killed-it-if-any.patch
kernel-exitc-if-init-dies-log-a-signal-which-killed-it-if-any-fix.patch
powerpc-eeh-remove-eeh_event_handler-daemonize.patch
ptrace-the-killed-tracee-should-not-enter-the-syscall.patch
ptrace-dont-send-sigtrap-on-exec-if-seized.patch
ptrace-dont-modify-flags-on-ptrace_setoptions-failure.patch
ptrace-simplify-ptrace_foo-constants-and-ptrace_setoptions-code.patch
ptrace-make-ptrace_seize-set-ptrace-options-specified-in-data-parameter.patch
ptrace-renumber-ptrace_event_stop-so-that-future-new-options-and-events-can-match.patch
ptrace-remove-ptrace_seize_devel-bit.patch
tile-use-set_current_blocked-and-block_sigmask.patch
hexagon-use-set_current_blocked-and-block_sigmask.patch
signal-give-send_sig_forced-more-power-to-beat-signal_unkillable.patch
signal-cosmetic-s-from_ancestor_ns-force-in-prepare_signal-paths.patch
signal-oom_kill_task-use-send_sig_forced-instead-of-force_sig.patch
signal-zap_pid_ns_processes-s-send_sig_noinfo-send_sig_forced.patch
usermodehelper-use-umh_wait_proc-consistently.patch
usermodehelper-introduce-umh_completesub_info.patch
usermodehelper-implement-umh_killable.patch
usermodehelper-kill-umh_wait-renumber-umh_-constants.patch
usermodehelper-____call_usermodehelper-doesnt-need-do_exit.patch
kmod-introduce-call_modprobe-helper.patch
kmod-make-__request_module-killable.patch
pidns-add-reboot_pid_ns-to-handle-the-reboot-syscall.patch
pidns-add-reboot_pid_ns-to-handle-the-reboot-syscall-fix.patch
sysctl-make-kernelns_last_pid-control-being-checkpoint_restore-dependent.patch
fs-proc-introduce-proc-pid-task-tid-children-entry-v9.patch
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree
[not found] ` <20120307162630.GG20558@moon>
@ 2012-03-07 17:41 ` Oleg Nesterov
2012-03-07 19:34 ` Cyrill Gorcunov
0 siblings, 1 reply; 5+ messages in thread
From: Oleg Nesterov @ 2012-03-07 17:41 UTC (permalink / raw)
To: Cyrill Gorcunov
Cc: akpm, linux-kernel, adobriyan, ebiederm, keescook,
kosaki.motohiro, matthltc, tj, xemul
s/mm-commits/lkml/
On 03/07, Cyrill Gorcunov wrote:
>
> On Tue, Mar 06, 2012 at 03:13:25PM -0800, akpm@linux-foundation.org wrote:
> > From: Oleg Nesterov <oleg@redhat.com>
> > Subject: mm/exec: rename mm->exe_file to mm->exe_path
> >
> > Rename mm->exe_file to mm->exe_path. We only need this member to get the
> > path - an additional reference to bprm->file makes no sense.
> >
> > The patch doesn't rename added_exe_file_vma/removed_exe_file_vma and
> > mm->num_exe_file_vmas, and perhaps we can remove them later.
> >
> > Also remove the stale comment in include/linux/mm.h.
> >
> > Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> > Acked-by: Matt Helsley <matthltc@us.ibm.com>
> > Cc: Alexey Dobriyan <adobriyan@gmail.com>
> > Cc: Cyrill Gorcunov <gorcunov@openvz.org>
> > Cc: "Eric W. Biederman" <ebiederm@xmission.com>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> > Cc: Pavel Emelyanov <xemul@parallels.com>
> > Cc: Tejun Heo <tj@kernel.org
> > Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
>
> Hi Oleg, I fear this won't work.
Why?
> The reference to the plain
> path pointer is not enough.
Why? ;)
> Previously we always have a
> copy reference to 'struct file' in mm:exe_file.
And?
> But now we don't have it and as result I can easily trigger
> NULL dereference simply reading /proc/pid/exe link in
> a cycle in one process and kill the program in another.
Thanks!
But so far I disagree, I can't understand why struct path can't work.
Of course I can be wrong, but currently I think that either this patch
reveals another problem (unlikley), or (most likely) I did some stupid
mistake.
Can you send me the reproducer just in case?
> [ 1961.066410] Code: 41 5c 41 5d c9 c3 55 48 89 e5 41 54 53 48 83 ec 30
> 66 66 66 66 90 48 63 c2 89 55 cc 48 89 fb 48 8d 04 06 48 89 45 e8 48 8b
> 7f 08 <48> 8b 87 a8 00 00 00 48 85 c0 74 0d 48 8b 40 38 48 85 c0 74 04
No sure I understand this asm... Looks like path->dentry is NULL, strange.
I do not think I really need it, but just in case... could you send me
(privately) the result of "make fs/dcache.s" ?
I'll try to recheck the patch and think.
But if you can _explain_ why do you think that "struct path" can't work,
please explain ;)
Oleg.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree
2012-03-07 17:41 ` Oleg Nesterov
@ 2012-03-07 19:34 ` Cyrill Gorcunov
2012-03-07 19:51 ` Oleg Nesterov
0 siblings, 1 reply; 5+ messages in thread
From: Cyrill Gorcunov @ 2012-03-07 19:34 UTC (permalink / raw)
To: Oleg Nesterov
Cc: akpm, linux-kernel, adobriyan, ebiederm, keescook,
kosaki.motohiro, matthltc, tj, xemul
On Wed, Mar 07, 2012 at 06:41:13PM +0100, Oleg Nesterov wrote:
...
>
> Of course I can be wrong, but currently I think that either this patch
> reveals another problem (unlikley), or (most likely) I did some stupid
> mistake.
>
> Can you send me the reproducer just in case?
>
> > [ 1961.066410] Code: 41 5c 41 5d c9 c3 55 48 89 e5 41 54 53 48 83 ec 30
> > 66 66 66 66 90 48 63 c2 89 55 cc 48 89 fb 48 8d 04 06 48 89 45 e8 48 8b
> > 7f 08 <48> 8b 87 a8 00 00 00 48 85 c0 74 0d 48 8b 40 38 48 85 c0 74 04
>
> No sure I understand this asm... Looks like path->dentry is NULL, strange.
>
> I do not think I really need it, but just in case... could you send me
> (privately) the result of "make fs/dcache.s" ?
>
yes, just sent.
> I'll try to recheck the patch and think.
>
> But if you can _explain_ why do you think that "struct path" can't work,
> please explain ;)
OK, the best way to prove myself that I was wrong is to try to
explain why it can't work. So I prepared a call trace to point
where we can get a reference to non-existing path and... found
that it's simply impossible. So then I tried to repeat oops
after the test machine got rebooted and found that I can't
repeat it. I'll continue testing but I think it was unrelated
OOPs. Sorry for false alarm, Oleg!
Cyrill
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree
2012-03-07 19:34 ` Cyrill Gorcunov
@ 2012-03-07 19:51 ` Oleg Nesterov
2012-03-07 20:37 ` Cyrill Gorcunov
0 siblings, 1 reply; 5+ messages in thread
From: Oleg Nesterov @ 2012-03-07 19:51 UTC (permalink / raw)
To: Cyrill Gorcunov
Cc: akpm, linux-kernel, adobriyan, ebiederm, keescook,
kosaki.motohiro, matthltc, tj, xemul
Andrew, please drop this (trivial as I thought) patch :/
On 03/07, Cyrill Gorcunov wrote:
>
> On Wed, Mar 07, 2012 at 06:41:13PM +0100, Oleg Nesterov wrote:
> ...
> > I do not think I really need it, but just in case... could you send me
> > (privately) the result of "make fs/dcache.s" ?
> >
>
> yes, just sent.
>
> > I'll try to recheck the patch and think.
> >
> > But if you can _explain_ why do you think that "struct path" can't work,
> > please explain ;)
>
> OK, the best way to prove myself that I was wrong is to try to
> explain why it can't work. So I prepared a call trace to point
> where we can get a reference to non-existing path and... found
> that it's simply impossible.
It is possible, and you even explained this in the private email
with asm you sent me.
> OOPs. Sorry for false alarm, Oleg!
No, thanks for the report and analysis.
Indeed, the patch is deadly wrong. Somehow I missed that ->f_path
is not the pointer! So set_mm_exe_path(&bprm->file->f_path) is
is obvioulsy wrong. I didn't bother to think about "&" think call
needs.
Thanks!
Oleg.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree
2012-03-07 19:51 ` Oleg Nesterov
@ 2012-03-07 20:37 ` Cyrill Gorcunov
0 siblings, 0 replies; 5+ messages in thread
From: Cyrill Gorcunov @ 2012-03-07 20:37 UTC (permalink / raw)
To: Oleg Nesterov
Cc: akpm, linux-kernel, adobriyan, ebiederm, keescook,
kosaki.motohiro, matthltc, tj, xemul
On Wed, Mar 07, 2012 at 08:51:04PM +0100, Oleg Nesterov wrote:
...
>
> > OOPs. Sorry for false alarm, Oleg!
>
> No, thanks for the report and analysis.
>
> Indeed, the patch is deadly wrong. Somehow I missed that ->f_path
> is not the pointer! So set_mm_exe_path(&bprm->file->f_path) is
> is obvioulsy wrong. I didn't bother to think about "&" think call
> needs.
>
OK. So it is not a false alarm as I thought after
trying to write a call trace, good to know ;)
Anyway, this problem is hard to repeat and I have
no idea how I managed to hit it in first place.
It was indeed "easily" until I rebooted the test
machine.
Cyrill
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-03-07 20:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-06 23:13 + mm-exec-rename-mm-exe_file-to-mm-exe_path.patch added to -mm tree akpm
[not found] ` <20120307162630.GG20558@moon>
2012-03-07 17:41 ` Oleg Nesterov
2012-03-07 19:34 ` Cyrill Gorcunov
2012-03-07 19:51 ` Oleg Nesterov
2012-03-07 20:37 ` Cyrill Gorcunov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.