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

libc/minimal: static variable of gmtime() does not located to z_libc_partition at usermode. #40679

Closed
atsushi-shinbo-esoltrinity opened this issue Nov 26, 2021 · 2 comments · Fixed by #45966
Assignees
Labels
area: Minimal libc Minimal C Standard Library area: Userspace Userspace bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Milestone

Comments

@atsushi-shinbo-esoltrinity

Describe the bug
A access fault occur when call gmtime() from a user thread.

gmtime() have a static allocated variable named "struct tm shared".
(zephyr/lib/libc/minimal/source/time/gmtime.c)
This variable is defined locally in the function, but allocated statically. So, it should be located to z_libc_partition.
Currently it is not. Therefore, an access fault occur when call gmtime() from user thread.

Issue 1:
The variable "shared" in gmtime() should be qualified with LIBC_DATA same as minimal/source/stdlib/rand.c.

static LIBC_DATA struct tm shared;

Issue 2:
Currently, to create "z_libc_partition" parition, CONFIG_MINIMAL_LIBC_RAND is also needed.
This configuration should only relate to rand function, not time function.

To Reproduce

  1. Modify samples/userspace/hello_world_user/src/main.c as following.
#include <zephyr.h>
#include <stdio.h>
#include <time.h>				// time_t
#include <sys/libc-hooks.h>		// z_libc_partition

#define USER_STACKSIZE	1024

struct k_thread user_thread;
K_THREAD_STACK_DEFINE(user_stack, USER_STACKSIZE);

static struct k_mem_domain user_domain;

static struct k_mem_partition *user_parts[] = {
	&z_libc_partition,
};

static void user_function(void *p1, void *p2, void *p3)
{
	printf("Hello World from UserSpace! %s\n", CONFIG_BOARD);
	
	time_t sec_time = 1234567890;	// 2009/02/13 23:31:30
	struct tm* tm_time = gmtime(&sec_time);
	printf("%02d/%02d/%02d %02d:%02d:%02d\n", 
		tm_time->tm_year + 1900,
		tm_time->tm_mon + 1,
		tm_time->tm_mday,
		tm_time->tm_hour,
		tm_time->tm_min,
		tm_time->tm_sec);
}

static void entry_user_function() {
	
	k_mem_domain_init(&user_domain, ARRAY_SIZE(user_parts), user_parts);
	k_mem_domain_add_thread(&user_domain, k_current_get());
	
	k_thread_user_mode_enter(user_function, NULL, NULL, NULL);
}

void main(void)
{
	k_thread_create(&user_thread, user_stack, USER_STACKSIZE,
			entry_user_function, NULL, NULL, NULL,
			-1, K_INHERIT_PERMS, K_MSEC(0));
}
  1. Add following lines to samples/userspace/hello_world_user/prj.conf
CONFIG_MINIMAL_LIBC=y
CONFIG_MINIMAL_LIBC_RAND=y
  1. west build -b hifive1_revb samples/userspace/hello_world_user
  2. cd build/zephyr
  3. $ZEPHYR_SDK_INSTALL_DIR/riscv64-zephyr-elf/bin/riscv64-zephyr-elf-objcopy -O ihex zephyr.elf zephyr.hex
  4. Write zephyr.hex to the Hifive1 revB board and run.

Expected behavior
gmtime() can be called from user thread when the thread have a permission to access "z_libc_partition".

Impact
I can use gmtime_r() instead of gmtime().
However, some library may use gmtime(), especially mbedtls. A example call flow is here.

mbedtls_x509_crt_verify()
 -> mbedtls_x509_time_is_past()
  -> x509_get_current_time()
   -> mbedtls_platform_gmtime_r()
    -> gmtime()

Logs and console output

*** Booting Zephyr OS version 2.7.99  ***
Hello World from UserSpace! hifive1_revb
E:
E:  mcause: 7, Store/AMO access fault
E:   mtval: 8000038c
E:      a0: 8000038c    t0: 20014004
E:      a1: 00000000    t1: 00000000
E:      a2: 800003b0    t2: 7fffffff
E:      a3: 00000000    t3: 499602d2
E:      a4: 000037d0    t4: a5690000
E:      a5: 8000038d    t5: 00000000
E:      a6: 00000000    t6: 00000000
E:      a7: a8c00000
E:                      tp: 2001f568
E:      ra: 20014548
E:    mepc: 2001425c
E: mstatus: 00000080
E:
E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
E: Current thread: 0x80000050 (unknown)
E: Halting system

Expected output (after workaround)

*** Booting Zephyr OS version 2.7.99  ***
Hello World from UserSpace! hifive1_revb
2009/02/13 23:31:30

Environment (please complete the following information):

  • OS: Ubuntu 18.04.5 LTS
  • Toolchain: zephyr-sdk-0.13.1
  • Version: v2.7.99
  • Commit: 1238410
  • Target: hifive1_revb
  • modules/crypto/mbedtls : "mbed TLS 3.0.0" (bf66e18046a96e83b6ef3bb4bec0ae81bdcefc68)
@atsushi-shinbo-esoltrinity atsushi-shinbo-esoltrinity added the bug The issue is a bug, or the PR is fixing a bug label Nov 26, 2021
@cfriedt cfriedt added the area: Minimal libc Minimal C Standard Library label Nov 30, 2021
@cfriedt cfriedt added area: Userspace Userspace priority: medium Medium impact/importance bug labels Nov 30, 2021
@github-actions
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

@github-actions
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Minimal libc Minimal C Standard Library area: Userspace Userspace bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants