The path of a handle is also used to mark the handle slot as used. When
strdup() failed the handle was returned to the client but the slot was
still marked as free and got reused (and the file descriptor of the
first user got lost) with the next open request.
Return -ENOMEM when the path can not be allocated. The callers close the
file descriptor and the handle slot remains unused.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
The path of an opened file or directory handle is allocated with
strdup() but was not freed when the handle got closed. Every open/close
sequence leaked the path string.
Free the path before clearing the handle.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
The Read File response buffer was allocated for the response header and
the requested data only. Short responses (e.g. count = 0) are extended to
ISOBUSFS_MIN_TRANSFER_LENGH which read beyond the allocated buffer and
sent heap content to the client.
Allocate at least ISOBUSFS_MIN_TRANSFER_LENGH bytes and fill the unused
bytes with 0xff.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Read File and Seek File requests only checked the handle index to be
within the handles array. Unused or closed handle slots are zeroed
(fd = 0, dir = NULL), so a read request on such a handle read from the
server's stdin and sent the content to the client. Additionally every
client was able to read and seek handles opened by other clients.
Add isobusfs_srv_get_client_handle() which only returns handles that
are in use and have been opened by the requesting client.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Fix directory operations to comply with ISO 11783-13:2021 (sections
C.3.4.2 and C.3.5.2), which specifies that directory operations differ
significantly from standard file operations:
- The Count parameter in a Read File request represents the number of
directory entries to read, not the number of bytes.
- The Offset parameter in a Seek File request represents the logical
entry index, not a byte offset.
The previous implementation treated directories strictly as files,
using byte-based offsets and counts. This resulted in incorrect seeking
behavior and protocol violations when listing directories.
Align the implementation with the standard by:
1. Server side:
- Introduce isobusfs_srv_dir_entry_visible() to consistently
filter out invalid (unreadable, hidden, oversized) entries. This
ensures that entry indices remain stable.
- Implement isobusfs_srv_dir_skip_entries() to advance the
directory stream by logical visible entries rather than bytes.
- Update the Read File handler to interpret count as the
maximum number of entries and return the number of entries read
in the response header.
- Update the Seek File handler to seek by entry index.
2. Client side:
- Calculate the request count based on the number of minimal-size
entries that fit into the maximum data length.
- Interpret the response count as the number of entries received
rather than the byte length of the payload.
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Fix following clang warnings:
CC isobusfs/isobusfs_srv_fa.o
isobusfs/isobusfs_srv_fa.c:387:6: warning: variable 'handle' is used
uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (ret < 0) {
^~~~~~~
isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
res.handle = handle;
^~~~~~
isobusfs/isobusfs_srv_fa.c:387:2: note: remove the 'if' if its condition is
always false
if (ret < 0) {
^~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:368:6: warning: variable 'handle' is used
uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (name_len > ISOBUSFS_MAX_PATH_NAME_LENGTH) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
res.handle = handle;
^~~~~~
isobusfs/isobusfs_srv_fa.c:368:2: note: remove the 'if' if its condition is
always false
if (name_len > ISOBUSFS_MAX_PATH_NAME_LENGTH) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:362:6: warning: variable 'handle' is used
uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (name_len > msg->len - sizeof(*req)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
res.handle = handle;
^~~~~~
isobusfs/isobusfs_srv_fa.c:362:2: note: remove the 'if' if its condition is
always false
if (name_len > msg->len - sizeof(*req)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:356:6: warning: variable 'handle' is used
uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
if (!client) {
^~~~~~~
isobusfs/isobusfs_srv_fa.c:411:15: note: uninitialized use occurs here
res.handle = handle;
^~~~~~
isobusfs/isobusfs_srv_fa.c:356:2: note: remove the 'if' if its condition is
always false
if (!client) {
^~~~~~~~~~~~~~
isobusfs/isobusfs_srv_fa.c:352:16: note: initialize the variable 'handle' to
silence this warning
uint8_t handle;
^
= '\0'
isobusfs/isobusfs_srv_fa.c:505:9: warning: variable 'entry_count' set but not
used [-Wunused-but-set-variable]
size_t entry_count = 0;
^
5 warnings generated.
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Before more contributions will come, change the license and make this
project usable as a library.
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Introduce the ISOBUS File Server (FS) interface, compatible with ISO
11783-13. The implementation utilizes the kernel's existing CAN J1939
socket support.
For testing following setup can be used:
ip link add type vcan
ip l s dev vcan0 up
j1939acd -r 64-95 -c /tmp/1122334455667788.jacd 1122334455667788 vcan0 &
j1939acd -r 96-127 -c /tmp/1122334455667789.jacd 1122334455667789 vcan0 &
sleep 1
isobusfs-srv -i vcan0 -n 1122334455667788 -v vol1:/path/to/export/
isobusfs-cli -i vcan0 -n 0x1122334455667789 -m 0x1122334455667788 -I
Interactive mode currently support following commands:
exit - exit interactive mode
quit - exit interactive mode
help - show this help
dmesg - show log buffer
selftest - run selftest
ls - list directory
ll - list directory with long listing format
cd - change directory
pwd - print name of current/working directory
get - get file
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>