Reading and writing system properties on KaiOS
KaiOS is a partially open source mobile Linux distribution that, under the hood, makes significant use of Android components like the Hardware Abstraction Layer (HAL). Gonk is KaiOS’ platform denomination for a combination of the Linux kernel and Android HAL, borrowed from it’s predecessor Firefox OS.
Like Android, KaiOS has system properties that provide a convenient way to share information like configurations, system-wide. These are stored in read-only property files (.prop
extension) like bootimg/ramdisk/default.prop
and system/build.prop
. System properties are then managed by property_service
to populate its internal in-memory database at start-up.
System properties are stored in a key-value format and include useful information like the device model name (ro.product.model
), whether debug mode is enabled (ro.debuggable
), and the timestamp when the OS build was generated (ro.bootimage.build.date.utc
).
Android Device Bridge (ADB)
Like Android, system properties are accessible using the getprop
and setprop
shell commands via the Android Device Bridge (ADB). Not all commercial KaiOS devices will be equip with ADB vendor keys, in which case you’ll get an unauthorized
error message.
1adb shell getprop ro.build.version.sdk
2adb shell setprop ctl.stop wpa_supplicant
Low-level Access
Static libraries like libcutils
(system/lib/libcutils.so
) contain wrappers to access system properties via native contexts in C/C++. In KaiOS, this is abstracted via
SystemProperty.cpp which lazy-loads libcutils
used throughout Gonk.
1// Get system property, null default value
2Property::Get("ro.build.version.sdk", value, nullptr);
3
4// Set system property to "radvd"
5Property::Set("ctl.start", "radvd");
The second example uses another special property that communicates with [init.rc]. Control messages–ctl.start
, ctl.stop
, and ctl.restart
–do as their name suggests: identify a service by name and start, stop, or restart it.
libcutils
is also exponsed via XPCOM components from a Javascript context within the Gecko system context.
1// Get system property, with "1" as the default value
2let numClients = libcutils.property_get("ro.moz.ril.numclients", "1");
3
4// Set system property value to "1"
5libcutils.property_set("sys.boot_completed", "1");
EngMode API
System properties are also accessible to
certified KaiOS apps using the
Engmode API . Behind the scenes, the Engmode API uses the same libcutils
component packaged with the
omni.ja
file.
KaiOS 2.5
1// Get system property
2let buildType = navigator.engmodeExtension.getPropertyValue("ro.build.type");
3
4// Set system property value to "b2g"
5navigator.engmodeExtension.setPropertyValue("ctl.stop", "b2g");
KaiOS 3.0
1// Get system property, returns Promise<string>
2navigator.b2g.engmodeManager.getPropertyValue("ro.operator.name")
3 .then((operator) => console.log(operator));
4
5// Set system property value to "1"
6navigator.b2g.engmodeManager.setPropertyValue("persist.service.adb.enable", "1");
Over-permissioning: In 2020, information security firm
NCC Group noted that the system Browser is over-permissioned with the jrdextension
and engmode
permissions. These are used to determine the carrier, but inadvertently grants access the Engmode API from Javascript executed on websites. This remains true across all tested version of KaiOS 2.5.
TCT Web Server
Using the same methodology identified in
CVE-2023-33294, it’s possible to access and modify system proprties from any Javascript context using XMLHttpRequest
. A local HTTP server is exposed at http://127.0.0.1:2929
on KaiOS 3.0 (http://127.0.0.1:1380/engmode/
on the
JioPhone Prima 4G running KaiOS 2.5.4), that accepts arbitrary commands to run as root.
1let xhr = new XMLHttpRequest();
2xhr.open("POST", "http://127.0.0.1:2929", true);
3xhr.send('cmd=shell&shellcommand=getprop ro.build.type');
However, this method isn’t recommended because it exploits a known vulnerability that doesn’t work across all KaiOS versions. Moreover, the port, path, and command syntax vary across devices.
Modifying Properties
Property namespaces (prefixes) are important, namely ro
(for properties set only once), and persist
(for properties that persist across reboots). Moreover, on KaiOS 2.5.4+ and KaiOS 3.0+, Security-Enhanced Linux (SELinux)
property contexts apply, which may prevent certain properties from being modified even with engmode
access.
Example Property Files
The following property files are from the recent JioPhone Prima 4G.
default.prop
1#
2# ADDITIONAL_DEFAULT_PROPERTIES
3#
4persist.log.tag=I
5ro.secure=1
6ro.allow.mock.location=0
7ro.debuggable=0
8ro.zygote=zygote32
9dalvik.vm.image-dex2oat-Xms=64m
10dalvik.vm.image-dex2oat-Xmx=64m
11dalvik.vm.dex2oat-Xms=64m
12dalvik.vm.dex2oat-Xmx=512m
13ro.dalvik.vm.native.bridge=0
14debug.atrace.tags.enableflags=0
15camera.disable_zsl_mode=1
16ro.gpu.boost=0
17persist.sys.usb.config=cdrom
18sys.usb.controller=musb-hdrc.0.auto
19ro.support.auto.roam=disabled
20#
21# BOOTIMAGE_BUILD_PROPERTIES
22#
23ro.bootimage.build.date=2023年 09月 01日 星期五 15:45:31 CST
24ro.bootimage.build.date.utc=1693554331
25ro.bootimage.build.fingerprint=Jio/F491H/F491H:6.0/MRA58K/Jio-F491H-F001-04-13-310823:user/release-keys
build.prop
1
2# begin build properties
3# autogenerated by buildinfo.sh
4ro.build.id=MRA58K
5ro.build.display.id=MRA58K release-keys
6ro.build.version.incremental=Jio-F491H-F001-04-13-310823
7ro.build.version.sdk=23
8ro.build.version.preview_sdk=0
9ro.build.version.codename=REL
10ro.build.version.all_codenames=REL
11ro.build.version.release=6.0
12ro.build.version.security_patch=2016-07-01
13ro.build.version.base_os=
14ro.build.date=2023年 09月 01日 星期五 15:42:27 CST
15ro.build.date.utc=1693554147
16ro.build.type=user
17ro.build.user=serveradmin
18ro.product.version_tag=kaios_jp4_pier_odm_20230829_10
19ro.fota.sw_ver=F.001.04.13
20ro.fota.cu_ref=F491H-PBJIINB
21ro.product.base_version=SPRDROID6.0_KAIOS_17D_RLS3_W20.52.2_P1
22ro.product.sar_value=Head SAR: 0.89 W/kg Body SAR: 1.37
23ro.build.host=bjfih007
24ro.build.tags=release-keys
25ro.build.flavor=MAD-user
26ro.product.model=F491H
27ro.product.brand=JIO
28ro.product.name=MAD
29ro.product.device=F491H
30ro.product.board=sp9820e_1h10
31# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,
32# use ro.product.cpu.abilist instead.
33ro.product.cpu.abi=armeabi-v7a
34ro.product.cpu.abi2=armeabi
35ro.product.cpu.abilist=armeabi-v7a,armeabi
36ro.product.cpu.abilist32=armeabi-v7a,armeabi
37ro.product.cpu.abilist64=
38ro.product.manufacturer=LYF-JP4
39ro.product.locale=en-US
40ro.wifi.channels=
41ro.board.platform=sp9820e
42# ro.build.product is obsolete; use ro.product.device
43ro.build.product=MAD
44# Do not try to parse description, fingerprint, or thumbprint
45ro.build.description=MAD-user 6.0 MRA58K Jio-F491H-F001-04-13-310823 release-keys
46ro.build.fingerprint=Jio/F491H/F491H:6.0/MRA58K/Jio-F491H-F001-04-13-310823:user/release-keys
47ro.build.characteristics=default
48# end build properties
49#
50# from device/sprd/sharkle/sp9820e_1h10/system.prop
51#
52# Default density config
53ro.sf.lcd_density=120
54ro.sf.lcd_width=24
55ro.sf.lcd_height=32
56ro.product.hardware=sp9820e_1h10
57# Set Opengl ES Version
58ro.opengles.version=196609
59
60# ro.fm.chip.port.UART.androidm=true
61
62# FRP property for pst device
63ro.frp.pst=/dev/block/platform/soc/soc:ap-ahb/20600000.sdio/by-name/persist
64
65#disable zsl function until zsl capture is ready
66persist.sys.cam.zsl=false
67
68#add for torch node
69ro.kaios.torch_node=/sys/devices/virtual/misc/sprd_flash/test
70ro.kaios.torch_enable_value=10
71ro.kaios.torch_disable_value=11
72persist.sys.aov.support=false
73persist.sys.mmi2.support=false
74ro.product.brand=LYF
75
76#enable audio nr tuning
77ro.audio_tunning.nr=1
78
79ro.build.cver=UN_9820_4_4_83_SEC_1
80
81#
82# ADDITIONAL_BUILD_PROPERTIES
83#
84ro.config.ringtone=Ring_Synth_04.ogg
85ro.config.notification_sound=pixiedust.ogg
86ro.carrier=unknown
87ro.config.alarm_alert=Alarm_Classic.ogg
88persist.sys.engpc.disable=1
89persist.sys.sprd.modemreset=1
90ro.product.partitionpath=/dev/block/platform/soc/soc:ap-ahb/20600000.sdio/by-name/
91ro.modem.l.dev=/proc/cptl/
92ro.modem.l.tty=/dev/stty_lte
93ro.modem.l.eth=seth_lte
94ro.modem.l.snd=1
95ro.modem.l.diag=/dev/sdiag_lte
96ro.modem.l.log=/dev/slog_lte
97ro.modem.l.loop=/dev/spipe_lte0
98ro.modem.l.nv=/dev/spipe_lte1
99ro.modem.l.assert=/dev/spipe_lte2
100ro.modem.l.vbc=/dev/spipe_lte6
101ro.modem.l.id=0
102ro.modem.l.fixnv_size=0xc8000
103ro.modem.l.runnv_size=0xe8000
104persist.modem.l.nvp=l_
105persist.modem.l.enable=1
106ro.radio.modemtype=l
107ro.telephony.default_network=11
108ro.modem.l.count=1
109persist.msms.phone_count=1
110persist.radio.multisim.config=ssss
111keyguard.no_require_sim=true
112ro.com.android.dataroaming=false
113ro.simlock.unlock.autoshow=1
114ro.simlock.unlock.bynv=0
115ro.simlock.onekey.lock=0
116ro.storage.flash_type=2
117sys.internal.emulated=1
118persist.storage.type=2
119ro.storage.install2internal=0
120drm.service.enabled=false
121ro.treble.enabled=true
122ro.product.first_api_level=26
123ro.vendor.vndk.version=1
124persist.sys.sprd.wcnreset=1
125persist.sys.apr.enabled=0
126persist.sys.start_udpdatastall=0
127persist.sys.apr.intervaltime=1
128persist.sys.apr.testgroup=CSSLAB
129persist.sys.apr.autoupload=1
130persist.sys.heartbeat.enable=1
131persist.sys.power.touch=1
132persist.recents.sprd=1
133ro.kaios.use_timerfd=true
134ro.kaios.usb.functions_node=/config/usb_gadget/g1/configs/b.1/strings/0x409/configuration
135ro.kaios.ums.directory_node=/config/usb_gadget/g1/functions/mass_storage.gs6
136ro.kaios.mtp.directory_node=/config/usb_gadget/g1/functions/mtp.gs0
137ro.kaios.usb.state_node=/sys/class/android_usb/android0/state
138ro.wcn.hardware.product=sharkle
139ro.wcn.hardware.etcpath=/system/etc
140ro.bt.bdaddr_path=/data/misc/bluedroid/btmac.txt
141ro.hotspot.enabled=1
142reset_default_http_response=true
143ro.void_charge_tip=true
144ro.softaplte.coexist=true
145ro.vowifi.softap.ee_warning=false
146persist.sys.wifi.pocketmode=true
147ro.wcn=enabled
148ro.softap.whitelist=true
149ro.btwifisoftap.coexist=true
150persist.wifi.func.hidessid=true
151ro.wifi.softap.maxstanum=10
152ro.wifi.signal.optimized=true
153ro.support.auto.roam=disabled
154ro.wifip2p.coexist=true
155ro.modem.wcn.enable=1
156ro.modem.wcn.diag=/dev/slog_wcn
157ro.modem.wcn.id=1
158ro.modem.wcn.count=1
159ro.modem.gnss.diag=/dev/slog_gnss
160persist.sys.support.vt=false
161persist.sys.csvt=false
162persist.radio.modem.workmode=3,10
163persist.radio.modem.config=TL_LF_W_G,G
164persist.radio.ssda.mode=csfb
165persist.radio.ssda.testmode=3
166persist.radio.ssda.testmode1=10
167ro.wcn.gpschip=ge2
168persist.dbg.wfc_avail_ovr=1
169persist.sys.vowifi.voice=cp
170persist.sys.cam.refocus.enable=false
171ro.lockscreen.disable.default=true
172ro.moz.ril.numclients=1
173ro.moz.ril.query_icc_count=true
174ro.moz.ril.radio_off_wo_card=true
175ro.moz.ril.data_reg_on_demand=true
176ro.moz.ril.ipv6=true
177ro.moz.ril.0.network_types=lte
178ril.ecclist=112,911,122
179persist.user.agent=default
180persist.data.collector.enable=true
181persist.device.vowifi.supported=true
182persist.sys.volte.enable=true
183ro.product.fota=redbend
184ro.moz.nfc.enabled=false
185ro.build.cver=UN_9820_4_4_83_SEC_1
186ro.embms.enable=1
187persist.sys.dalvik.vm.lib.2=libart
188dalvik.vm.isa.arm.variant=generic
189dalvik.vm.isa.arm.features=default
190net.bt.name=Android
191dalvik.vm.stack-trace-file=/data/anr/traces.txt
192ro.expect.recovery_id=0xd65615fd4cbd808139fbedcc46c59e4481a764c4000000000000000000000000
Conclusion
KaiOS’ kernel-level component, Gonk, is built on top of Android’s board support package (BSP) and hardware abstraction layer (HAL). As a result, it retains many features like system properties. Most app developers do not need low-level access, but in rare cases, it can be useful because the necessary data isn’t exposed via other APIs. If you need an expert-level KaiOS partner, contact the author from the About page.