Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rustc >= nightly-2021-03-05 builds (i.e. LLVM 12) #135

Closed
ojeda opened this issue Mar 21, 2021 · 11 comments · Fixed by #288
Closed

Fix rustc >= nightly-2021-03-05 builds (i.e. LLVM 12) #135

ojeda opened this issue Mar 21, 2021 · 11 comments · Fixed by #288
Labels
• toolchain Related to `rustc`, `bindgen`, `rustdoc`, LLVM, Clippy...

Comments

@ojeda
Copy link
Member

ojeda commented Mar 21, 2021

https://github.com/Rust-for-Linux/linux/pull/134/checks?check_run_id=2161428668

[    0.270313] module rust_example_3: unsupported RELA relocation: 311
@ojeda ojeda added prio: high • kbuild Related to building the kernel, `make`, `Kbuild`, `Kconfig` options... labels Mar 21, 2021
@ojeda
Copy link
Member Author

ojeda commented Mar 22, 2021

See also
https://lore.kernel.org/rust-for-linux/CAMmOe3SaBn9+XzjhZC8QxmZnHQkvB0R=nV4NaRRyMRF6EfcvvA@mail.gmail.com/

@jabedude
Copy link

Relevant relocation from elf.h:

#define R_AARCH64_ADR_GOT_PAGE  311     /* P-page-rel. GOT off. ADRP 32:12.  */

I took a look at the logs for the CI failure and was wondering if there's a way to grab artifacts from the build run. I couldn't find a way

@ojeda
Copy link
Member Author

ojeda commented Mar 22, 2021

I took a look at the logs for the CI failure and was wondering if there's a way to grab artifacts from the build run.

There is currently no way that I am aware of, because we do not upload them (the reason is that, when I tried a couple months ago, it turned out it failed from time to time, it was not reliable).

@ojeda
Copy link
Member Author

ojeda commented Mar 23, 2021

This was due to rustc's upgrade to LLVM 12 (rust-lang/rust#81451) starting in nightly 2021-03-05.

Possibly also related to rust-lang/rust#83335.

@ojeda ojeda changed the title Find out why #134 failed Fix rustc >= nightly-2021-03-05 builds (i.e. LLVM 12) Mar 23, 2021
@alex
Copy link
Member

alex commented Mar 23, 2021 via email

@ojeda
Copy link
Member Author

ojeda commented Mar 23, 2021

Yeah, I tried setting "position-independent-executable": false in case relocation-model was somehow being overridden now by the former, but it didn't help. Not sure how they interact in any case.

@ojeda ojeda added • toolchain Related to `rustc`, `bindgen`, `rustdoc`, LLVM, Clippy... and removed • kbuild Related to building the kernel, `make`, `Kbuild`, `Kconfig` options... labels Mar 23, 2021
@ojeda
Copy link
Member Author

ojeda commented Mar 23, 2021

@alex
Copy link
Member

alex commented Mar 28, 2021

PR on the Rust side: rust-lang/rust#83592

@ojeda
Copy link
Member Author

ojeda commented Apr 6, 2021

The fix has been merged 🎊 -- I will try the new nightly tomorrow and update accordingly.

@ojeda
Copy link
Member Author

ojeda commented Apr 8, 2021

No more unsupported relocations since nightly 2021-04-07. However, rustfmt is not there in the last two so we need to wait.

@bjorn3
Copy link
Member

bjorn3 commented Apr 15, 2021

Rustfmt has been present since 2021-04-13: https://rust-lang.github.io/rustup-components-history/

bors added a commit to rust-lang-ci/rust that referenced this issue May 19, 2021
Set dso_local for more items

Related to rust-lang#83592. (cc `@nagisa)`

