Fix redirections with execute. Redirection consumed the remembered
input, and execute couldn't find it and mistakenly raised the tampering deity alarm. Closes #804644: (saved_bytes): New. (save_input): Set it. (forget_input): New. (seen_input): Don't discard, return a value for forget_input(). (save_input): Return a value for forget_input(), just because it makes sense. (input_to_forget, redir_authorized, prompt): Save value of seen_input() to new input_to_forget in redir_authorized(), pass it to forget_input() in prompt().
This commit is contained in:
parent
72b01c8ba1
commit
02a9af06a0
3 changed files with 54 additions and 8 deletions
|
@ -39,8 +39,15 @@
|
|||
#include "secure.h"
|
||||
|
||||
struct ring recent_input;
|
||||
static size_t saved_bytes;
|
||||
|
||||
void
|
||||
/*
|
||||
* Remember line of input INP for a while.
|
||||
* It must end with a newline.
|
||||
* Return value is suitable for forget_input(): it makes it forget all
|
||||
* input up to and including this line.
|
||||
*/
|
||||
size_t
|
||||
save_input(char *inp)
|
||||
{
|
||||
size_t len = strlen(inp);
|
||||
|
@ -53,19 +60,47 @@ save_input(char *inp)
|
|||
ring_discard(&recent_input, ring_search(&recent_input, "\n"));
|
||||
ring_putm(&recent_input, inp, len);
|
||||
}
|
||||
saved_bytes += len;
|
||||
return saved_bytes;
|
||||
}
|
||||
|
||||
int
|
||||
/*
|
||||
* Can you still remember a line of input that ends with TAIL?
|
||||
* It must end with a newline.
|
||||
* Return non-zero iff TAIL can be remembered.
|
||||
* Passing that value to forget_input() will forget all input up to
|
||||
* and including this line.
|
||||
*/
|
||||
size_t
|
||||
seen_input(char *tail)
|
||||
{
|
||||
size_t len = strlen(tail);
|
||||
int dist = ring_search(&recent_input, tail);
|
||||
size_t remembered = ring_len(&recent_input);
|
||||
int dist;
|
||||
|
||||
assert(len && tail[len - 1] == '\n');
|
||||
|
||||
dist = ring_search(&recent_input, tail);
|
||||
if (dist < 0)
|
||||
return 0;
|
||||
|
||||
ring_discard(&recent_input, dist + len);
|
||||
return 1;
|
||||
assert(dist + len <= remembered && remembered <= saved_bytes);
|
||||
return saved_bytes - remembered + dist + len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Forget remembered input up to SEEN.
|
||||
* SEEN should be obtained from save_input() or seen_input().
|
||||
*/
|
||||
void
|
||||
forget_input(size_t seen)
|
||||
{
|
||||
size_t forgotten = saved_bytes - ring_len(&recent_input);
|
||||
|
||||
assert(seen);
|
||||
|
||||
if (seen > forgotten) {
|
||||
assert(ring_peek(&recent_input, seen - forgotten - 1) == '\n');
|
||||
ring_discard(&recent_input, seen - forgotten);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
#ifndef SECURE_H
|
||||
#define SECURE_H
|
||||
|
||||
extern void save_input(char *);
|
||||
extern int seen_input(char *);
|
||||
extern size_t save_input(char *);
|
||||
extern size_t seen_input(char *);
|
||||
extern void forget_input(size_t);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
* Dave Pare, 1989
|
||||
* Steve McClure, 1998
|
||||
* Ron Koenderink, 2005
|
||||
* Markus Armbruster, 2005-2007
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -50,6 +51,7 @@ FILE *auxfp;
|
|||
|
||||
static FILE *redir_fp;
|
||||
static FILE *pipe_fp;
|
||||
static size_t input_to_forget;
|
||||
|
||||
static void prompt(int, char *, char *);
|
||||
static void doredir(char *p);
|
||||
|
@ -124,7 +126,12 @@ prompt(int code, char *prompt, char *teles)
|
|||
(void)pclose(pipe_fp);
|
||||
pipe_fp = NULL;
|
||||
}
|
||||
if (input_to_forget) {
|
||||
forget_input(input_to_forget);
|
||||
input_to_forget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nl = code == C_PROMPT || code == C_INFORM ? "\n" : "";
|
||||
printf("%s%s%s", nl, teles, prompt);
|
||||
fflush(stdout);
|
||||
|
@ -148,11 +155,14 @@ fname(char *s)
|
|||
static int
|
||||
redir_authorized(char *arg, char *attempt)
|
||||
{
|
||||
if (!seen_input(arg)) {
|
||||
size_t seen = seen_input(arg);
|
||||
|
||||
if (!seen || (input_to_forget && input_to_forget != seen)) {
|
||||
fprintf(stderr, "WARNING! Server attempted to %s %s\n",
|
||||
attempt, arg);
|
||||
return 0;
|
||||
}
|
||||
input_to_forget = seen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue