aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin
diff options
context:
space:
mode:
authormurilo ijanc2026-03-25 15:41:40 -0300
committermurilo ijanc2026-03-25 15:49:08 -0300
commit290f53c38cdacd502eb6dda52f2ad207063e3973 (patch)
treec5cd20f1fdc56b1d2420f12c674700ca1db396c0 /src/bin
parent62b68cc461b5e298add3ab190fe9a38f3efefe7a (diff)
downloadtesseras-paste-290f53c38cdacd502eb6dda52f2ad207063e3973.tar.gz
Limit stdin read in tp, bound protocol drain, document Arc leak
- tp: limit stdin to 64 KiB + 1 byte to reject oversized pastes early without unbounded memory allocation - daemon: bound the oversized-line drain to MAX_LINE_SIZE so a client without newlines cannot block beyond the read timeout - tpd: document intentional Arc::into_raw leak in signal handler
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/tp.rs27
-rw-r--r--src/bin/tpd.rs4
2 files changed, 23 insertions, 8 deletions
diff --git a/src/bin/tp.rs b/src/bin/tp.rs
index 860d1c9..5c4c473 100644
--- a/src/bin/tp.rs
+++ b/src/bin/tp.rs
@@ -110,14 +110,27 @@ fn main() {
std::process::exit(1);
}
};
+ // Read at most MAX_PASTE + 1 byte so we can detect
+ // oversized input without unbounded allocation.
+ const MAX_PASTE: usize = 64 * 1024;
let mut content = Vec::new();
- if let Err(e) = std::io::stdin().read_to_end(&mut content) {
- eprintln!("error: reading stdin: {e}");
- std::process::exit(1);
- }
- if content.is_empty() {
- eprintln!("error: empty input");
- std::process::exit(1);
+ match std::io::stdin()
+ .take((MAX_PASTE + 1) as u64)
+ .read_to_end(&mut content)
+ {
+ Ok(0) => {
+ eprintln!("error: empty input");
+ std::process::exit(1);
+ }
+ Ok(n) if n > MAX_PASTE => {
+ eprintln!("error: input exceeds 64 KiB limit");
+ std::process::exit(1);
+ }
+ Err(e) => {
+ eprintln!("error: reading stdin: {e}");
+ std::process::exit(1);
+ }
+ _ => {}
}
let cmd = if public { "PUTP" } else { "PUT" };
format!("{cmd} {ttl_secs} {}\n", base58::encode(&content))
diff --git a/src/bin/tpd.rs b/src/bin/tpd.rs
index a1edf79..e1ebc7b 100644
--- a/src/bin/tpd.rs
+++ b/src/bin/tpd.rs
@@ -256,7 +256,9 @@ fn main() {
let shutdown = Arc::new(AtomicBool::new(false));
- // Signal handler
+ // Signal handler — Arc::into_raw intentionally leaks the
+ // refcount so the pointer remains valid for the process
+ // lifetime. No matching Arc::from_raw needed.
let sig = Arc::clone(&shutdown);
unsafe {
SHUTDOWN_PTR.store(