Noticed that on x86_64 with `relocation-model: static` `R_X86_64_GOTPCREL` relocations were still generated in some cases. (related: Rust-for-Linux/linux#135; Rust-for-Linux needs these fixes to successfully build)

First time doing anything with LLVM so not sure whether this is correct but the following are some of the things I've tried to convince myself.

## C equivalent

Example from clang which also sets `dso_local` in these cases:
`clang-12 -fno-PIC -S -emit-llvm test.c`
```C
extern int A;

int* a() {
    return &A;
}

int B;

int* b() {
    return &B;
}
```
```
; ModuleID = 'test.c'
source_filename = "test.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

`@A` = external dso_local global i32, align 4
`@B` = dso_local global i32 0, align 4

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32* `@a()` #0 {
  ret i32* `@A`
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32* `@b()` #0 {
  ret i32* `@B`
}

attributes #0 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project/ b978a93)"}
```
`clang-12 -fno-PIC -c test.c`
`objdump test.o -r`:
```
test.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
0000000000000006 R_X86_64_64       A
0000000000000016 R_X86_64_64       B

RELOCATION RECORDS FOR [.eh_frame]:
OFFSET           TYPE              VALUE
0000000000000020 R_X86_64_PC32     .text
0000000000000040 R_X86_64_PC32     .text+0x0000000000000010
```

## Comparison to pre-LLVM 12 output

`rustc --emit=obj,llvm-ir --target=x86_64-unknown-none-linuxkernel --crate-type rlib test.rs`
```Rust
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized {}

#[lang="sync"]
trait Sync {}

#[lang = "drop_in_place"]
pub unsafe fn drop_in_place<T: ?Sized>(_: *mut T) {}

impl Sync for i32 {}

pub static STATIC: i32 = 32;

extern {
    pub static EXT_STATIC: i32;
}

pub fn a() -> &'static i32 {
    &STATIC
}
pub fn b() -> &'static i32 {
    unsafe {&EXT_STATIC}
}
```
`objdump test.o -r`
nightly-2021-02-20 (rustc target is `x86_64-linux-kernel`):
```
RELOCATION RECORDS FOR [.text._ZN4test1a17h1024ba65f3424175E]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_32S      _ZN4test6STATIC17h3adc41a83746c9ffE

RELOCATION RECORDS FOR [.text._ZN4test1b17h86a6a80c1190ac8dE]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_32S      EXT_STATIC
```
nightly-2021-05-10:
```
RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_GOTPCREL  _ZN4test6STATIC17h5a059515bf3d4968E-0x0000000000000004

RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_GOTPCREL  EXT_STATIC-0x0000000000000004
```
This PR:
```
RELOCATION RECORDS FOR [.text._ZN4test1a17he846f03bf37b2d20E]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_32S      _ZN4test6STATIC17h5a059515bf3d4968E

RELOCATION RECORDS FOR [.text._ZN4test1b17h7e0f7f80fbd91125E]:
OFFSET           TYPE              VALUE
0000000000000007 R_X86_64_32S      EXT_STATIC
```
fbq pushed a commit that referenced this issue Dec 28, 2023
syzkaller report:

 kernel BUG at net/core/skbuff.c:3452!
 invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.7.0-rc4-00009-gbee0e7762ad2-dirty #135
 RIP: 0010:skb_copy_and_csum_bits (net/core/skbuff.c:3452)
 Call Trace:
 icmp_glue_bits (net/ipv4/icmp.c:357)
 __ip_append_data.isra.0 (net/ipv4/ip_output.c:1165)
 ip_append_data (net/ipv4/ip_output.c:1362 net/ipv4/ip_output.c:1341)
 icmp_push_reply (net/ipv4/icmp.c:370)
 __icmp_send (./include/net/route.h:252 net/ipv4/icmp.c:772)
 ip_fragment.constprop.0 (./include/linux/skbuff.h:1234 net/ipv4/ip_output.c:592 net/ipv4/ip_output.c:577)
 __ip_finish_output (net/ipv4/ip_output.c:311 net/ipv4/ip_output.c:295)
 ip_output (net/ipv4/ip_output.c:427)
 __ip_queue_xmit (net/ipv4/ip_output.c:535)
 __tcp_transmit_skb (net/ipv4/tcp_output.c:1462)
 __tcp_retransmit_skb (net/ipv4/tcp_output.c:3387)
 tcp_retransmit_skb (net/ipv4/tcp_output.c:3404)
 tcp_retransmit_timer (net/ipv4/tcp_timer.c:604)
 tcp_write_timer (./include/linux/spinlock.h:391 net/ipv4/tcp_timer.c:716)

The panic issue was trigered by tcp simultaneous initiation.
The initiation process is as follows:

      TCP A                                            TCP B

  1.  CLOSED                                           CLOSED

  2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...

  3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT

  4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

  5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...

  // TCP B: not send challenge ack for ack limit or packet loss
  // TCP A: close
	tcp_close
	   tcp_send_fin
              if (!tskb && tcp_under_memory_pressure(sk))
                  tskb = skb_rb_last(&sk->tcp_rtx_queue); //pick SYN_ACK packet
           TCP_SKB_CB(tskb)->tcp_flags |= TCPHDR_FIN;  // set FIN flag

  6.  FIN_WAIT_1  --> <SEQ=100><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ...

  // TCP B: send challenge ack to SYN_FIN_ACK

  7.               ... <SEQ=301><ACK=101><CTL=ACK>   <-- SYN-RECEIVED //challenge ack

  // TCP A:  <SND.UNA=101>

  8.  FIN_WAIT_1 --> <SEQ=101><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ... // retransmit panic

	__tcp_retransmit_skb  //skb->len=0
	    tcp_trim_head
		len = tp->snd_una - TCP_SKB_CB(skb)->seq // len=101-100
		    __pskb_trim_head
			skb->data_len -= len // skb->len=-1, wrap around
	    ... ...
	    ip_fragment
		icmp_glue_bits //BUG_ON

If we use tcp_trim_head() to remove acked SYN from packet that contains data
or other flags, skb->len will be incorrectly decremented. We can remove SYN
flag that has been acked from rtx_queue earlier than tcp_trim_head(), which
can fix the problem mentioned above.

Fixes: 1da177e ("Linux-2.6.12-rc2")
Co-developed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Link: https://lore.kernel.org/r/20231210020200.1539875-1-dongchenchen2@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
• toolchain Related to `rustc`, `bindgen`, `rustdoc`, LLVM, Clippy...
Development

Successfully merging a pull request may close this issue.

4 participants