diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs
index 778d38b153764..81371708b51e9 100644
--- a/library/core/src/io/borrowed_buf.rs
+++ b/library/core/src/io/borrowed_buf.rs
@@ -249,9 +249,10 @@ impl<'a> BorrowedCursor<'a> {
     /// Panics if there are less than `n` bytes initialized.
     #[inline]
     pub fn advance(&mut self, n: usize) -> &mut Self {
-        assert!(self.buf.init >= self.buf.filled + n);
+        let filled = self.buf.filled.strict_add(n);
+        assert!(filled <= self.buf.init);
 
-        self.buf.filled += n;
+        self.buf.filled = filled;
         self
     }
 
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index eb5d59887683b..090a091b09a13 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -209,6 +209,15 @@ fn read_buf_exact() {
     assert_eq!(c.read_buf_exact(buf.unfilled()).unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
 }
 
+#[test]
+#[should_panic]
+fn borrowed_cursor_advance_overflow() {
+    let mut buf = [0; 512];
+    let mut buf = BorrowedBuf::from(&mut buf[..]);
+    buf.unfilled().advance(1);
+    buf.unfilled().advance(usize::MAX);
+}
+
 #[test]
 fn take_eof() {
     struct R;