Ndef-write from package nfcd-tools crashes when trying to write a empty tag

REPRODUCIBILITY (% or how often): 100% (tested +/- 30 times)
BUILD ID = OS VERSION (Settings > About product): 4.3.0.12
HARDWARE (XA2, X10, X10 II, …): X10 II
UI LANGUAGE: nl_NL
REGRESSION: (compared to previous public release: Yes, No, ?): ?

DESCRIPTION:

While trying to write to a NFC tag usingndef-writefrom the nfcd-tools package, ndef-write segfaults when running.

I have no idea what the best place is to report this issue. The issue tracker at GitHub is closed and bugs.sailfishos.org doesn’t that active any more, there doesn’t seem to be a category for nfcd to begin with, so I’d thought I’d report it over here.

In the meanwhile, is there another way to write NFC tags? I’ve tried writing a simple application using the Qt NFC module, but the Qt NFC implementation seems to be intentionally disabled: qnearfieldtarget_neard_p.h\nfc\src - qt/qtconnectivity.git - Qt Connectivity due to https://bugreports.qt.io/browse/QTBUG-43802

PRECONDITIONS:

Have the package nfcd-tools installed (zypper in nfcd-tools).

STEPS TO REPRODUCE:

  1. Install ndef-write from the package nfcd-tools
  2. Run ndef-write -v -u https://example.org in a terminal.

EXPECTED RESULT:

The NDEF URI record gets written to the tag and some debugging output appears on the terminal.

ACTUAL RESULT:

Nothing gets written to stdout and a segmentation fault occurs

ADDITIONAL INFORMATION:

Writing an SmartPoster or Text record also fails and crashes the program. Writing an empty record does not crash.

I’ve tried debugging it myself, but the behaviour of the program differs depending on whether or not it is being debugged. It will segfault less and print the more breakpoints are set for some reason:

(gdb) start -v --uri https://example.org
Temporary breakpoint 1 at 0x403740: file ndef-write.c, line 521.
Starting program: /usr/bin/ndef-write -v --uri https://example.org
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Temporary breakpoint 1, main (argc=4, argv=0x7ffffff6c8) at ndef-write.c:521
521         char* uri = NULL;
(gdb) b write_ndef
Breakpoint 2 at 0x40fce0: file ndef-write.c, line 345.
(gdb) b write_ndef_to_type2_tag
Breakpoint 3 at 0x410194: file ndef-write.c, line 220.
(gdb) b ndef-write.c:583
Breakpoint 4 at 0x403a44: file ndef-write.c, line 583.
(gdb) c
Continuing.

Breakpoint 4, main (argc=<optimized out>, argv=<optimized out>) at ndef-write.c:583
583                     NfcNdefRec* rec = ndef_proc(ndef_spec);
(gdb) c
Continuing.

Breakpoint 2, write_ndef (app=app@entry=0x7ffffff438) at ndef-write.c:345
345         GError* error = NULL;
(gdb) c
Continuing.
[New Thread 0x7fbf57e100 (LWP 26972)]
[New Thread 0x7fbf37d100 (LWP 26973)]
NFC adapter /nfc0
Waiting for tag...
Tag detected
Tag /nfc0/tag10
Type 2 tag /nfc0/tag10

Thread 1 "ndef-write" hit Breakpoint 3, write_ndef_to_type2_tag (t2=0x46a290, app=0x7ffffff438) at ndef-write.c:220
220                     ret = write_ndef_to_type2_tag(app, t2);
(gdb) c
Continuing.
Read 496 bytes:
  0000: 03 00 fe 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0010: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  00F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  0190: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  01A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  01B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  01C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  01D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
  01E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00    ........ ........
Nothing to write.

Thread 1 "ndef-write" received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in  ()
#1  0x0000000000403a6c in main (argc=<optimized out>, argv=<optimized out>) at ndef-write.c:588

Note that it will never reach to this point without setting these breakpoints. I’m utterly confused why it happens, as it happens both on the version available from the Jolla repo’s as well as the one I compiled myself from https://github.com/sailfishos/nfcd.git at version 1.1.9, using sdfk build -d and sfdk deploy --sdk --debug. I’ve made sure to reboot my phone for the new daemon to be load, but it still happens.

I have no idea how I can debug this any further, as I’m confused why the program behaves differently when it is observed with a debugger.

There are memory corruption (the program is writing outside where it should), so depending how the allocated memory for the program is mapped, it will crash at different places or not crash at all. Running inside gdb makes the memory layout different from when it is run outside.

If I may suggest an option for such cases, you can try to run it with valgrind. It will then print out when there is a memory write outside a valid region.

Good luck, these are tricky cases.

1 Like